[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EFFNA0TYVPADR1M5DMPT77":3,"skill-same:01M6EFFNA0TYVPADR1M5DMPT77":58},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":25,"publishedAt":31,"linkOnly":32,"markdownContent":33,"markdownBody":33,"frontMatter":34,"refName":35,"commitSha":36,"skillDirectory":37,"forksCount":38,"repositoryHtmlUrl":39,"repositoryHomepageUrl":40,"ownerHtmlUrl":41,"ownerBlogUrl":6,"ownerDescription":42,"updatedAt":43,"install":44,"resources":57},"01M6EFFNA0TYVPADR1M5DMPT77","mcp-server-builder",null,"ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FTerminalSkills\u002Fskills\u002Fmcp-server-builder\u002FSKILL.md",[17,22],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",[26,27,28,29,30],"MCP","mcp server","server","mcp server builder","builder","2026-11-10 10:12:30",false,"# MCP Server Builder\n\n## Overview\n\nCreate Model Context Protocol (MCP) servers that expose tools, resources, and prompts to AI agents like Claude, Cursor, and other MCP-compatible clients. This skill scaffolds complete MCP server projects with proper typing, error handling, input validation, and deployment configuration.\n\n## Instructions\n\nWhen a user asks to build an MCP server, follow these steps:\n\n### Step 1: Define the server's purpose and capabilities\n\nDetermine what the MCP server will expose:\n- **Tools** — Functions the AI can call (e.g., query a database, call an API, run a search)\n- **Resources** — Data the AI can read (e.g., file contents, database records, config)\n- **Prompts** — Reusable prompt templates with parameters\n\nAsk: What service or data source should the AI agent connect to?\n\n### Step 2: Scaffold the project\n\n**TypeScript (recommended):**\n\n```bash\nmkdir my-mcp-server && cd my-mcp-server\nnpm init -y\nnpm install @modelcontextprotocol\u002Fsdk zod\nnpm install -D typescript @types\u002Fnode\nnpx tsc --init --target ES2022 --module NodeNext --moduleResolution NodeNext --outDir dist\n```\n\nCreate the entry point structure:\n```\nmy-mcp-server\u002F\n├── src\u002F\n│   └── index.ts       # Server entry point\n├── package.json\n└── tsconfig.json\n```\n\nUpdate `package.json`:\n```json\n{\n  \"type\": \"module\",\n  \"bin\": { \"my-mcp-server\": \".\u002Fdist\u002Findex.js\" },\n  \"scripts\": {\n    \"build\": \"tsc\",\n    \"start\": \"node dist\u002Findex.js\"\n  }\n}\n```\n\n**Python:**\n\n```bash\nmkdir my-mcp-server && cd my-mcp-server\npython -m venv .venv && source .venv\u002Fbin\u002Factivate\npip install mcp[cli]\n```\n\n### Step 3: Implement the server\n\n**TypeScript MCP server template:**\n\n```typescript\n#!\u002Fusr\u002Fbin\u002Fenv node\nimport { McpServer } from '@modelcontextprotocol\u002Fsdk\u002Fserver\u002Fmcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol\u002Fsdk\u002Fserver\u002Fstdio.js';\nimport { z } from 'zod';\n\nconst server = new McpServer({\n  name: 'my-mcp-server',\n  version: '1.0.0',\n});\n\n\u002F\u002F Define a tool\nserver.tool(\n  'search_issues',\n  'Search GitHub issues by query. Returns title, number, state, and URL.',\n  {\n    query: z.string().describe('Search query for issues'),\n    repo: z.string().describe('Repository in owner\u002Frepo format'),\n    state: z.enum(['open', 'closed', 'all']).default('open').describe('Issue state filter'),\n  },\n  async ({ query, repo, state }) => {\n    const response = await fetch(\n      `https:\u002F\u002Fapi.github.com\u002Fsearch\u002Fissues?q=${encodeURIComponent(query)}+repo:${repo}+state:${state}`\n    );\n    if (!response.ok) {\n      return { content: [{ type: 'text', text: `Error: ${response.statusText}` }], isError: true };\n    }\n    const data = await response.json();\n    const results = data.items.slice(0, 10).map((issue: any) =>\n      `#${issue.number} [${issue.state}] ${issue.title}\\n  ${issue.html_url}`\n    ).join('\\n\\n');\n\n    return { content: [{ type: 'text', text: results || 'No issues found.' }] };\n  }\n);\n\n\u002F\u002F Define a resource\nserver.resource(\n  'repo-readme',\n  'github:\u002F\u002Freadme\u002F{owner}\u002F{repo}',\n  async (uri) => {\n    const [owner, repo] = uri.pathname.split('\u002F').filter(Boolean);\n    const response = await fetch(`https:\u002F\u002Fapi.github.com\u002Frepos\u002F${owner}\u002F${repo}\u002Freadme`, {\n      headers: { Accept: 'application\u002Fvnd.github.raw' },\n    });\n    return { contents: [{ uri: uri.href, text: await response.text(), mimeType: 'text\u002Fmarkdown' }] };\n  }\n);\n\n\u002F\u002F Start the server\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n```\n\n**Python MCP server template:**\n\n```python\nfrom mcp.server.fastmcp import FastMCP\nimport httpx\n\nmcp = FastMCP(\"my-mcp-server\")\n\n@mcp.tool()\nasync def search_issues(query: str, repo: str, state: str = \"open\") -> str:\n    \"\"\"Search GitHub issues by query. Returns title, number, state, and URL.\"\"\"\n    async with httpx.AsyncClient() as client:\n        resp = await client.get(\n            \"https:\u002F\u002Fapi.github.com\u002Fsearch\u002Fissues\",\n            params={\"q\": f\"{query} repo:{repo} state:{state}\"},\n        )\n        resp.raise_for_status()\n        items = resp.json()[\"items\"][:10]\n        return \"\\n\\n\".join(\n            f\"#{i['number']} [{i['state']}] {i['title']}\\n  {i['html_url']}\"\n            for i in items\n        ) or \"No issues found.\"\n\n@mcp.resource(\"github:\u002F\u002Freadme\u002F{owner}\u002F{repo}\")\nasync def repo_readme(owner: str, repo: str) -> str:\n    \"\"\"Fetch the README for a GitHub repository.\"\"\"\n    async with httpx.AsyncClient() as client:\n        resp = await client.get(\n            f\"https:\u002F\u002Fapi.github.com\u002Frepos\u002F{owner}\u002F{repo}\u002Freadme\",\n            headers={\"Accept\": \"application\u002Fvnd.github.raw\"},\n        )\n        return resp.text\n\nif __name__ == \"__main__\":\n    mcp.run()\n```\n\n### Step 4: Add client configuration\n\nGenerate the MCP client config for the user:\n\n**Claude Desktop (`claude_desktop_config.json`):**\n```json\n{\n  \"mcpServers\": {\n    \"my-mcp-server\": {\n      \"command\": \"node\",\n      \"args\": [\"\u002Fabsolute\u002Fpath\u002Fto\u002Fdist\u002Findex.js\"],\n      \"env\": {\n        \"GITHUB_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\n**For Python servers:**\n```json\n{\n  \"mcpServers\": {\n    \"my-mcp-server\": {\n      \"command\": \"python\",\n      \"args\": [\"\u002Fabsolute\u002Fpath\u002Fto\u002Fserver.py\"]\n    }\n  }\n}\n```\n\n### Step 5: Test the server\n\n```bash\n# TypeScript — build and test\nnpm run build\necho '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools\u002Flist\"}' | node dist\u002Findex.js\n\n# Python — test with MCP inspector\nmcp dev server.py\n```\n\nVerify:\n- All tools appear in `tools\u002Flist` response\n- Tool inputs are validated (try invalid params)\n- Error responses are graceful, not stack traces\n\n## Examples\n\n### Example 1: MCP server for a PostgreSQL database\n\n**User request:** \"Build an MCP server so Claude can query my Postgres database\"\n\n**Actions taken:**\n1. Scaffolded TypeScript MCP project with `pg` driver\n2. Created tools: `run_query` (read-only SQL), `list_tables`, `describe_table`\n3. Added connection pooling and query timeout (30s)\n4. Restricted to SELECT queries only (safety)\n\n**Key tool implementation:**\n```typescript\nserver.tool(\n  'run_query',\n  'Execute a read-only SQL query against the database. Only SELECT statements allowed.',\n  { sql: z.string().describe('SQL SELECT query to execute') },\n  async ({ sql }) => {\n    if (!\u002F^\\s*SELECT\\b\u002Fi.test(sql)) {\n      return { content: [{ type: 'text', text: 'Error: Only SELECT queries are allowed.' }], isError: true };\n    }\n    const result = await pool.query({ text: sql, timeout: 30000 });\n    const formatted = result.rows.map(r => JSON.stringify(r)).join('\\n');\n    return { content: [{ type: 'text', text: `${result.rowCount} rows:\\n${formatted}` }] };\n  }\n);\n```\n\n**Result:** 3 tools created, tested with MCP inspector, config generated for Claude Desktop.\n\n### Example 2: MCP server wrapping a REST API (Jira)\n\n**User request:** \"Create an MCP server for Jira so I can manage tickets from Claude\"\n\n**Actions taken:**\n1. Created Python FastMCP server with httpx\n2. Implemented tools: `search_tickets`, `create_ticket`, `update_status`, `add_comment`\n3. Added authentication via environment variable `JIRA_API_TOKEN`\n4. Input validation with proper error messages\n\n**Tools created:**\n```\n- search_tickets(jql: str, max_results: int = 10) → Search Jira issues using JQL\n- create_ticket(project: str, summary: str, description: str, type: str) → Create a new issue\n- update_status(ticket_key: str, status: str) → Transition issue status\n- add_comment(ticket_key: str, body: str) → Add a comment to an issue\n```\n\n**Result:** 4 tools, all tested. User can now ask Claude: \"Find all open bugs in PROJECT assigned to me\" and Claude calls `search_tickets` with the appropriate JQL.\n\n## Guidelines\n\n- Always validate tool inputs with Zod (TypeScript) or type hints (Python). Never trust raw input.\n- Return structured, readable text from tools — the AI will interpret it for the user.\n- Use `isError: true` in tool responses for failures so the AI knows to retry or report the error.\n- Keep tool descriptions clear and specific — the AI uses them to decide when to call each tool.\n- For database tools, enforce read-only access by default. Only allow writes if explicitly requested.\n- Store API keys and credentials in environment variables, never hardcode them.\n- Add timeouts to all external calls (HTTP requests, database queries) to prevent hangs.\n- Limit response sizes — if a query returns 10,000 rows, paginate or truncate.\n- Use stdio transport for local development, SSE\u002FHTTP transport for remote deployment.\n- Test every tool with the MCP inspector (`npx @modelcontextprotocol\u002Finspector`) before shipping.\n- Include a README with setup instructions, required env vars, and example Claude Desktop config.\n",{},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002FTerminalSkills\u002Fskills\u002Fmcp-server-builder",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":7,"skillName":5,"commands":45,"prompt":55,"zipAvailable":56},[46,49,52],{"tool":47,"command":48},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill mcp-server-builder",{"tool":50,"command":51},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill mcp-server-builder",{"tool":53,"command":54},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill mcp-server-builder","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FTerminalSkills\u002Fskills\u002Fmcp-server-builder\u002FSKILL.md",true,[],[59,69,78,87,93,100],{"skillNo":60,"name":61,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":62,"categories":63,"keywords":65,"publishedAt":31},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[64],{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},[66,67,68],"model","model hierarchy","model hierarchy skill",{"skillNo":70,"name":71,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":72,"categories":73,"keywords":75,"publishedAt":31},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[74],{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},[26,76,77],"zoom","zoom mcp",{"skillNo":79,"name":80,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":83,"publishedAt":31},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[84,85,86,76],"sdk","zoom apps sdk","apps",{"skillNo":88,"name":89,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":90,"categories":91,"keywords":92,"publishedAt":31},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[89],{"skillNo":94,"name":95,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":99,"publishedAt":31},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[98],{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},[95],{"skillNo":101,"name":102,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":105,"publishedAt":31},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[102]]