Build Claude Desktop Extensions (DXT) with proper MCP server setup and manifest configuration
/plugin marketplace add claudeforge/marketplace/plugin install desktop-integrator@claudeforge-marketplaceBuild Claude Desktop Extensions using the Model Context Protocol to extend Claude Desktop with custom tools and capabilities.
Run this command when you want to create a new Desktop Extension:
/claude-desktop-extension
The command will guide you through creating a complete extension with server code and manifest.
A basic DXT includes two main files:
manifest.json
{
"name": "my-extension",
"version": "1.0.0",
"description": "Custom tools for Claude",
"main": "server.js",
"mcp": {
"transport": "stdio"
}
}
server.js
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = new Server({
name: 'my-extension',
version: '1.0.0'
}, {
capabilities: {
tools: {}
}
});
server.setRequestHandler('tools/list', async () => ({
tools: [{
name: 'my_tool',
description: 'Does something useful',
inputSchema: {
type: 'object',
properties: {
input: { type: 'string' }
}
}
}]
}));
server.setRequestHandler('tools/call', async (request) => {
const { name, arguments: args } = request.params;
if (name === 'my_tool') {
return {
content: [{ type: 'text', text: `Processed: ${args.input}` }]
};
}
throw new Error(`Unknown tool: ${name}`);
});
const transport = new StdioServerTransport();
await server.connect(transport);
After building your extension:
npm install @modelcontextprotocol/sdkmacOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%/Claude/claude_desktop_config.json
{
"mcpServers": {
"my-extension": {
"command": "node",
"args": ["/path/to/your/server.js"]
}
}
}
Reading environment variables:
const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error('API_KEY not configured');
}
Making HTTP requests:
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return { content: [{ type: 'text', text: JSON.stringify(data) }] };
File operations:
import fs from 'fs/promises';
const content = await fs.readFile(args.path, 'utf-8');
return { content: [{ type: 'text', text: content }] };