Introduction
In my previous article, I explained what Model Context Protocol (MCP) is — the "USB-C for AI" that provides a universal way to connect AI assistants to external tools and applications.
Today, I'm excited to share how we implemented MCP in DiskCleanKit 5.0, allowing AI assistants like Claude, Cursor, and VS Code Copilot to scan and clean your Mac automatically.
What you'll learn:
- How MCP works under the hood
- Step-by-step guide to building your own MCP server
- Real-world implementation patterns
- Publishing to npm and MCP Registry
Resources:
- 📦 npm: @vannamtran/diskcleankit-mcp
- 🔗 GitHub: namtran/diskcleankit-mcp
- 📋 MCP Registry: registry.modelcontextprotocol.io
What is MCP? (Quick Recap)
MCP (Model Context Protocol) is an open-source standard created by Anthropic that allows AI assistants to interact with external tools, data sources, and applications.
┌─────────────────────────────────────────────────────────────────┐
│ Before MCP │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Claude ──── Custom Code ──── Your App │
│ ChatGPT ─── Different Code ── Your App │
│ Copilot ─── Another Code ──── Your App │
│ │
│ 😫 Every AI needs custom integration │
│ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ After MCP │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Claude ────┐ │
│ Cursor ────┼──── MCP Server ──── Your App │
│ Copilot ───┘ │
│ │
│ 😊 One integration works with all AI assistants │
│ │
└─────────────────────────────────────────────────────────────────┘
DiskCleanKit MCP Architecture
Here's how our MCP server connects AI assistants to DiskCleanKit:
┌─────────────────────────────────────────────────────────────────┐
│ DiskCleanKit MCP Flow │
├─────────────────────────────────────────────────────────────────┤
│ │
│ User: "Clean up my Mac" │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ AI Assistant │ (Claude, Cursor, Copilot) │
│ │ Understands │ │
│ │ user intent │ │
│ └────────┬────────┘ │
│ │ Calls MCP tool: one_touch_clean │
│ ▼ │
│ ┌─────────────────┐ │
│ │ MCP Server │ (@vannamtran/diskcleankit-mcp) │
│ │ Node.js │ │
│ └────────┬────────┘ │
│ │ URL Scheme: diskcleankit://one-touch-clean │
│ ▼ │
│ ┌─────────────────┐ │
│ │ DiskCleanKit │ (macOS App) │
│ │ Native App │ │
│ └────────┬────────┘ │
│ │ Writes result to temp file │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Response JSON │ /tmp/diskcleankit_mcp_response.json │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ AI: "I cleaned 2.5GB of cache files from your Mac! 🎉" │
│ │
└─────────────────────────────────────────────────────────────────┘
Step-by-Step: Building an MCP Server
Step 1: Project Setup
mkdir my-mcp-server
cd my-mcp-server
npm init -y
Install dependencies:
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node
package.json:
{
"name": "@yourname/my-mcp-server",
"version": "1.0.0",
"type": "module",
"bin": {
"my-mcp-server": "./dist/index.js"
},
"files": ["dist"],
"scripts": {
"build": "tsc",
"start": "node dist/index.js"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.0.0",
"zod": "^3.22.0"
},
"devDependencies": {
"typescript": "^5.3.0",
"@types/node": "^20.0.0"
}
}
tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"declaration": true
},
"include": ["src/**/*"]
}
Step 2: Create the MCP Server
src/index.ts:
#!/usr/bin/env node
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// Create server instance
const server = new McpServer({
name: "my-mcp-server",
version: "1.0.0",
});
// Define your tools
server.tool(
"hello_world",
"Says hello to the user",
{
name: z.string().describe("Name to greet"),
},
async ({ name }) => {
return {
content: [
{
type: "text",
text: `Hello, ${name}! 👋`,
},
],
};
}
);
// Start the server
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("MCP Server running on stdio");
}
main().catch(console.error);
Step 3: How DiskCleanKit Implements Tools
Here's how we implemented the actual tools in DiskCleanKit MCP:
// Tool: one_touch_scan
server.tool(
"one_touch_scan",
"Scan Mac for junk files without deleting anything",
{},
async () => {
// 1. Trigger the app via URL scheme
const { exec } = await import("child_process");
exec("open 'diskcleankit://one-touch-scan'");
// 2. Wait for response file
const response = await waitForResponse();
// 3. Return result to AI
return {
content: [
{
type: "text",
text: JSON.stringify(response, null, 2),
},
],
};
}
);
// Tool: one_touch_clean
server.tool(
"one_touch_clean",
"Scan AND clean junk files automatically (safe items only)",
{},
async () => {
const { exec } = await import("child_process");
exec("open 'diskcleankit://one-touch-clean'");
const response = await waitForResponse();
return {
content: [
{
type: "text",
text: JSON.stringify(response, null, 2),
},
],
};
}
);
// Tool: get_disk_status
server.tool(
"get_disk_status",
"Check disk space and health status",
{},
async () => {
const { exec } = await import("child_process");
exec("open 'diskcleankit://disk-status'");
const response = await waitForResponse();
return {
content: [
{
type: "text",
text: JSON.stringify(response, null, 2),
},
],
};
}
);
// Helper: Wait for app response
async function waitForResponse(timeout = 30000): Promise<any> {
const responseFile = "/tmp/diskcleankit_mcp_response.json";
const startTime = Date.now();
while (Date.now() - startTime < timeout) {
try {
const fs = await import("fs/promises");
const data = await fs.readFile(responseFile, "utf-8");
await fs.unlink(responseFile); // Clean up
return JSON.parse(data);
} catch {
// File not ready yet, wait and retry
await new Promise((resolve) => setTimeout(resolve, 500));
}
}
throw new Error("Timeout waiting for DiskCleanKit response");
}
Step 4: Communication via URL Schemes
The key to connecting Node.js MCP server to a native macOS app is URL schemes.
In your macOS app (Swift):
// Register URL scheme in Info.plist
// <key>CFBundleURLSchemes</key>
// <array><string>diskcleankit</string></array>
// Handle URL in AppDelegate
func application(_ application: NSApplication,
open urls: [URL]) {
guard let url = urls.first else { return }
switch url.host {
case "one-touch-scan":
performScan()
case "one-touch-clean":
performClean()
case "disk-status":
getDiskStatus()
default:
break
}
}
// Write response for MCP server
func writeResponse(_ result: [String: Any]) {
let path = "/tmp/diskcleankit_mcp_response.json"
let data = try? JSONSerialization.data(withJSONObject: result)
try? data?.write(to: URL(fileURLWithPath: path))
}
Publishing Your MCP Server
Step 1: Build the Project
npm run build
Step 2: Add Shebang to Entry File
Make sure dist/index.js starts with:
#!/usr/bin/env node
Step 3: Publish to npm
npm login
npm publish --access public
Step 4: Register with MCP Registry
Create a server.json file:
{
"$schema": "https://registry.modelcontextprotocol.io/schema/server.json",
"name": "@vannamtran/diskcleankit-mcp",
"description": "MCP server for DiskCleanKit - One Touch Scan and Clean for Mac",
"repository": {
"type": "git",
"url": "https://github.com/namtran/diskcleankit-mcp"
},
"version_detail": {
"version": "1.0.0",
"release_date": "2025-01-01",
"is_latest": true
},
"packages": [
{
"registry_name": "npm",
"name": "@vannamtran/diskcleankit-mcp",
"version": "1.0.0"
}
],
"tools": [
{
"name": "one_touch_scan",
"description": "Scan Mac for junk files (safe, no deletion)"
},
{
"name": "one_touch_clean",
"description": "Scan AND clean junk files automatically"
},
{
"name": "get_disk_status",
"description": "Check disk space and health"
}
]
}
Submit to the registry by creating a PR to github.com/modelcontextprotocol/registry.
Configuring AI Clients
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"diskcleankit": {
"command": "npx",
"args": ["@vannamtran/diskcleankit-mcp"]
}
}
}
Claude Code (CLI)
claude mcp add diskcleankit -- npx @vannamtran/diskcleankit-mcp
Cursor
Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"diskcleankit": {
"command": "npx",
"args": ["@vannamtran/diskcleankit-mcp"]
}
}
}
VS Code (GitHub Copilot)
Add to settings.json:
{
"mcp.servers": {
"diskcleankit": {
"command": "npx",
"args": ["@vannamtran/diskcleankit-mcp"]
}
}
}
Usage Examples
Once configured, you can ask your AI assistant:
| User Says | AI Calls | Result |
|---|---|---|
| "Scan my Mac for junk" | one_touch_scan |
Shows cleanable items |
| "Clean up my Mac" | one_touch_clean |
Removes cache/logs |
| "How much disk space do I have?" | get_disk_status |
Shows storage info |
| "What can be cleaned?" | get_cleanable_estimate |
Estimates by category |
| "Show cleaning history" | get_cleaning_history |
Past sessions |
Example conversation:
User: My Mac is running low on storage. Can you help?
Claude: I'll check your disk status and scan for cleanable files.
[Calls get_disk_status]
[Calls one_touch_scan]
Your Mac has 45GB free out of 500GB. I found 8.2GB of cleanable
files:
- System Caches: 3.1GB
- Application Caches: 2.8GB
- Browser Caches: 1.5GB
- Log Files: 0.8GB
Would you like me to clean these? They're all safe to remove and
will be regenerated as needed.
User: Yes, please clean them.
Claude: [Calls one_touch_clean]
Done! I've cleaned 8.2GB of cache and log files. Your Mac now
has 53.2GB free. 🎉
Security Considerations
When building MCP servers, security is crucial:
| Practice | Description |
|---|---|
| Principle of Least Privilege | Only expose necessary tools |
| Safe by Default |
one_touch_scan doesn't delete anything |
| Clear Tool Names | Users understand what each tool does |
| No External Data | All processing happens locally |
| Safe Items Only | Only clean regenerable files (caches, logs) |
What DiskCleanKit MCP cleans:
| Category | Safe? | Regenerable? |
|---|---|---|
| System Caches | ✅ Yes | ✅ Yes |
| Application Caches | ✅ Yes | ✅ Yes |
| Browser Caches | ✅ Yes | ✅ Yes |
| Log Files | ✅ Yes | ✅ Yes |
| Personal Documents | ❌ Never touched | - |
| Photos/Videos | ❌ Never touched | - |
Common Patterns for MCP Servers
Pattern 1: URL Scheme (Desktop Apps)
MCP Server → URL Scheme → Native App → Temp File → MCP Server
Best for: macOS/Windows desktop applications
Pattern 2: Local HTTP API
MCP Server → HTTP Request → Local Server → HTTP Response
Best for: Apps with REST APIs
Pattern 3: IPC (Inter-Process Communication)
MCP Server → Named Pipe/Socket → Native Process
Best for: Background services
Pattern 4: Direct File System
MCP Server → Read/Write Files Directly
Best for: File management tools
Troubleshooting
"Timeout waiting for response"
# Check if DiskCleanKit is installed
ls /Applications/DiskCleanKit.app
# Try opening manually
open "diskcleankit://disk-status"
"Server not appearing in Claude"
- Verify config path is correct
- Restart Claude Desktop
- Check logs:
~/Library/Logs/Claude/mcp*.log
"Permission denied"
# Make the script executable
chmod +x ./dist/index.js
What's Next?
MCP is still evolving. Here's what we're excited about:
- More AI Clients: Expecting ChatGPT support soon
- Remote MCP Servers: HTTP-based servers (not just stdio)
- Richer Tool Types: Beyond just function calls
- Better Discovery: Improved MCP Registry features
Conclusion
Building an MCP server is straightforward once you understand the pattern:
-
Create a Node.js server using
@modelcontextprotocol/sdk - Define tools that AI assistants can call
- Connect to your app via URL schemes, HTTP, or IPC
- Publish to npm and register with MCP Registry
- Configure AI clients with a simple JSON config
MCP opens up exciting possibilities for AI-powered applications. Your desktop app can now be controlled by natural language through any MCP-compatible AI assistant.
Try it yourself:
npm install -g @vannamtran/diskcleankit-mcp
Resources
- 📦 npm Package: @vannamtran/diskcleankit-mcp
- 🔗 GitHub: namtran/diskcleankit-mcp
- 📋 MCP Registry: registry.modelcontextprotocol.io
- 📖 MCP Documentation: modelcontextprotocol.io
- 🧹 DiskCleanKit App: diskcleankit.com
Have you built an MCP server? Share your experience in the comments!
Tags: #mcp #ai #typescript #macos #tutorial
Top comments (0)