├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── src └── index.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | build/ 3 | *.log 4 | .env* -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # create-mcp-server 2 | 3 | A specialized MCP server that helps create new MCP server scaffolds. This tool streamlines the process of creating new Model Context Protocol (MCP) servers by providing a structured development protocol and example templates. 4 | 5 | ## How to use 6 | 7 | ### NPX 8 | 9 | ```json 10 | { 11 | "mcpServers": { 12 | "mediaProcessor": { 13 | "command": "npx", 14 | "args": [ 15 | "-y", 16 | "create-mcp-server@latest" 17 | ] 18 | } 19 | } 20 | } 21 | ``` 22 | 23 | ## License 24 | 25 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. 26 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "y", 3 | "version": "0.1.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "y", 9 | "version": "0.1.0", 10 | "dependencies": { 11 | "@modelcontextprotocol/sdk": "0.6.0" 12 | }, 13 | "bin": { 14 | "y": "build/index.js" 15 | }, 16 | "devDependencies": { 17 | "@types/node": "^20.11.24", 18 | "typescript": "^5.3.3" 19 | } 20 | }, 21 | "node_modules/@modelcontextprotocol/sdk": { 22 | "version": "0.6.0", 23 | "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-0.6.0.tgz", 24 | "integrity": "sha512-9rsDudGhDtMbvxohPoMMyAUOmEzQsOK+XFchh6gZGqo8sx9sBuZQs+CUttXqa8RZXKDaJRCN2tUtgGof7jRkkw==", 25 | "license": "MIT", 26 | "dependencies": { 27 | "content-type": "^1.0.5", 28 | "raw-body": "^3.0.0", 29 | "zod": "^3.23.8" 30 | } 31 | }, 32 | "node_modules/@types/node": { 33 | "version": "20.17.23", 34 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.23.tgz", 35 | "integrity": "sha512-8PCGZ1ZJbEZuYNTMqywO+Sj4vSKjSjT6Ua+6RFOYlEvIvKQABPtrNkoVSLSKDb4obYcMhspVKmsw8Cm10NFRUg==", 36 | "dev": true, 37 | "license": "MIT", 38 | "dependencies": { 39 | "undici-types": "~6.19.2" 40 | } 41 | }, 42 | "node_modules/bytes": { 43 | "version": "3.1.2", 44 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 45 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 46 | "license": "MIT", 47 | "engines": { 48 | "node": ">= 0.8" 49 | } 50 | }, 51 | "node_modules/content-type": { 52 | "version": "1.0.5", 53 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 54 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 55 | "license": "MIT", 56 | "engines": { 57 | "node": ">= 0.6" 58 | } 59 | }, 60 | "node_modules/depd": { 61 | "version": "2.0.0", 62 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 63 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 64 | "license": "MIT", 65 | "engines": { 66 | "node": ">= 0.8" 67 | } 68 | }, 69 | "node_modules/http-errors": { 70 | "version": "2.0.0", 71 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 72 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 73 | "license": "MIT", 74 | "dependencies": { 75 | "depd": "2.0.0", 76 | "inherits": "2.0.4", 77 | "setprototypeof": "1.2.0", 78 | "statuses": "2.0.1", 79 | "toidentifier": "1.0.1" 80 | }, 81 | "engines": { 82 | "node": ">= 0.8" 83 | } 84 | }, 85 | "node_modules/iconv-lite": { 86 | "version": "0.6.3", 87 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 88 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 89 | "license": "MIT", 90 | "dependencies": { 91 | "safer-buffer": ">= 2.1.2 < 3.0.0" 92 | }, 93 | "engines": { 94 | "node": ">=0.10.0" 95 | } 96 | }, 97 | "node_modules/inherits": { 98 | "version": "2.0.4", 99 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 100 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 101 | "license": "ISC" 102 | }, 103 | "node_modules/raw-body": { 104 | "version": "3.0.0", 105 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", 106 | "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", 107 | "license": "MIT", 108 | "dependencies": { 109 | "bytes": "3.1.2", 110 | "http-errors": "2.0.0", 111 | "iconv-lite": "0.6.3", 112 | "unpipe": "1.0.0" 113 | }, 114 | "engines": { 115 | "node": ">= 0.8" 116 | } 117 | }, 118 | "node_modules/safer-buffer": { 119 | "version": "2.1.2", 120 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 121 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 122 | "license": "MIT" 123 | }, 124 | "node_modules/setprototypeof": { 125 | "version": "1.2.0", 126 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 127 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", 128 | "license": "ISC" 129 | }, 130 | "node_modules/statuses": { 131 | "version": "2.0.1", 132 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 133 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 134 | "license": "MIT", 135 | "engines": { 136 | "node": ">= 0.8" 137 | } 138 | }, 139 | "node_modules/toidentifier": { 140 | "version": "1.0.1", 141 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 142 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 143 | "license": "MIT", 144 | "engines": { 145 | "node": ">=0.6" 146 | } 147 | }, 148 | "node_modules/typescript": { 149 | "version": "5.8.2", 150 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", 151 | "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", 152 | "dev": true, 153 | "license": "Apache-2.0", 154 | "bin": { 155 | "tsc": "bin/tsc", 156 | "tsserver": "bin/tsserver" 157 | }, 158 | "engines": { 159 | "node": ">=14.17" 160 | } 161 | }, 162 | "node_modules/undici-types": { 163 | "version": "6.19.8", 164 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", 165 | "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", 166 | "dev": true, 167 | "license": "MIT" 168 | }, 169 | "node_modules/unpipe": { 170 | "version": "1.0.0", 171 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 172 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 173 | "license": "MIT", 174 | "engines": { 175 | "node": ">= 0.8" 176 | } 177 | }, 178 | "node_modules/zod": { 179 | "version": "3.24.2", 180 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", 181 | "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", 182 | "license": "MIT", 183 | "funding": { 184 | "url": "https://github.com/sponsors/colinhacks" 185 | } 186 | } 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-mcp-server", 3 | "version": "0.0.1", 4 | "description": "A MCP Server to create MCP Servers", 5 | "type": "module", 6 | "bin": { 7 | "create-mcp-server": "./build/index.js" 8 | }, 9 | "files": [ 10 | "build" 11 | ], 12 | "scripts": { 13 | "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"", 14 | "prepare": "npm run build", 15 | "watch": "tsc --watch", 16 | "inspector": "npx @modelcontextprotocol/inspector build/index.js" 17 | }, 18 | "dependencies": { 19 | "@modelcontextprotocol/sdk": "0.6.0" 20 | }, 21 | "devDependencies": { 22 | "@types/node": "^20.11.24", 23 | "typescript": "^5.3.3" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { Server } from "@modelcontextprotocol/sdk/server/index.js"; 4 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; 5 | import { 6 | CallToolRequestSchema, 7 | ListToolsRequestSchema, 8 | } from "@modelcontextprotocol/sdk/types.js"; 9 | 10 | 11 | const server = new Server( 12 | { 13 | name: "create-mcp-server", 14 | version: "0.1.0", 15 | }, 16 | { 17 | capabilities: { 18 | tools: {}, 19 | }, 20 | } 21 | ); 22 | 23 | const exampleProjectStructure = ` 24 | 25 | This section contains a summary of this file. 26 | 27 | 28 | This file contains a packed representation of a MCP server project. 29 | It is designed to be easily consumable by AI systems for analysis, code review, 30 | or other automated processes. 31 | 32 | 33 | 34 | The content is organized as follows: 35 | 1. This summary section 36 | 2. Repository information 37 | 3. Directory structure 38 | 4. Repository files, each consisting of: 39 | - File path as an attribute 40 | - Full contents of the file 41 | 42 | 43 | 44 | - This file should be treated as read-only. Any changes should be made to the 45 | original repository files, not this packed version. 46 | - When processing this file, use the file path to distinguish 47 | between different files in the repository. 48 | - Be aware that this file may contain sensitive information. Handle it with 49 | the same level of security as you would the original repository. 50 | 51 | 52 | 53 | 54 | 55 | src/ 56 | index.ts 57 | .gitignore 58 | package.json 59 | README.md 60 | tsconfig.json 61 | 62 | 63 | 64 | This section contains the contents of the repository's files. 65 | 66 | 67 | #!/usr/bin/env node 68 | 69 | /** 70 | * This is a template MCP server that implements a simple notes system. 71 | * It demonstrates core MCP concepts like resources and tools by allowing: 72 | * - Listing notes as resources 73 | * - Reading individual notes 74 | * - Creating new notes via a tool 75 | * - Summarizing all notes via a prompt 76 | */ 77 | 78 | import { Server } from "@modelcontextprotocol/sdk/server/index.js"; 79 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; 80 | import { 81 | CallToolRequestSchema, 82 | ListResourcesRequestSchema, 83 | ListToolsRequestSchema, 84 | ReadResourceRequestSchema, 85 | ListPromptsRequestSchema, 86 | GetPromptRequestSchema, 87 | } from "@modelcontextprotocol/sdk/types.js"; 88 | 89 | /** 90 | * Type alias for a note object. 91 | */ 92 | type Note = { title: string, content: string }; 93 | 94 | /** 95 | * Simple in-memory storage for notes. 96 | * In a real implementation, this would likely be backed by a database. 97 | */ 98 | const notes: { [id: string]: Note } = { 99 | "1": { title: "First Note", content: "This is note 1" }, 100 | "2": { title: "Second Note", content: "This is note 2" } 101 | }; 102 | 103 | /** 104 | * Create an MCP server with capabilities for resources (to list/read notes), 105 | * tools (to create new notes), and prompts (to summarize notes). 106 | */ 107 | const server = new Server( 108 | { 109 | name: "mcp-example", 110 | version: "0.1.0", 111 | }, 112 | { 113 | capabilities: { 114 | resources: {}, 115 | tools: {}, 116 | prompts: {}, 117 | }, 118 | } 119 | ); 120 | 121 | /** 122 | * Handler for listing available notes as resources. 123 | * Each note is exposed as a resource with: 124 | * - A note:// URI scheme 125 | * - Plain text MIME type 126 | * - Human readable name and description (now including the note title) 127 | */ 128 | server.setRequestHandler(ListResourcesRequestSchema, async () => { 129 | return { 130 | resources: Object.entries(notes).map(([id, note]) => ({ 131 | uri: \`note:///\${id}\`, 132 | mimeType: "text/plain", 133 | name: note.title, 134 | description: \`A text note: \${note.title}\` 135 | })) 136 | }; 137 | }); 138 | 139 | /** 140 | * Handler for reading the contents of a specific note. 141 | * Takes a note:// URI and returns the note content as plain text. 142 | */ 143 | server.setRequestHandler(ReadResourceRequestSchema, async (request) => { 144 | const url = new URL(request.params.uri); 145 | const id = url.pathname.replace(/^\//, ''); 146 | const note = notes[id]; 147 | 148 | if (!note) { 149 | throw new Error(\`Note \${id} not found\`); 150 | } 151 | 152 | return { 153 | contents: [{ 154 | uri: request.params.uri, 155 | mimeType: "text/plain", 156 | text: note.content 157 | }] 158 | }; 159 | }); 160 | 161 | /** 162 | * Handler that lists available tools. 163 | * Exposes a single "create_note" tool that lets clients create new notes. 164 | */ 165 | server.setRequestHandler(ListToolsRequestSchema, async () => { 166 | return { 167 | tools: [ 168 | { 169 | name: "create_note", 170 | description: "Create a new note", 171 | inputSchema: { 172 | type: "object", 173 | properties: { 174 | title: { 175 | type: "string", 176 | description: "Title of the note" 177 | }, 178 | content: { 179 | type: "string", 180 | description: "Text content of the note" 181 | } 182 | }, 183 | required: ["title", "content"] 184 | } 185 | } 186 | ] 187 | }; 188 | }); 189 | 190 | /** 191 | * Handler for the create_note tool. 192 | * Creates a new note with the provided title and content, and returns success message. 193 | */ 194 | server.setRequestHandler(CallToolRequestSchema, async (request) => { 195 | switch (request.params.name) { 196 | case "create_note": { 197 | const title = String(request.params.arguments?.title); 198 | const content = String(request.params.arguments?.content); 199 | if (!title || !content) { 200 | throw new Error("Title and content are required"); 201 | } 202 | 203 | const id = String(Object.keys(notes).length + 1); 204 | notes[id] = { title, content }; 205 | 206 | return { 207 | content: [{ 208 | type: "text", 209 | text: \`Created note \${id}: \${title}\` 210 | }] 211 | }; 212 | } 213 | 214 | default: 215 | throw new Error("Unknown tool"); 216 | } 217 | }); 218 | 219 | /** 220 | * Handler that lists available prompts. 221 | * Exposes a single "summarize_notes" prompt that summarizes all notes. 222 | */ 223 | server.setRequestHandler(ListPromptsRequestSchema, async () => { 224 | return { 225 | prompts: [ 226 | { 227 | name: "summarize_notes", 228 | description: "Summarize all notes", 229 | } 230 | ] 231 | }; 232 | }); 233 | 234 | /** 235 | * Handler for the summarize_notes prompt. 236 | * Returns a prompt that requests summarization of all notes, with the notes' contents embedded as resources. 237 | */ 238 | server.setRequestHandler(GetPromptRequestSchema, async (request) => { 239 | if (request.params.name !== "summarize_notes") { 240 | throw new Error("Unknown prompt"); 241 | } 242 | 243 | const embeddedNotes = Object.entries(notes).map(([id, note]) => ({ 244 | type: "resource" as const, 245 | resource: { 246 | uri: \`note:///\${id}\`, 247 | mimeType: "text/plain", 248 | text: note.content 249 | } 250 | })); 251 | 252 | return { 253 | messages: [ 254 | { 255 | role: "user", 256 | content: { 257 | type: "text", 258 | text: "Please summarize the following notes:" 259 | } 260 | }, 261 | ...embeddedNotes.map(note => ({ 262 | role: "user" as const, 263 | content: note 264 | })), 265 | { 266 | role: "user", 267 | content: { 268 | type: "text", 269 | text: "Provide a concise summary of all the notes above." 270 | } 271 | } 272 | ] 273 | }; 274 | }); 275 | 276 | /** 277 | * Start the server using stdio transport. 278 | * This allows the server to communicate via standard input/output streams. 279 | */ 280 | async function main() { 281 | const transport = new StdioServerTransport(); 282 | await server.connect(transport); 283 | } 284 | 285 | main().catch((error) => { 286 | console.error("Server error:", error); 287 | process.exit(1); 288 | }); 289 | 290 | 291 | 292 | node_modules/ 293 | build/ 294 | *.log 295 | .env* 296 | 297 | 298 | 299 | { 300 | "name": "mcp-example", 301 | "version": "0.1.0", 302 | "description": "This is an example of MCP server using TypeScript", 303 | "private": true, 304 | "type": "module", 305 | "bin": { 306 | "mcp-example": "./build/index.js" 307 | }, 308 | "files": [ 309 | "build" 310 | ], 311 | "scripts": { 312 | "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"", 313 | "prepare": "npm run build", 314 | "watch": "tsc --watch", 315 | "inspector": "npx @modelcontextprotocol/inspector build/index.js" 316 | }, 317 | "dependencies": { 318 | "@modelcontextprotocol/sdk": "0.6.0" 319 | }, 320 | "devDependencies": { 321 | "@types/node": "^20.11.24", 322 | "typescript": "^5.3.3" 323 | } 324 | } 325 | 326 | 327 | 328 | # mcp-example MCP Server 329 | 330 | This is an example of MCP server using TypeScript 331 | 332 | This is a TypeScript-based MCP server that implements a simple notes system. It demonstrates core MCP concepts by providing: 333 | 334 | - Resources representing text notes with URIs and metadata 335 | - Tools for creating new notes 336 | - Prompts for generating summaries of notes 337 | 338 | ## Features 339 | 340 | ### Resources 341 | - List and access notes via \`note://\` URIs 342 | - Each note has a title, content and metadata 343 | - Plain text mime type for simple content access 344 | 345 | ### Tools 346 | - \`create_note\` - Create new text notes 347 | - Takes title and content as required parameters 348 | - Stores note in server state 349 | 350 | ### Prompts 351 | - \`summarize_notes\` - Generate a summary of all stored notes 352 | - Includes all note contents as embedded resources 353 | - Returns structured prompt for LLM summarization 354 | 355 | ## Development 356 | 357 | Install dependencies: 358 | \`\`\`bash 359 | npm install 360 | \`\`\` 361 | 362 | Build the server: 363 | \`\`\`bash 364 | npm run build 365 | \`\`\` 366 | 367 | For development with auto-rebuild: 368 | \`\`\`bash 369 | npm run watch 370 | \`\`\` 371 | 372 | ## Installation 373 | 374 | To use with Claude Desktop, add the server config: 375 | 376 | On MacOS: \`~/Library/Application Support/Claude/claude_desktop_config.json\` 377 | On Windows: \`%APPDATA%/Claude/claude_desktop_config.json\` 378 | 379 | \`\`\`json 380 | { 381 | "mcpServers": { 382 | "mcp-example": { 383 | "command": "/path/to/mcp-example/build/index.js" 384 | } 385 | } 386 | } 387 | \`\`\` 388 | 389 | ### Debugging 390 | 391 | Since MCP servers communicate over stdio, debugging can be challenging. We recommend using the [MCP Inspector](https://github.com/modelcontextprotocol/inspector), which is available as a package script: 392 | 393 | \`\`\`bash 394 | npm run inspector 395 | \`\`\` 396 | 397 | The Inspector will provide a URL to access debugging tools in your browser. 398 | 399 | 400 | 401 | { 402 | "compilerOptions": { 403 | "target": "ES2022", 404 | "module": "Node16", 405 | "moduleResolution": "Node16", 406 | "outDir": "./build", 407 | "rootDir": "./src", 408 | "strict": true, 409 | "esModuleInterop": true, 410 | "skipLibCheck": true, 411 | "forceConsistentCasingInFileNames": true 412 | }, 413 | "include": ["src/**/*"], 414 | "exclude": ["node_modules"] 415 | } 416 | 417 | 418 | 419 | ` 420 | 421 | const MCP_Server_Development_Protocol = () => ` 422 | The Model Context Protocol (MCP) enables communication between the system and locally running MCP servers that provide additional tools and resources to extend your capabilities. You have the ability to create an MCP server. 423 | You MUST follow the following instructions when creating an MCP server: 424 | 425 | ## Step 1: Planning 426 | - You MUST plan out the resources and tools that you will need for your MCP server. 427 | - What API/service will it use? 428 | 429 | ## Step 2: Implementation 430 | 431 | ### Example MCP Server: 432 | Refer to the example project structure below for a list of files that you will need to create. 433 | 434 | ${exampleProjectStructure} 435 | 436 | ### Core Implementation 437 | 438 | - Implement the resources and tools that you planned out in step 1 439 | - Implement comprehensive logging 440 | \`\`\`typescript 441 | console.error('[Setup] Initializing server...'); 442 | console.error('[API] Request to endpoint:', endpoint); 443 | console.error('[Error] Failed with:', error); 444 | \`\`\` 445 | 446 | - Add type definitions 447 | - Handle errors with context 448 | - Whenever you need an environment variable such as an API key to configure the MCP server, walk the user through the process of getting the key. For example, they may need to create an account and go to a developer dashboard to generate the key. Provide step-by-step instructions and URLs to make it easy for the user to retrieve the necessary information. Then use the ask_followup_question tool to ask the user for the key, in this case the OpenWeather API key. 449 | 450 | ### Installation 451 | - Before running the server, you MUST install the dependencies and build the server. 452 | \`\`\`bash 453 | npm install 454 | npm run build 455 | \`\`\` 456 | 457 | ## Step 3: Testing 458 | 459 | BEFORE completing, I MUST verify: 460 | □ Have I tested EVERY tool? 461 | □ Have I confirmed success from the user for each test? 462 | □ Have I documented the test results? 463 | 464 | If ANY answer is "no", I MUST NOT complete the task. 465 | 466 | 467 | - Test each tool with valid inputs 468 | - Verify output format is correct 469 | - DO NOT PROCEED UNTIL ALL TOOLS TESTED 470 | ` 471 | 472 | server.setRequestHandler(ListToolsRequestSchema, async () => { 473 | return { 474 | tools: [ 475 | { 476 | name: "create_mcp_server", 477 | description: "Create a new MCP server scaffold", 478 | inputSchema: { 479 | type: "object", 480 | properties: { 481 | }, 482 | required: [] 483 | } 484 | } 485 | ] 486 | }; 487 | }); 488 | 489 | server.setRequestHandler(CallToolRequestSchema, async (request) => { 490 | switch (request.params.name) { 491 | case "create_mcp_server": { 492 | return { 493 | content: [{ 494 | type: "text", 495 | text: MCP_Server_Development_Protocol() 496 | }] 497 | }; 498 | } 499 | 500 | default: 501 | throw new Error("Unknown tool"); 502 | } 503 | }); 504 | 505 | async function main() { 506 | const transport = new StdioServerTransport(); 507 | console.log("Starting MCP server..."); 508 | await server.connect(transport); 509 | } 510 | 511 | main().catch((error) => { 512 | console.error("Server error:", error); 513 | process.exit(1); 514 | }); 515 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "Node16", 5 | "moduleResolution": "Node16", 6 | "outDir": "./build", 7 | "rootDir": "./src", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true 12 | }, 13 | "include": ["src/**/*"], 14 | "exclude": ["node_modules"] 15 | } 16 | --------------------------------------------------------------------------------