A comprehensive TypeScript framework for building custom MCP (Model Context Protocol) servers that extend AI assistants with specialized tools, resources, and prompts.
- 🚀 Easy Setup: Quick project initialization with CLI tools
- 🔧 Tool Registry: Register and execute custom tools with schema validation
- 📚 Resource Management: Serve dynamic content and data resources
- 💬 Prompt Templates: Create reusable prompt templates with arguments
- ⚙️ Configuration Management: Flexible configuration with environment support
- 🧪 Testing Utilities: Built-in testing framework for MCP protocol compliance
- 📝 TypeScript Support: Full TypeScript support with declaration files
- 🔍 Debugging Tools: Comprehensive logging and connection testing
npm install mcp-server-dev
npx mcp-server init my-custom-server
cd my-custom-server
npm install
import { MCPServer } from 'mcp-server-dev'; const server = new MCPServer({ name: 'my-custom-server', version: '1.0.0' }); // Register a simple tool server.toolRegistry.registerTool({ name: 'greet', description: 'Greet a user with a custom message', inputSchema: { type: 'object', properties: { name: { type: 'string', description: 'Name to greet' }, greeting: { type: 'string', description: 'Greeting message', default: 'Hello' } }, required: ['name'] }, handler: async (args) => { return { content: [{ type: 'text', text: `${args.greeting}, ${args.name}!` }] }; } }); export default server;
npm run build npm start
The framework includes a powerful CLI for server management:
# Start with default configuration mcp-server start # Start with custom config mcp-server start --config ./my-config.json # Start with debug logging mcp-server start --debug # Start in HTTP mode (default is stdio) mcp-server start --http --port 3000
# Create new project in current directory mcp-server init my-server # Create in specific directory mcp-server init my-server --directory ./projects
mcp-server validate --config ./mcp-config.json
mcp-server test-connection
The main server class that orchestrates all MCP functionality.
import { MCPServer, ServerConfig } from 'mcp-server-dev'; const server = new MCPServer(config: ServerConfig);
start(): Promise<void>
- Start the MCP serverstop(): Promise<void>
- Stop the server gracefullytoolRegistry: ToolRegistry
- Access to tool managementresourceManager: ResourceManager
- Access to resource managementpromptManager: PromptManager
- Access to prompt management
Register and manage custom tools that can be executed by AI assistants.
import { ToolRegistry, ToolDefinition } from 'mcp-server-dev'; const toolRegistry = new ToolRegistry(); // Register a tool toolRegistry.registerTool({ name: 'file-reader', description: 'Read file contents', inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'File path to read' } }, required: ['path'] }, handler: async (args) => { const fs = await import('fs/promises'); const content = await fs.readFile(args.path, 'utf-8'); return { content: [{ type: 'text', text: content }] }; } });
Serve dynamic content and data resources.
import { ResourceManager } from 'mcp-server-dev'; const resourceManager = new ResourceManager(); // Register a resource resourceManager.registerResource({ uri: 'file://logs/{date}', name: 'Daily Logs', description: 'Access daily log files', mimeType: 'text/plain', provider: async (uri) => { const date = uri.match(/file:\/\/logs\/(.+)/)?.[1]; const logContent = await getLogForDate(date); return { contents: [{ type: 'text', text: logContent }] }; } });
Create reusable prompt templates with dynamic arguments.
import { PromptManager } from 'mcp-server-dev'; const promptManager = new PromptManager(); // Register a prompt template promptManager.registerPrompt({ name: 'code-review', description: 'Generate code review prompts', arguments: [ { name: 'language', description: 'Programming language', required: true }, { name: 'focus', description: 'Review focus area', required: false } ], template: async (args) => { return [{ role: 'user', content: { type: 'text', text: `Please review this ${args.language} code${args.focus ? ` focusing on ${args.focus}` : ''}:` } }]; } });
interface ServerConfig { name: string; version: string; description?: string; transport?: 'stdio' | 'http'; port?: number; logging?: { level: 'debug' | 'info' | 'warn' | 'error'; format?: 'json' | 'text'; }; }
{ "name": "my-mcp-server", "version": "1.0.0", "description": "Custom MCP server for specialized tasks", "transport": "stdio", "logging": { "level": "info", "format": "json" } }
The framework includes comprehensive testing utilities:
import { MCPTestClient } from 'mcp-server-dev/testing'; // Create test client const client = new MCPTestClient(); // Test server initialization await client.connect(); const initResult = await client.initialize({ protocolVersion: '2024-11-05', capabilities: {}, clientInfo: { name: 'test-client', version: '1.0.0' } }); // Test tool execution const toolResult = await client.callTool('greet', { name: 'World' }); expect(toolResult.content[0].text).toBe('Hello, World!'); // Test resource access const resource = await client.readResource('file://logs/2024-01-01'); expect(resource.contents).toBeDefined(); // Test prompt generation const prompt = await client.getPrompt('code-review', { language: 'typescript' }); expect(prompt.messages).toBeDefined(); await client.disconnect();
server.toolRegistry.registerTool({ name: 'list-files', description: 'List files in a directory', inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'Directory path' }, pattern: { type: 'string', description: 'File pattern (optional)' } }, required: ['path'] }, handler: async (args) => { const fs = await import('fs/promises'); const path = await import('path'); const files = await fs.readdir(args.path); const filteredFiles = args.pattern ? files.filter(f => f.includes(args.pattern)) : files; return { content: [{ type: 'text', text: filteredFiles.join('\n') }] }; } });
resourceManager.registerResource({ uri: 'web://{url}', name: 'Web Content', description: 'Scrape content from web pages', mimeType: 'text/html', provider: async (uri) => { const url = uri.replace('web://', 'https://'); const response = await fetch(url); const html = await response.text(); return { contents: [{ type: 'text', text: html, mimeType: 'text/html' }] }; } });
promptManager.registerPrompt({ name: 'generate-function', description: 'Generate function implementation', arguments: [ { name: 'functionName', required: true }, { name: 'language', required: true }, { name: 'description', required: true }, { name: 'parameters', required: false } ], template: async (args) => { const paramText = args.parameters ? ` with parameters: ${args.parameters}` : ''; return [{ role: 'user', content: { type: 'text', text: `Generate a ${args.language} function named "${args.functionName}"${paramText}. Description: ${args.description}` } }]; } });
# Via CLI mcp-server start --debug # Via environment LOG_LEVEL=debug mcp-server start # Via configuration { "logging": { "level": "debug" } }
import { ConnectionTester } from 'mcp-server-dev/testing'; const tester = new ConnectionTester(); const result = await tester.testConnection(serverConfig); if (result.success) { console.log('Server is working correctly'); console.log('Capabilities:', result.capabilities); } else { console.error('Connection failed:', result.error); }
The framework ensures full MCP protocol compliance:
- ✅ JSON-RPC 2.0 message format
- ✅ MCP initialization handshake
- ✅ Capability negotiation
- ✅ Tool execution protocol
- ✅ Resource serving protocol
- ✅ Prompt template protocol
- ✅ Error handling standards
- ✅ Graceful shutdown
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
MIT License - see LICENSE file for details.
- Initial release
- Core MCP protocol implementation
- Tool, resource, and prompt management
- CLI utilities
- Testing framework
- TypeScript support