[{"data":1,"prerenderedAt":6249},["ShallowReactive",2],{"doc-page:\u002Fdocs\u002Fmcp-server-development":3},{"doc":4,"prev":6216,"next":6223,"resolvedType":8,"readingMinutes":293,"audience":6225,"checklist":6229,"related":6233},{"path":5,"title":6,"description":7,"docType":8,"resourceKind":9,"categoryId":10,"categoryLabel":11,"updatedAt":12,"publishedAt":12,"icon":13,"body":14},"\u002Fdocs\u002Fmcp-server-development","MCP 服务器开发指南","Model Context Protocol 服务器开发教程，为 AI 代理提供自定义工具","article",null,"ai-tools","AI 工具","2026-02-28","i-carbon-chat-bot",{"type":15,"value":16,"toc":6155},"minimark",[17,21,25,28,32,45,49,53,86,89,92,113,116,119,176,180,187,724,728,733,1137,1140,1143,1206,1209,1264,1267,1270,1273,1466,1469,1630,1633,1758,1761,1764,1884,1887,2073,2076,2079,2202,2205,2354,2357,2360,2548,2551,2678,2681,2830,2833,2837,3558,3562,3974,3978,4621,4624,4628,4647,4654,4665,4668,4848,4851,5049,5052,5056,5125,5131,5190,5194,5298,5304,5358,5362,5424,5427,5491,5494,5498,5542,5546,5628,5632,5731,5735,5865,5869,6021,6024,6027,6044,6047,6051,6054,6068,6072,6075,6078,6081,6084,6105,6108,6151],[18,19,6],"h1",{"id":20},"mcp-服务器开发指南",[22,23,24],"p",{},"Model Context Protocol (MCP) 是一个开放协议，允许 AI 代理通过标准化接口访问外部工具和数据源。本指南教你如何开发自定义 MCP 服务器。",[22,26,27],{},"这页适合作为“自己给 AI 代理造工具”的开发文档。真正的重点不是先把所有能力都做出来，而是先把输入、输出、权限边界、错误处理和调试链路设计清楚。",[29,30,31],"h2",{"id":31},"适合谁读",[33,34,35,39,42],"ul",{},[36,37,38],"li",{},"想把内部系统接给 AI 代理的人",[36,40,41],{},"想把脚本、数据库、SaaS API 包成标准工具的人",[36,43,44],{},"想做团队内部专用 Agent 能力层的人",[29,46,48],{"id":47},"mcp-协议概述","MCP 协议概述",[50,51,52],"h3",{"id":52},"核心概念",[33,54,55,62,68,74,80],{},[36,56,57,61],{},[58,59,60],"strong",{},"Server","：提供工具和资源的服务",[36,63,64,67],{},[58,65,66],{},"Client","：AI 代理，调用服务器的工具",[36,69,70,73],{},[58,71,72],{},"Tool","：服务器暴露的功能（函数）",[36,75,76,79],{},[58,77,78],{},"Resource","：服务器提供的数据（文件、API 响应等）",[36,81,82,85],{},[58,83,84],{},"Prompt","：预定义的提示词模板",[50,87,88],{"id":88},"通信方式",[22,90,91],{},"MCP 支持三种传输方式：",[93,94,95,101,107],"ol",{},[36,96,97,100],{},[58,98,99],{},"stdio","：标准输入输出（最常用）",[36,102,103,106],{},[58,104,105],{},"SSE","：Server-Sent Events（HTTP 流）",[36,108,109,112],{},[58,110,111],{},"WebSocket","：双向通信",[29,114,115],{"id":115},"快速开始",[50,117,118],{"id":118},"环境准备",[120,121,126],"pre",{"className":122,"code":123,"language":124,"meta":125,"style":125},"language-bash shiki shiki-themes github-light github-dark","# Node.js 实现\nnpm install @modelcontextprotocol\u002Fsdk\n\n# Python 实现\npip install mcp\n","bash","",[127,128,129,138,152,159,165],"code",{"__ignoreMap":125},[130,131,134],"span",{"class":132,"line":133},"line",1,[130,135,137],{"class":136},"sJ8bj","# Node.js 实现\n",[130,139,141,145,149],{"class":132,"line":140},2,[130,142,144],{"class":143},"sScJk","npm",[130,146,148],{"class":147},"sZZnC"," install",[130,150,151],{"class":147}," @modelcontextprotocol\u002Fsdk\n",[130,153,155],{"class":132,"line":154},3,[130,156,158],{"emptyLinePlaceholder":157},true,"\n",[130,160,162],{"class":132,"line":161},4,[130,163,164],{"class":136},"# Python 实现\n",[130,166,168,171,173],{"class":132,"line":167},5,[130,169,170],{"class":143},"pip",[130,172,148],{"class":147},[130,174,175],{"class":147}," mcp\n",[50,177,179],{"id":178},"最小示例nodejs","最小示例（Node.js）",[22,181,182,183,186],{},"创建 ",[127,184,185],{},"server.js","：",[120,188,192],{"className":189,"code":190,"language":191,"meta":125,"style":125},"language-javascript shiki shiki-themes github-light github-dark","import { Server } from \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002Findex.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002Fstdio.js\";\n\nconst server = new Server(\n  {\n    name: \"my-mcp-server\",\n    version: \"1.0.0\",\n  },\n  {\n    capabilities: {\n      tools: {},\n    },\n  },\n);\n\n\u002F\u002F 注册工具\nserver.setRequestHandler(\"tools\u002Flist\", async () => {\n  return {\n    tools: [\n      {\n        name: \"get_weather\",\n        description: \"获取指定城市的天气信息\",\n        inputSchema: {\n          type: \"object\",\n          properties: {\n            city: {\n              type: \"string\",\n              description: \"城市名称\",\n            },\n          },\n          required: [\"city\"],\n        },\n      },\n    ],\n  };\n});\n\n\u002F\u002F 处理工具调用\nserver.setRequestHandler(\"tools\u002Fcall\", async (request) => {\n  if (request.params.name === \"get_weather\") {\n    const city = request.params.arguments.city;\n    \u002F\u002F 实际应用中调用天气 API\n    return {\n      content: [\n        {\n          type: \"text\",\n          text: `${city} 的天气：晴天，25°C`,\n        },\n      ],\n    };\n  }\n  throw new Error(\"Unknown tool\");\n});\n\n\u002F\u002F 启动服务器\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n","javascript",[127,193,194,213,227,231,252,257,269,280,286,291,297,303,309,314,320,325,331,361,369,375,381,392,403,409,420,426,432,443,454,460,466,478,484,490,496,502,508,513,519,549,567,581,587,595,601,607,617,634,639,645,651,657,675,680,685,691,709],{"__ignoreMap":125},[130,195,196,200,204,207,210],{"class":132,"line":133},[130,197,199],{"class":198},"szBVR","import",[130,201,203],{"class":202},"sVt8B"," { Server } ",[130,205,206],{"class":198},"from",[130,208,209],{"class":147}," \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002Findex.js\"",[130,211,212],{"class":202},";\n",[130,214,215,217,220,222,225],{"class":132,"line":140},[130,216,199],{"class":198},[130,218,219],{"class":202}," { StdioServerTransport } ",[130,221,206],{"class":198},[130,223,224],{"class":147}," \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002Fstdio.js\"",[130,226,212],{"class":202},[130,228,229],{"class":132,"line":154},[130,230,158],{"emptyLinePlaceholder":157},[130,232,233,236,240,243,246,249],{"class":132,"line":161},[130,234,235],{"class":198},"const",[130,237,239],{"class":238},"sj4cs"," server",[130,241,242],{"class":198}," =",[130,244,245],{"class":198}," new",[130,247,248],{"class":143}," Server",[130,250,251],{"class":202},"(\n",[130,253,254],{"class":132,"line":167},[130,255,256],{"class":202},"  {\n",[130,258,260,263,266],{"class":132,"line":259},6,[130,261,262],{"class":202},"    name: ",[130,264,265],{"class":147},"\"my-mcp-server\"",[130,267,268],{"class":202},",\n",[130,270,272,275,278],{"class":132,"line":271},7,[130,273,274],{"class":202},"    version: ",[130,276,277],{"class":147},"\"1.0.0\"",[130,279,268],{"class":202},[130,281,283],{"class":132,"line":282},8,[130,284,285],{"class":202},"  },\n",[130,287,289],{"class":132,"line":288},9,[130,290,256],{"class":202},[130,292,294],{"class":132,"line":293},10,[130,295,296],{"class":202},"    capabilities: {\n",[130,298,300],{"class":132,"line":299},11,[130,301,302],{"class":202},"      tools: {},\n",[130,304,306],{"class":132,"line":305},12,[130,307,308],{"class":202},"    },\n",[130,310,312],{"class":132,"line":311},13,[130,313,285],{"class":202},[130,315,317],{"class":132,"line":316},14,[130,318,319],{"class":202},");\n",[130,321,323],{"class":132,"line":322},15,[130,324,158],{"emptyLinePlaceholder":157},[130,326,328],{"class":132,"line":327},16,[130,329,330],{"class":136},"\u002F\u002F 注册工具\n",[130,332,334,337,340,343,346,349,352,355,358],{"class":132,"line":333},17,[130,335,336],{"class":202},"server.",[130,338,339],{"class":143},"setRequestHandler",[130,341,342],{"class":202},"(",[130,344,345],{"class":147},"\"tools\u002Flist\"",[130,347,348],{"class":202},", ",[130,350,351],{"class":198},"async",[130,353,354],{"class":202}," () ",[130,356,357],{"class":198},"=>",[130,359,360],{"class":202}," {\n",[130,362,364,367],{"class":132,"line":363},18,[130,365,366],{"class":198},"  return",[130,368,360],{"class":202},[130,370,372],{"class":132,"line":371},19,[130,373,374],{"class":202},"    tools: [\n",[130,376,378],{"class":132,"line":377},20,[130,379,380],{"class":202},"      {\n",[130,382,384,387,390],{"class":132,"line":383},21,[130,385,386],{"class":202},"        name: ",[130,388,389],{"class":147},"\"get_weather\"",[130,391,268],{"class":202},[130,393,395,398,401],{"class":132,"line":394},22,[130,396,397],{"class":202},"        description: ",[130,399,400],{"class":147},"\"获取指定城市的天气信息\"",[130,402,268],{"class":202},[130,404,406],{"class":132,"line":405},23,[130,407,408],{"class":202},"        inputSchema: {\n",[130,410,412,415,418],{"class":132,"line":411},24,[130,413,414],{"class":202},"          type: ",[130,416,417],{"class":147},"\"object\"",[130,419,268],{"class":202},[130,421,423],{"class":132,"line":422},25,[130,424,425],{"class":202},"          properties: {\n",[130,427,429],{"class":132,"line":428},26,[130,430,431],{"class":202},"            city: {\n",[130,433,435,438,441],{"class":132,"line":434},27,[130,436,437],{"class":202},"              type: ",[130,439,440],{"class":147},"\"string\"",[130,442,268],{"class":202},[130,444,446,449,452],{"class":132,"line":445},28,[130,447,448],{"class":202},"              description: ",[130,450,451],{"class":147},"\"城市名称\"",[130,453,268],{"class":202},[130,455,457],{"class":132,"line":456},29,[130,458,459],{"class":202},"            },\n",[130,461,463],{"class":132,"line":462},30,[130,464,465],{"class":202},"          },\n",[130,467,469,472,475],{"class":132,"line":468},31,[130,470,471],{"class":202},"          required: [",[130,473,474],{"class":147},"\"city\"",[130,476,477],{"class":202},"],\n",[130,479,481],{"class":132,"line":480},32,[130,482,483],{"class":202},"        },\n",[130,485,487],{"class":132,"line":486},33,[130,488,489],{"class":202},"      },\n",[130,491,493],{"class":132,"line":492},34,[130,494,495],{"class":202},"    ],\n",[130,497,499],{"class":132,"line":498},35,[130,500,501],{"class":202},"  };\n",[130,503,505],{"class":132,"line":504},36,[130,506,507],{"class":202},"});\n",[130,509,511],{"class":132,"line":510},37,[130,512,158],{"emptyLinePlaceholder":157},[130,514,516],{"class":132,"line":515},38,[130,517,518],{"class":136},"\u002F\u002F 处理工具调用\n",[130,520,522,524,526,528,531,533,535,538,542,545,547],{"class":132,"line":521},39,[130,523,336],{"class":202},[130,525,339],{"class":143},[130,527,342],{"class":202},[130,529,530],{"class":147},"\"tools\u002Fcall\"",[130,532,348],{"class":202},[130,534,351],{"class":198},[130,536,537],{"class":202}," (",[130,539,541],{"class":540},"s4XuR","request",[130,543,544],{"class":202},") ",[130,546,357],{"class":198},[130,548,360],{"class":202},[130,550,552,555,558,561,564],{"class":132,"line":551},40,[130,553,554],{"class":198},"  if",[130,556,557],{"class":202}," (request.params.name ",[130,559,560],{"class":198},"===",[130,562,563],{"class":147}," \"get_weather\"",[130,565,566],{"class":202},") {\n",[130,568,570,573,576,578],{"class":132,"line":569},41,[130,571,572],{"class":198},"    const",[130,574,575],{"class":238}," city",[130,577,242],{"class":198},[130,579,580],{"class":202}," request.params.arguments.city;\n",[130,582,584],{"class":132,"line":583},42,[130,585,586],{"class":136},"    \u002F\u002F 实际应用中调用天气 API\n",[130,588,590,593],{"class":132,"line":589},43,[130,591,592],{"class":198},"    return",[130,594,360],{"class":202},[130,596,598],{"class":132,"line":597},44,[130,599,600],{"class":202},"      content: [\n",[130,602,604],{"class":132,"line":603},45,[130,605,606],{"class":202},"        {\n",[130,608,610,612,615],{"class":132,"line":609},46,[130,611,414],{"class":202},[130,613,614],{"class":147},"\"text\"",[130,616,268],{"class":202},[130,618,620,623,626,629,632],{"class":132,"line":619},47,[130,621,622],{"class":202},"          text: ",[130,624,625],{"class":147},"`${",[130,627,628],{"class":202},"city",[130,630,631],{"class":147},"} 的天气：晴天，25°C`",[130,633,268],{"class":202},[130,635,637],{"class":132,"line":636},48,[130,638,483],{"class":202},[130,640,642],{"class":132,"line":641},49,[130,643,644],{"class":202},"      ],\n",[130,646,648],{"class":132,"line":647},50,[130,649,650],{"class":202},"    };\n",[130,652,654],{"class":132,"line":653},51,[130,655,656],{"class":202},"  }\n",[130,658,660,663,665,668,670,673],{"class":132,"line":659},52,[130,661,662],{"class":198},"  throw",[130,664,245],{"class":198},[130,666,667],{"class":143}," Error",[130,669,342],{"class":202},[130,671,672],{"class":147},"\"Unknown tool\"",[130,674,319],{"class":202},[130,676,678],{"class":132,"line":677},53,[130,679,507],{"class":202},[130,681,683],{"class":132,"line":682},54,[130,684,158],{"emptyLinePlaceholder":157},[130,686,688],{"class":132,"line":687},55,[130,689,690],{"class":136},"\u002F\u002F 启动服务器\n",[130,692,694,696,699,701,703,706],{"class":132,"line":693},56,[130,695,235],{"class":198},[130,697,698],{"class":238}," transport",[130,700,242],{"class":198},[130,702,245],{"class":198},[130,704,705],{"class":143}," StdioServerTransport",[130,707,708],{"class":202},"();\n",[130,710,712,715,718,721],{"class":132,"line":711},57,[130,713,714],{"class":198},"await",[130,716,717],{"class":202}," server.",[130,719,720],{"class":143},"connect",[130,722,723],{"class":202},"(transport);\n",[50,725,727],{"id":726},"最小示例python","最小示例（Python）",[22,729,182,730,186],{},[127,731,732],{},"server.py",[120,734,738],{"className":735,"code":736,"language":737,"meta":125,"style":125},"language-python shiki shiki-themes github-light github-dark","from mcp.server import Server\nfrom mcp.server.stdio import stdio_server\nfrom mcp.types import Tool, TextContent\n\napp = Server(\"my-mcp-server\")\n\n@app.list_tools()\nasync def list_tools() -> list[Tool]:\n    return [\n        Tool(\n            name=\"get_weather\",\n            description=\"获取指定城市的天气信息\",\n            inputSchema={\n                \"type\": \"object\",\n                \"properties\": {\n                    \"city\": {\n                        \"type\": \"string\",\n                        \"description\": \"城市名称\"\n                    }\n                },\n                \"required\": [\"city\"]\n            }\n        )\n    ]\n\n@app.call_tool()\nasync def call_tool(name: str, arguments: dict) -> list[TextContent]:\n    if name == \"get_weather\":\n        city = arguments[\"city\"]\n        # 实际应用中调用天气 API\n        return [\n            TextContent(\n                type=\"text\",\n                text=f\"{city} 的天气：晴天，25°C\"\n            )\n        ]\n    raise ValueError(f\"Unknown tool: {name}\")\n\nif __name__ == \"__main__\":\n    import asyncio\n    asyncio.run(stdio_server(app))\n","python",[127,739,740,752,764,776,780,796,800,808,821,828,833,844,855,865,877,885,892,903,913,918,923,936,941,946,951,955,962,986,1002,1016,1021,1028,1033,1044,1068,1073,1078,1104,1108,1124,1132],{"__ignoreMap":125},[130,741,742,744,747,749],{"class":132,"line":133},[130,743,206],{"class":198},[130,745,746],{"class":202}," mcp.server ",[130,748,199],{"class":198},[130,750,751],{"class":202}," Server\n",[130,753,754,756,759,761],{"class":132,"line":140},[130,755,206],{"class":198},[130,757,758],{"class":202}," mcp.server.stdio ",[130,760,199],{"class":198},[130,762,763],{"class":202}," stdio_server\n",[130,765,766,768,771,773],{"class":132,"line":154},[130,767,206],{"class":198},[130,769,770],{"class":202}," mcp.types ",[130,772,199],{"class":198},[130,774,775],{"class":202}," Tool, TextContent\n",[130,777,778],{"class":132,"line":161},[130,779,158],{"emptyLinePlaceholder":157},[130,781,782,785,788,791,793],{"class":132,"line":167},[130,783,784],{"class":202},"app ",[130,786,787],{"class":198},"=",[130,789,790],{"class":202}," Server(",[130,792,265],{"class":147},[130,794,795],{"class":202},")\n",[130,797,798],{"class":132,"line":259},[130,799,158],{"emptyLinePlaceholder":157},[130,801,802,805],{"class":132,"line":271},[130,803,804],{"class":143},"@app.list_tools",[130,806,807],{"class":202},"()\n",[130,809,810,812,815,818],{"class":132,"line":282},[130,811,351],{"class":198},[130,813,814],{"class":198}," def",[130,816,817],{"class":143}," list_tools",[130,819,820],{"class":202},"() -> list[Tool]:\n",[130,822,823,825],{"class":132,"line":288},[130,824,592],{"class":198},[130,826,827],{"class":202}," [\n",[130,829,830],{"class":132,"line":293},[130,831,832],{"class":202},"        Tool(\n",[130,834,835,838,840,842],{"class":132,"line":299},[130,836,837],{"class":540},"            name",[130,839,787],{"class":198},[130,841,389],{"class":147},[130,843,268],{"class":202},[130,845,846,849,851,853],{"class":132,"line":305},[130,847,848],{"class":540},"            description",[130,850,787],{"class":198},[130,852,400],{"class":147},[130,854,268],{"class":202},[130,856,857,860,862],{"class":132,"line":311},[130,858,859],{"class":540},"            inputSchema",[130,861,787],{"class":198},[130,863,864],{"class":202},"{\n",[130,866,867,870,873,875],{"class":132,"line":316},[130,868,869],{"class":147},"                \"type\"",[130,871,872],{"class":202},": ",[130,874,417],{"class":147},[130,876,268],{"class":202},[130,878,879,882],{"class":132,"line":322},[130,880,881],{"class":147},"                \"properties\"",[130,883,884],{"class":202},": {\n",[130,886,887,890],{"class":132,"line":327},[130,888,889],{"class":147},"                    \"city\"",[130,891,884],{"class":202},[130,893,894,897,899,901],{"class":132,"line":333},[130,895,896],{"class":147},"                        \"type\"",[130,898,872],{"class":202},[130,900,440],{"class":147},[130,902,268],{"class":202},[130,904,905,908,910],{"class":132,"line":363},[130,906,907],{"class":147},"                        \"description\"",[130,909,872],{"class":202},[130,911,912],{"class":147},"\"城市名称\"\n",[130,914,915],{"class":132,"line":371},[130,916,917],{"class":202},"                    }\n",[130,919,920],{"class":132,"line":377},[130,921,922],{"class":202},"                },\n",[130,924,925,928,931,933],{"class":132,"line":383},[130,926,927],{"class":147},"                \"required\"",[130,929,930],{"class":202},": [",[130,932,474],{"class":147},[130,934,935],{"class":202},"]\n",[130,937,938],{"class":132,"line":394},[130,939,940],{"class":202},"            }\n",[130,942,943],{"class":132,"line":405},[130,944,945],{"class":202},"        )\n",[130,947,948],{"class":132,"line":411},[130,949,950],{"class":202},"    ]\n",[130,952,953],{"class":132,"line":422},[130,954,158],{"emptyLinePlaceholder":157},[130,956,957,960],{"class":132,"line":428},[130,958,959],{"class":143},"@app.call_tool",[130,961,807],{"class":202},[130,963,964,966,968,971,974,977,980,983],{"class":132,"line":434},[130,965,351],{"class":198},[130,967,814],{"class":198},[130,969,970],{"class":143}," call_tool",[130,972,973],{"class":202},"(name: ",[130,975,976],{"class":238},"str",[130,978,979],{"class":202},", arguments: ",[130,981,982],{"class":238},"dict",[130,984,985],{"class":202},") -> list[TextContent]:\n",[130,987,988,991,994,997,999],{"class":132,"line":445},[130,989,990],{"class":198},"    if",[130,992,993],{"class":202}," name ",[130,995,996],{"class":198},"==",[130,998,563],{"class":147},[130,1000,1001],{"class":202},":\n",[130,1003,1004,1007,1009,1012,1014],{"class":132,"line":456},[130,1005,1006],{"class":202},"        city ",[130,1008,787],{"class":198},[130,1010,1011],{"class":202}," arguments[",[130,1013,474],{"class":147},[130,1015,935],{"class":202},[130,1017,1018],{"class":132,"line":462},[130,1019,1020],{"class":136},"        # 实际应用中调用天气 API\n",[130,1022,1023,1026],{"class":132,"line":468},[130,1024,1025],{"class":198},"        return",[130,1027,827],{"class":202},[130,1029,1030],{"class":132,"line":480},[130,1031,1032],{"class":202},"            TextContent(\n",[130,1034,1035,1038,1040,1042],{"class":132,"line":486},[130,1036,1037],{"class":540},"                type",[130,1039,787],{"class":198},[130,1041,614],{"class":147},[130,1043,268],{"class":202},[130,1045,1046,1049,1051,1054,1057,1060,1062,1065],{"class":132,"line":492},[130,1047,1048],{"class":540},"                text",[130,1050,787],{"class":198},[130,1052,1053],{"class":198},"f",[130,1055,1056],{"class":147},"\"",[130,1058,1059],{"class":238},"{",[130,1061,628],{"class":202},[130,1063,1064],{"class":238},"}",[130,1066,1067],{"class":147}," 的天气：晴天，25°C\"\n",[130,1069,1070],{"class":132,"line":498},[130,1071,1072],{"class":202},"            )\n",[130,1074,1075],{"class":132,"line":504},[130,1076,1077],{"class":202},"        ]\n",[130,1079,1080,1083,1086,1088,1090,1093,1095,1098,1100,1102],{"class":132,"line":510},[130,1081,1082],{"class":198},"    raise",[130,1084,1085],{"class":238}," ValueError",[130,1087,342],{"class":202},[130,1089,1053],{"class":198},[130,1091,1092],{"class":147},"\"Unknown tool: ",[130,1094,1059],{"class":238},[130,1096,1097],{"class":202},"name",[130,1099,1064],{"class":238},[130,1101,1056],{"class":147},[130,1103,795],{"class":202},[130,1105,1106],{"class":132,"line":515},[130,1107,158],{"emptyLinePlaceholder":157},[130,1109,1110,1113,1116,1119,1122],{"class":132,"line":521},[130,1111,1112],{"class":198},"if",[130,1114,1115],{"class":238}," __name__",[130,1117,1118],{"class":198}," ==",[130,1120,1121],{"class":147}," \"__main__\"",[130,1123,1001],{"class":202},[130,1125,1126,1129],{"class":132,"line":551},[130,1127,1128],{"class":198},"    import",[130,1130,1131],{"class":202}," asyncio\n",[130,1133,1134],{"class":132,"line":569},[130,1135,1136],{"class":202},"    asyncio.run(stdio_server(app))\n",[50,1138,1139],{"id":1139},"配置客户端",[22,1141,1142],{},"在 AI 代理（如 nanobot、OpenClaw）中配置：",[120,1144,1148],{"className":1145,"code":1146,"language":1147,"meta":125,"style":125},"language-json shiki shiki-themes github-light github-dark","{\n  \"mcpServers\": {\n    \"weather\": {\n      \"command\": \"node\",\n      \"args\": [\"server.js\"]\n    }\n  }\n}\n","json",[127,1149,1150,1154,1161,1168,1180,1192,1197,1201],{"__ignoreMap":125},[130,1151,1152],{"class":132,"line":133},[130,1153,864],{"class":202},[130,1155,1156,1159],{"class":132,"line":140},[130,1157,1158],{"class":238},"  \"mcpServers\"",[130,1160,884],{"class":202},[130,1162,1163,1166],{"class":132,"line":154},[130,1164,1165],{"class":238},"    \"weather\"",[130,1167,884],{"class":202},[130,1169,1170,1173,1175,1178],{"class":132,"line":161},[130,1171,1172],{"class":238},"      \"command\"",[130,1174,872],{"class":202},[130,1176,1177],{"class":147},"\"node\"",[130,1179,268],{"class":202},[130,1181,1182,1185,1187,1190],{"class":132,"line":167},[130,1183,1184],{"class":238},"      \"args\"",[130,1186,930],{"class":202},[130,1188,1189],{"class":147},"\"server.js\"",[130,1191,935],{"class":202},[130,1193,1194],{"class":132,"line":259},[130,1195,1196],{"class":202},"    }\n",[130,1198,1199],{"class":132,"line":271},[130,1200,656],{"class":202},[130,1202,1203],{"class":132,"line":282},[130,1204,1205],{"class":202},"}\n",[22,1207,1208],{},"或 Python 版本：",[120,1210,1212],{"className":1145,"code":1211,"language":1147,"meta":125,"style":125},"{\n  \"mcpServers\": {\n    \"weather\": {\n      \"command\": \"python\",\n      \"args\": [\"server.py\"]\n    }\n  }\n}\n",[127,1213,1214,1218,1224,1230,1241,1252,1256,1260],{"__ignoreMap":125},[130,1215,1216],{"class":132,"line":133},[130,1217,864],{"class":202},[130,1219,1220,1222],{"class":132,"line":140},[130,1221,1158],{"class":238},[130,1223,884],{"class":202},[130,1225,1226,1228],{"class":132,"line":154},[130,1227,1165],{"class":238},[130,1229,884],{"class":202},[130,1231,1232,1234,1236,1239],{"class":132,"line":161},[130,1233,1172],{"class":238},[130,1235,872],{"class":202},[130,1237,1238],{"class":147},"\"python\"",[130,1240,268],{"class":202},[130,1242,1243,1245,1247,1250],{"class":132,"line":167},[130,1244,1184],{"class":238},[130,1246,930],{"class":202},[130,1248,1249],{"class":147},"\"server.py\"",[130,1251,935],{"class":202},[130,1253,1254],{"class":132,"line":259},[130,1255,1196],{"class":202},[130,1257,1258],{"class":132,"line":271},[130,1259,656],{"class":202},[130,1261,1262],{"class":132,"line":282},[130,1263,1205],{"class":202},[29,1265,1266],{"id":1266},"工具开发",[50,1268,1269],{"id":1269},"输入验证",[22,1271,1272],{},"使用 JSON Schema 定义输入：",[120,1274,1276],{"className":189,"code":1275,"language":191,"meta":125,"style":125},"{\n  name: \"search_files\",\n  description: \"在指定目录搜索文件\",\n  inputSchema: {\n    type: \"object\",\n    properties: {\n      directory: {\n        type: \"string\",\n        description: \"搜索目录路径\"\n      },\n      pattern: {\n        type: \"string\",\n        description: \"文件名模式（支持通配符）\"\n      },\n      recursive: {\n        type: \"boolean\",\n        description: \"是否递归搜索子目录\",\n        default: false\n      }\n    },\n    required: [\"directory\", \"pattern\"]\n  }\n}\n",[127,1277,1278,1282,1294,1306,1313,1324,1331,1338,1349,1359,1363,1370,1380,1389,1393,1400,1411,1422,1432,1437,1441,1458,1462],{"__ignoreMap":125},[130,1279,1280],{"class":132,"line":133},[130,1281,864],{"class":202},[130,1283,1284,1287,1289,1292],{"class":132,"line":140},[130,1285,1286],{"class":143},"  name",[130,1288,872],{"class":202},[130,1290,1291],{"class":147},"\"search_files\"",[130,1293,268],{"class":202},[130,1295,1296,1299,1301,1304],{"class":132,"line":154},[130,1297,1298],{"class":143},"  description",[130,1300,872],{"class":202},[130,1302,1303],{"class":147},"\"在指定目录搜索文件\"",[130,1305,268],{"class":202},[130,1307,1308,1311],{"class":132,"line":161},[130,1309,1310],{"class":143},"  inputSchema",[130,1312,884],{"class":202},[130,1314,1315,1318,1320,1322],{"class":132,"line":167},[130,1316,1317],{"class":143},"    type",[130,1319,872],{"class":202},[130,1321,417],{"class":147},[130,1323,268],{"class":202},[130,1325,1326,1329],{"class":132,"line":259},[130,1327,1328],{"class":143},"    properties",[130,1330,884],{"class":202},[130,1332,1333,1336],{"class":132,"line":271},[130,1334,1335],{"class":143},"      directory",[130,1337,884],{"class":202},[130,1339,1340,1343,1345,1347],{"class":132,"line":282},[130,1341,1342],{"class":143},"        type",[130,1344,872],{"class":202},[130,1346,440],{"class":147},[130,1348,268],{"class":202},[130,1350,1351,1354,1356],{"class":132,"line":288},[130,1352,1353],{"class":143},"        description",[130,1355,872],{"class":202},[130,1357,1358],{"class":147},"\"搜索目录路径\"\n",[130,1360,1361],{"class":132,"line":293},[130,1362,489],{"class":202},[130,1364,1365,1368],{"class":132,"line":299},[130,1366,1367],{"class":143},"      pattern",[130,1369,884],{"class":202},[130,1371,1372,1374,1376,1378],{"class":132,"line":305},[130,1373,1342],{"class":143},[130,1375,872],{"class":202},[130,1377,440],{"class":147},[130,1379,268],{"class":202},[130,1381,1382,1384,1386],{"class":132,"line":311},[130,1383,1353],{"class":143},[130,1385,872],{"class":202},[130,1387,1388],{"class":147},"\"文件名模式（支持通配符）\"\n",[130,1390,1391],{"class":132,"line":316},[130,1392,489],{"class":202},[130,1394,1395,1398],{"class":132,"line":322},[130,1396,1397],{"class":143},"      recursive",[130,1399,884],{"class":202},[130,1401,1402,1404,1406,1409],{"class":132,"line":327},[130,1403,1342],{"class":143},[130,1405,872],{"class":202},[130,1407,1408],{"class":147},"\"boolean\"",[130,1410,268],{"class":202},[130,1412,1413,1415,1417,1420],{"class":132,"line":333},[130,1414,1353],{"class":143},[130,1416,872],{"class":202},[130,1418,1419],{"class":147},"\"是否递归搜索子目录\"",[130,1421,268],{"class":202},[130,1423,1424,1427,1429],{"class":132,"line":363},[130,1425,1426],{"class":198},"        default",[130,1428,872],{"class":202},[130,1430,1431],{"class":238},"false\n",[130,1433,1434],{"class":132,"line":371},[130,1435,1436],{"class":202},"      }\n",[130,1438,1439],{"class":132,"line":377},[130,1440,308],{"class":202},[130,1442,1443,1446,1448,1451,1453,1456],{"class":132,"line":383},[130,1444,1445],{"class":143},"    required",[130,1447,930],{"class":202},[130,1449,1450],{"class":147},"\"directory\"",[130,1452,348],{"class":202},[130,1454,1455],{"class":147},"\"pattern\"",[130,1457,935],{"class":202},[130,1459,1460],{"class":132,"line":394},[130,1461,656],{"class":202},[130,1463,1464],{"class":132,"line":405},[130,1465,1205],{"class":202},[50,1467,1468],{"id":1468},"返回多种内容类型",[120,1470,1472],{"className":189,"code":1471,"language":191,"meta":125,"style":125},"server.setRequestHandler(\"tools\u002Fcall\", async (request) => {\n  if (request.params.name === \"analyze_image\") {\n    return {\n      content: [\n        {\n          type: \"text\",\n          text: \"图像分析结果：\",\n        },\n        {\n          type: \"image\",\n          data: base64ImageData,\n          mimeType: \"image\u002Fpng\",\n        },\n        {\n          type: \"resource\",\n          uri: \"file:\u002F\u002F\u002Fpath\u002Fto\u002Freport.json\",\n          mimeType: \"application\u002Fjson\",\n        },\n      ],\n    };\n  }\n});\n",[127,1473,1474,1498,1511,1517,1521,1525,1533,1542,1546,1550,1559,1564,1574,1578,1582,1591,1601,1610,1614,1618,1622,1626],{"__ignoreMap":125},[130,1475,1476,1478,1480,1482,1484,1486,1488,1490,1492,1494,1496],{"class":132,"line":133},[130,1477,336],{"class":202},[130,1479,339],{"class":143},[130,1481,342],{"class":202},[130,1483,530],{"class":147},[130,1485,348],{"class":202},[130,1487,351],{"class":198},[130,1489,537],{"class":202},[130,1491,541],{"class":540},[130,1493,544],{"class":202},[130,1495,357],{"class":198},[130,1497,360],{"class":202},[130,1499,1500,1502,1504,1506,1509],{"class":132,"line":140},[130,1501,554],{"class":198},[130,1503,557],{"class":202},[130,1505,560],{"class":198},[130,1507,1508],{"class":147}," \"analyze_image\"",[130,1510,566],{"class":202},[130,1512,1513,1515],{"class":132,"line":154},[130,1514,592],{"class":198},[130,1516,360],{"class":202},[130,1518,1519],{"class":132,"line":161},[130,1520,600],{"class":202},[130,1522,1523],{"class":132,"line":167},[130,1524,606],{"class":202},[130,1526,1527,1529,1531],{"class":132,"line":259},[130,1528,414],{"class":202},[130,1530,614],{"class":147},[130,1532,268],{"class":202},[130,1534,1535,1537,1540],{"class":132,"line":271},[130,1536,622],{"class":202},[130,1538,1539],{"class":147},"\"图像分析结果：\"",[130,1541,268],{"class":202},[130,1543,1544],{"class":132,"line":282},[130,1545,483],{"class":202},[130,1547,1548],{"class":132,"line":288},[130,1549,606],{"class":202},[130,1551,1552,1554,1557],{"class":132,"line":293},[130,1553,414],{"class":202},[130,1555,1556],{"class":147},"\"image\"",[130,1558,268],{"class":202},[130,1560,1561],{"class":132,"line":299},[130,1562,1563],{"class":202},"          data: base64ImageData,\n",[130,1565,1566,1569,1572],{"class":132,"line":305},[130,1567,1568],{"class":202},"          mimeType: ",[130,1570,1571],{"class":147},"\"image\u002Fpng\"",[130,1573,268],{"class":202},[130,1575,1576],{"class":132,"line":311},[130,1577,483],{"class":202},[130,1579,1580],{"class":132,"line":316},[130,1581,606],{"class":202},[130,1583,1584,1586,1589],{"class":132,"line":322},[130,1585,414],{"class":202},[130,1587,1588],{"class":147},"\"resource\"",[130,1590,268],{"class":202},[130,1592,1593,1596,1599],{"class":132,"line":327},[130,1594,1595],{"class":202},"          uri: ",[130,1597,1598],{"class":147},"\"file:\u002F\u002F\u002Fpath\u002Fto\u002Freport.json\"",[130,1600,268],{"class":202},[130,1602,1603,1605,1608],{"class":132,"line":333},[130,1604,1568],{"class":202},[130,1606,1607],{"class":147},"\"application\u002Fjson\"",[130,1609,268],{"class":202},[130,1611,1612],{"class":132,"line":363},[130,1613,483],{"class":202},[130,1615,1616],{"class":132,"line":371},[130,1617,644],{"class":202},[130,1619,1620],{"class":132,"line":377},[130,1621,650],{"class":202},[130,1623,1624],{"class":132,"line":383},[130,1625,656],{"class":202},[130,1627,1628],{"class":132,"line":394},[130,1629,507],{"class":202},[50,1631,1632],{"id":1632},"错误处理",[120,1634,1636],{"className":189,"code":1635,"language":191,"meta":125,"style":125},"server.setRequestHandler(\"tools\u002Fcall\", async (request) => {\n  try {\n    \u002F\u002F 工具逻辑\n  } catch (error) {\n    return {\n      content: [\n        {\n          type: \"text\",\n          text: `错误：${error.message}`,\n        },\n      ],\n      isError: true,\n    };\n  }\n});\n",[127,1637,1638,1662,1669,1674,1685,1691,1695,1699,1707,1728,1732,1736,1746,1750,1754],{"__ignoreMap":125},[130,1639,1640,1642,1644,1646,1648,1650,1652,1654,1656,1658,1660],{"class":132,"line":133},[130,1641,336],{"class":202},[130,1643,339],{"class":143},[130,1645,342],{"class":202},[130,1647,530],{"class":147},[130,1649,348],{"class":202},[130,1651,351],{"class":198},[130,1653,537],{"class":202},[130,1655,541],{"class":540},[130,1657,544],{"class":202},[130,1659,357],{"class":198},[130,1661,360],{"class":202},[130,1663,1664,1667],{"class":132,"line":140},[130,1665,1666],{"class":198},"  try",[130,1668,360],{"class":202},[130,1670,1671],{"class":132,"line":154},[130,1672,1673],{"class":136},"    \u002F\u002F 工具逻辑\n",[130,1675,1676,1679,1682],{"class":132,"line":161},[130,1677,1678],{"class":202},"  } ",[130,1680,1681],{"class":198},"catch",[130,1683,1684],{"class":202}," (error) {\n",[130,1686,1687,1689],{"class":132,"line":167},[130,1688,592],{"class":198},[130,1690,360],{"class":202},[130,1692,1693],{"class":132,"line":259},[130,1694,600],{"class":202},[130,1696,1697],{"class":132,"line":271},[130,1698,606],{"class":202},[130,1700,1701,1703,1705],{"class":132,"line":282},[130,1702,414],{"class":202},[130,1704,614],{"class":147},[130,1706,268],{"class":202},[130,1708,1709,1711,1714,1717,1720,1723,1726],{"class":132,"line":288},[130,1710,622],{"class":202},[130,1712,1713],{"class":147},"`错误：${",[130,1715,1716],{"class":202},"error",[130,1718,1719],{"class":147},".",[130,1721,1722],{"class":202},"message",[130,1724,1725],{"class":147},"}`",[130,1727,268],{"class":202},[130,1729,1730],{"class":132,"line":293},[130,1731,483],{"class":202},[130,1733,1734],{"class":132,"line":299},[130,1735,644],{"class":202},[130,1737,1738,1741,1744],{"class":132,"line":305},[130,1739,1740],{"class":202},"      isError: ",[130,1742,1743],{"class":238},"true",[130,1745,268],{"class":202},[130,1747,1748],{"class":132,"line":311},[130,1749,650],{"class":202},[130,1751,1752],{"class":132,"line":316},[130,1753,656],{"class":202},[130,1755,1756],{"class":132,"line":322},[130,1757,507],{"class":202},[29,1759,1760],{"id":1760},"资源提供",[50,1762,1763],{"id":1763},"列出资源",[120,1765,1767],{"className":189,"code":1766,"language":191,"meta":125,"style":125},"server.setRequestHandler(\"resources\u002Flist\", async () => {\n  return {\n    resources: [\n      {\n        uri: \"file:\u002F\u002F\u002Fworkspace\u002FREADME.md\",\n        name: \"项目说明\",\n        mimeType: \"text\u002Fmarkdown\",\n      },\n      {\n        uri: \"db:\u002F\u002Fusers\u002F123\",\n        name: \"用户数据\",\n        mimeType: \"application\u002Fjson\",\n      },\n    ],\n  };\n});\n",[127,1768,1769,1790,1796,1801,1805,1815,1824,1834,1838,1842,1851,1860,1868,1872,1876,1880],{"__ignoreMap":125},[130,1770,1771,1773,1775,1777,1780,1782,1784,1786,1788],{"class":132,"line":133},[130,1772,336],{"class":202},[130,1774,339],{"class":143},[130,1776,342],{"class":202},[130,1778,1779],{"class":147},"\"resources\u002Flist\"",[130,1781,348],{"class":202},[130,1783,351],{"class":198},[130,1785,354],{"class":202},[130,1787,357],{"class":198},[130,1789,360],{"class":202},[130,1791,1792,1794],{"class":132,"line":140},[130,1793,366],{"class":198},[130,1795,360],{"class":202},[130,1797,1798],{"class":132,"line":154},[130,1799,1800],{"class":202},"    resources: [\n",[130,1802,1803],{"class":132,"line":161},[130,1804,380],{"class":202},[130,1806,1807,1810,1813],{"class":132,"line":167},[130,1808,1809],{"class":202},"        uri: ",[130,1811,1812],{"class":147},"\"file:\u002F\u002F\u002Fworkspace\u002FREADME.md\"",[130,1814,268],{"class":202},[130,1816,1817,1819,1822],{"class":132,"line":259},[130,1818,386],{"class":202},[130,1820,1821],{"class":147},"\"项目说明\"",[130,1823,268],{"class":202},[130,1825,1826,1829,1832],{"class":132,"line":271},[130,1827,1828],{"class":202},"        mimeType: ",[130,1830,1831],{"class":147},"\"text\u002Fmarkdown\"",[130,1833,268],{"class":202},[130,1835,1836],{"class":132,"line":282},[130,1837,489],{"class":202},[130,1839,1840],{"class":132,"line":288},[130,1841,380],{"class":202},[130,1843,1844,1846,1849],{"class":132,"line":293},[130,1845,1809],{"class":202},[130,1847,1848],{"class":147},"\"db:\u002F\u002Fusers\u002F123\"",[130,1850,268],{"class":202},[130,1852,1853,1855,1858],{"class":132,"line":299},[130,1854,386],{"class":202},[130,1856,1857],{"class":147},"\"用户数据\"",[130,1859,268],{"class":202},[130,1861,1862,1864,1866],{"class":132,"line":305},[130,1863,1828],{"class":202},[130,1865,1607],{"class":147},[130,1867,268],{"class":202},[130,1869,1870],{"class":132,"line":311},[130,1871,489],{"class":202},[130,1873,1874],{"class":132,"line":316},[130,1875,495],{"class":202},[130,1877,1878],{"class":132,"line":322},[130,1879,501],{"class":202},[130,1881,1882],{"class":132,"line":327},[130,1883,507],{"class":202},[50,1885,1886],{"id":1886},"读取资源",[120,1888,1890],{"className":189,"code":1889,"language":191,"meta":125,"style":125},"server.setRequestHandler(\"resources\u002Fread\", async (request) => {\n  const uri = request.params.uri;\n\n  if (uri.startsWith(\"file:\u002F\u002F\")) {\n    const path = uri.slice(7);\n    const content = await fs.readFile(path, \"utf-8\");\n    return {\n      contents: [\n        {\n          uri,\n          mimeType: \"text\u002Fplain\",\n          text: content,\n        },\n      ],\n    };\n  }\n\n  throw new Error(\"Unsupported URI scheme\");\n});\n",[127,1891,1892,1917,1930,1934,1952,1974,2000,2006,2011,2015,2020,2029,2034,2038,2042,2046,2050,2054,2069],{"__ignoreMap":125},[130,1893,1894,1896,1898,1900,1903,1905,1907,1909,1911,1913,1915],{"class":132,"line":133},[130,1895,336],{"class":202},[130,1897,339],{"class":143},[130,1899,342],{"class":202},[130,1901,1902],{"class":147},"\"resources\u002Fread\"",[130,1904,348],{"class":202},[130,1906,351],{"class":198},[130,1908,537],{"class":202},[130,1910,541],{"class":540},[130,1912,544],{"class":202},[130,1914,357],{"class":198},[130,1916,360],{"class":202},[130,1918,1919,1922,1925,1927],{"class":132,"line":140},[130,1920,1921],{"class":198},"  const",[130,1923,1924],{"class":238}," uri",[130,1926,242],{"class":198},[130,1928,1929],{"class":202}," request.params.uri;\n",[130,1931,1932],{"class":132,"line":154},[130,1933,158],{"emptyLinePlaceholder":157},[130,1935,1936,1938,1941,1944,1946,1949],{"class":132,"line":161},[130,1937,554],{"class":198},[130,1939,1940],{"class":202}," (uri.",[130,1942,1943],{"class":143},"startsWith",[130,1945,342],{"class":202},[130,1947,1948],{"class":147},"\"file:\u002F\u002F\"",[130,1950,1951],{"class":202},")) {\n",[130,1953,1954,1956,1959,1961,1964,1967,1969,1972],{"class":132,"line":167},[130,1955,572],{"class":198},[130,1957,1958],{"class":238}," path",[130,1960,242],{"class":198},[130,1962,1963],{"class":202}," uri.",[130,1965,1966],{"class":143},"slice",[130,1968,342],{"class":202},[130,1970,1971],{"class":238},"7",[130,1973,319],{"class":202},[130,1975,1976,1978,1981,1983,1986,1989,1992,1995,1998],{"class":132,"line":259},[130,1977,572],{"class":198},[130,1979,1980],{"class":238}," content",[130,1982,242],{"class":198},[130,1984,1985],{"class":198}," await",[130,1987,1988],{"class":202}," fs.",[130,1990,1991],{"class":143},"readFile",[130,1993,1994],{"class":202},"(path, ",[130,1996,1997],{"class":147},"\"utf-8\"",[130,1999,319],{"class":202},[130,2001,2002,2004],{"class":132,"line":271},[130,2003,592],{"class":198},[130,2005,360],{"class":202},[130,2007,2008],{"class":132,"line":282},[130,2009,2010],{"class":202},"      contents: [\n",[130,2012,2013],{"class":132,"line":288},[130,2014,606],{"class":202},[130,2016,2017],{"class":132,"line":293},[130,2018,2019],{"class":202},"          uri,\n",[130,2021,2022,2024,2027],{"class":132,"line":299},[130,2023,1568],{"class":202},[130,2025,2026],{"class":147},"\"text\u002Fplain\"",[130,2028,268],{"class":202},[130,2030,2031],{"class":132,"line":305},[130,2032,2033],{"class":202},"          text: content,\n",[130,2035,2036],{"class":132,"line":311},[130,2037,483],{"class":202},[130,2039,2040],{"class":132,"line":316},[130,2041,644],{"class":202},[130,2043,2044],{"class":132,"line":322},[130,2045,650],{"class":202},[130,2047,2048],{"class":132,"line":327},[130,2049,656],{"class":202},[130,2051,2052],{"class":132,"line":333},[130,2053,158],{"emptyLinePlaceholder":157},[130,2055,2056,2058,2060,2062,2064,2067],{"class":132,"line":363},[130,2057,662],{"class":198},[130,2059,245],{"class":198},[130,2061,667],{"class":143},[130,2063,342],{"class":202},[130,2065,2066],{"class":147},"\"Unsupported URI scheme\"",[130,2068,319],{"class":202},[130,2070,2071],{"class":132,"line":371},[130,2072,507],{"class":202},[29,2074,2075],{"id":2075},"提示词模板",[50,2077,2078],{"id":2078},"定义模板",[120,2080,2082],{"className":189,"code":2081,"language":191,"meta":125,"style":125},"server.setRequestHandler(\"prompts\u002Flist\", async () => {\n  return {\n    prompts: [\n      {\n        name: \"code_review\",\n        description: \"代码审查提示词\",\n        arguments: [\n          {\n            name: \"language\",\n            description: \"编程语言\",\n            required: true,\n          },\n        ],\n      },\n    ],\n  };\n});\n",[127,2083,2084,2105,2111,2116,2120,2129,2138,2143,2148,2158,2168,2177,2181,2186,2190,2194,2198],{"__ignoreMap":125},[130,2085,2086,2088,2090,2092,2095,2097,2099,2101,2103],{"class":132,"line":133},[130,2087,336],{"class":202},[130,2089,339],{"class":143},[130,2091,342],{"class":202},[130,2093,2094],{"class":147},"\"prompts\u002Flist\"",[130,2096,348],{"class":202},[130,2098,351],{"class":198},[130,2100,354],{"class":202},[130,2102,357],{"class":198},[130,2104,360],{"class":202},[130,2106,2107,2109],{"class":132,"line":140},[130,2108,366],{"class":198},[130,2110,360],{"class":202},[130,2112,2113],{"class":132,"line":154},[130,2114,2115],{"class":202},"    prompts: [\n",[130,2117,2118],{"class":132,"line":161},[130,2119,380],{"class":202},[130,2121,2122,2124,2127],{"class":132,"line":167},[130,2123,386],{"class":202},[130,2125,2126],{"class":147},"\"code_review\"",[130,2128,268],{"class":202},[130,2130,2131,2133,2136],{"class":132,"line":259},[130,2132,397],{"class":202},[130,2134,2135],{"class":147},"\"代码审查提示词\"",[130,2137,268],{"class":202},[130,2139,2140],{"class":132,"line":271},[130,2141,2142],{"class":202},"        arguments: [\n",[130,2144,2145],{"class":132,"line":282},[130,2146,2147],{"class":202},"          {\n",[130,2149,2150,2153,2156],{"class":132,"line":288},[130,2151,2152],{"class":202},"            name: ",[130,2154,2155],{"class":147},"\"language\"",[130,2157,268],{"class":202},[130,2159,2160,2163,2166],{"class":132,"line":293},[130,2161,2162],{"class":202},"            description: ",[130,2164,2165],{"class":147},"\"编程语言\"",[130,2167,268],{"class":202},[130,2169,2170,2173,2175],{"class":132,"line":299},[130,2171,2172],{"class":202},"            required: ",[130,2174,1743],{"class":238},[130,2176,268],{"class":202},[130,2178,2179],{"class":132,"line":305},[130,2180,465],{"class":202},[130,2182,2183],{"class":132,"line":311},[130,2184,2185],{"class":202},"        ],\n",[130,2187,2188],{"class":132,"line":316},[130,2189,489],{"class":202},[130,2191,2192],{"class":132,"line":322},[130,2193,495],{"class":202},[130,2195,2196],{"class":132,"line":327},[130,2197,501],{"class":202},[130,2199,2200],{"class":132,"line":333},[130,2201,507],{"class":202},[50,2203,2204],{"id":2204},"生成提示词",[120,2206,2208],{"className":189,"code":2207,"language":191,"meta":125,"style":125},"server.setRequestHandler(\"prompts\u002Fget\", async (request) => {\n  if (request.params.name === \"code_review\") {\n    const language = request.params.arguments.language;\n    return {\n      messages: [\n        {\n          role: \"user\",\n          content: {\n            type: \"text\",\n            text: `请审查以下 ${language} 代码，关注：\n1. 代码质量和可读性\n2. 潜在的 bug 和安全问题\n3. 性能优化建议`,\n          },\n        },\n      ],\n    };\n  }\n});\n",[127,2209,2210,2235,2248,2260,2266,2271,2275,2285,2290,2299,2313,2318,2323,2330,2334,2338,2342,2346,2350],{"__ignoreMap":125},[130,2211,2212,2214,2216,2218,2221,2223,2225,2227,2229,2231,2233],{"class":132,"line":133},[130,2213,336],{"class":202},[130,2215,339],{"class":143},[130,2217,342],{"class":202},[130,2219,2220],{"class":147},"\"prompts\u002Fget\"",[130,2222,348],{"class":202},[130,2224,351],{"class":198},[130,2226,537],{"class":202},[130,2228,541],{"class":540},[130,2230,544],{"class":202},[130,2232,357],{"class":198},[130,2234,360],{"class":202},[130,2236,2237,2239,2241,2243,2246],{"class":132,"line":140},[130,2238,554],{"class":198},[130,2240,557],{"class":202},[130,2242,560],{"class":198},[130,2244,2245],{"class":147}," \"code_review\"",[130,2247,566],{"class":202},[130,2249,2250,2252,2255,2257],{"class":132,"line":154},[130,2251,572],{"class":198},[130,2253,2254],{"class":238}," language",[130,2256,242],{"class":198},[130,2258,2259],{"class":202}," request.params.arguments.language;\n",[130,2261,2262,2264],{"class":132,"line":161},[130,2263,592],{"class":198},[130,2265,360],{"class":202},[130,2267,2268],{"class":132,"line":167},[130,2269,2270],{"class":202},"      messages: [\n",[130,2272,2273],{"class":132,"line":259},[130,2274,606],{"class":202},[130,2276,2277,2280,2283],{"class":132,"line":271},[130,2278,2279],{"class":202},"          role: ",[130,2281,2282],{"class":147},"\"user\"",[130,2284,268],{"class":202},[130,2286,2287],{"class":132,"line":282},[130,2288,2289],{"class":202},"          content: {\n",[130,2291,2292,2295,2297],{"class":132,"line":288},[130,2293,2294],{"class":202},"            type: ",[130,2296,614],{"class":147},[130,2298,268],{"class":202},[130,2300,2301,2304,2307,2310],{"class":132,"line":293},[130,2302,2303],{"class":202},"            text: ",[130,2305,2306],{"class":147},"`请审查以下 ${",[130,2308,2309],{"class":202},"language",[130,2311,2312],{"class":147},"} 代码，关注：\n",[130,2314,2315],{"class":132,"line":299},[130,2316,2317],{"class":147},"1. 代码质量和可读性\n",[130,2319,2320],{"class":132,"line":305},[130,2321,2322],{"class":147},"2. 潜在的 bug 和安全问题\n",[130,2324,2325,2328],{"class":132,"line":311},[130,2326,2327],{"class":147},"3. 性能优化建议`",[130,2329,268],{"class":202},[130,2331,2332],{"class":132,"line":316},[130,2333,465],{"class":202},[130,2335,2336],{"class":132,"line":322},[130,2337,483],{"class":202},[130,2339,2340],{"class":132,"line":327},[130,2341,644],{"class":202},[130,2343,2344],{"class":132,"line":333},[130,2345,650],{"class":202},[130,2347,2348],{"class":132,"line":363},[130,2349,656],{"class":202},[130,2351,2352],{"class":132,"line":371},[130,2353,507],{"class":202},[29,2355,2356],{"id":2356},"高级特性",[50,2358,2359],{"id":2359},"流式响应",[120,2361,2363],{"className":189,"code":2362,"language":191,"meta":125,"style":125},"server.setRequestHandler(\"tools\u002Fcall\", async (request) => {\n  if (request.params.name === \"generate_report\") {\n    \u002F\u002F 返回流式内容\n    return {\n      content: [\n        {\n          type: \"text\",\n          text: \"正在生成报告...\",\n        },\n      ],\n      _meta: {\n        progressToken: \"report-123\",\n      },\n    };\n  }\n});\n\n\u002F\u002F 发送进度更新\nserver.notification({\n  method: \"notifications\u002Fprogress\",\n  params: {\n    progressToken: \"report-123\",\n    progress: 50,\n    total: 100,\n  },\n});\n",[127,2364,2365,2389,2402,2407,2413,2417,2421,2429,2438,2442,2446,2451,2461,2465,2469,2473,2477,2481,2486,2496,2506,2511,2520,2530,2540,2544],{"__ignoreMap":125},[130,2366,2367,2369,2371,2373,2375,2377,2379,2381,2383,2385,2387],{"class":132,"line":133},[130,2368,336],{"class":202},[130,2370,339],{"class":143},[130,2372,342],{"class":202},[130,2374,530],{"class":147},[130,2376,348],{"class":202},[130,2378,351],{"class":198},[130,2380,537],{"class":202},[130,2382,541],{"class":540},[130,2384,544],{"class":202},[130,2386,357],{"class":198},[130,2388,360],{"class":202},[130,2390,2391,2393,2395,2397,2400],{"class":132,"line":140},[130,2392,554],{"class":198},[130,2394,557],{"class":202},[130,2396,560],{"class":198},[130,2398,2399],{"class":147}," \"generate_report\"",[130,2401,566],{"class":202},[130,2403,2404],{"class":132,"line":154},[130,2405,2406],{"class":136},"    \u002F\u002F 返回流式内容\n",[130,2408,2409,2411],{"class":132,"line":161},[130,2410,592],{"class":198},[130,2412,360],{"class":202},[130,2414,2415],{"class":132,"line":167},[130,2416,600],{"class":202},[130,2418,2419],{"class":132,"line":259},[130,2420,606],{"class":202},[130,2422,2423,2425,2427],{"class":132,"line":271},[130,2424,414],{"class":202},[130,2426,614],{"class":147},[130,2428,268],{"class":202},[130,2430,2431,2433,2436],{"class":132,"line":282},[130,2432,622],{"class":202},[130,2434,2435],{"class":147},"\"正在生成报告...\"",[130,2437,268],{"class":202},[130,2439,2440],{"class":132,"line":288},[130,2441,483],{"class":202},[130,2443,2444],{"class":132,"line":293},[130,2445,644],{"class":202},[130,2447,2448],{"class":132,"line":299},[130,2449,2450],{"class":202},"      _meta: {\n",[130,2452,2453,2456,2459],{"class":132,"line":305},[130,2454,2455],{"class":202},"        progressToken: ",[130,2457,2458],{"class":147},"\"report-123\"",[130,2460,268],{"class":202},[130,2462,2463],{"class":132,"line":311},[130,2464,489],{"class":202},[130,2466,2467],{"class":132,"line":316},[130,2468,650],{"class":202},[130,2470,2471],{"class":132,"line":322},[130,2472,656],{"class":202},[130,2474,2475],{"class":132,"line":327},[130,2476,507],{"class":202},[130,2478,2479],{"class":132,"line":333},[130,2480,158],{"emptyLinePlaceholder":157},[130,2482,2483],{"class":132,"line":363},[130,2484,2485],{"class":136},"\u002F\u002F 发送进度更新\n",[130,2487,2488,2490,2493],{"class":132,"line":371},[130,2489,336],{"class":202},[130,2491,2492],{"class":143},"notification",[130,2494,2495],{"class":202},"({\n",[130,2497,2498,2501,2504],{"class":132,"line":377},[130,2499,2500],{"class":202},"  method: ",[130,2502,2503],{"class":147},"\"notifications\u002Fprogress\"",[130,2505,268],{"class":202},[130,2507,2508],{"class":132,"line":383},[130,2509,2510],{"class":202},"  params: {\n",[130,2512,2513,2516,2518],{"class":132,"line":394},[130,2514,2515],{"class":202},"    progressToken: ",[130,2517,2458],{"class":147},[130,2519,268],{"class":202},[130,2521,2522,2525,2528],{"class":132,"line":405},[130,2523,2524],{"class":202},"    progress: ",[130,2526,2527],{"class":238},"50",[130,2529,268],{"class":202},[130,2531,2532,2535,2538],{"class":132,"line":411},[130,2533,2534],{"class":202},"    total: ",[130,2536,2537],{"class":238},"100",[130,2539,268],{"class":202},[130,2541,2542],{"class":132,"line":422},[130,2543,285],{"class":202},[130,2545,2546],{"class":132,"line":428},[130,2547,507],{"class":202},[50,2549,2550],{"id":2550},"订阅资源变化",[120,2552,2554],{"className":189,"code":2553,"language":191,"meta":125,"style":125},"server.setRequestHandler(\"resources\u002Fsubscribe\", async (request) => {\n  const uri = request.params.uri;\n\n  \u002F\u002F 监听文件变化\n  fs.watch(uri.slice(7), (eventType) => {\n    server.notification({\n      method: \"notifications\u002Fresources\u002Fupdated\",\n      params: { uri },\n    });\n  });\n\n  return {};\n});\n",[127,2555,2556,2581,2591,2595,2600,2629,2638,2648,2653,2658,2663,2667,2674],{"__ignoreMap":125},[130,2557,2558,2560,2562,2564,2567,2569,2571,2573,2575,2577,2579],{"class":132,"line":133},[130,2559,336],{"class":202},[130,2561,339],{"class":143},[130,2563,342],{"class":202},[130,2565,2566],{"class":147},"\"resources\u002Fsubscribe\"",[130,2568,348],{"class":202},[130,2570,351],{"class":198},[130,2572,537],{"class":202},[130,2574,541],{"class":540},[130,2576,544],{"class":202},[130,2578,357],{"class":198},[130,2580,360],{"class":202},[130,2582,2583,2585,2587,2589],{"class":132,"line":140},[130,2584,1921],{"class":198},[130,2586,1924],{"class":238},[130,2588,242],{"class":198},[130,2590,1929],{"class":202},[130,2592,2593],{"class":132,"line":154},[130,2594,158],{"emptyLinePlaceholder":157},[130,2596,2597],{"class":132,"line":161},[130,2598,2599],{"class":136},"  \u002F\u002F 监听文件变化\n",[130,2601,2602,2605,2608,2611,2613,2615,2617,2620,2623,2625,2627],{"class":132,"line":167},[130,2603,2604],{"class":202},"  fs.",[130,2606,2607],{"class":143},"watch",[130,2609,2610],{"class":202},"(uri.",[130,2612,1966],{"class":143},[130,2614,342],{"class":202},[130,2616,1971],{"class":238},[130,2618,2619],{"class":202},"), (",[130,2621,2622],{"class":540},"eventType",[130,2624,544],{"class":202},[130,2626,357],{"class":198},[130,2628,360],{"class":202},[130,2630,2631,2634,2636],{"class":132,"line":259},[130,2632,2633],{"class":202},"    server.",[130,2635,2492],{"class":143},[130,2637,2495],{"class":202},[130,2639,2640,2643,2646],{"class":132,"line":271},[130,2641,2642],{"class":202},"      method: ",[130,2644,2645],{"class":147},"\"notifications\u002Fresources\u002Fupdated\"",[130,2647,268],{"class":202},[130,2649,2650],{"class":132,"line":282},[130,2651,2652],{"class":202},"      params: { uri },\n",[130,2654,2655],{"class":132,"line":288},[130,2656,2657],{"class":202},"    });\n",[130,2659,2660],{"class":132,"line":293},[130,2661,2662],{"class":202},"  });\n",[130,2664,2665],{"class":132,"line":299},[130,2666,158],{"emptyLinePlaceholder":157},[130,2668,2669,2671],{"class":132,"line":305},[130,2670,366],{"class":198},[130,2672,2673],{"class":202}," {};\n",[130,2675,2676],{"class":132,"line":311},[130,2677,507],{"class":202},[50,2679,2680],{"id":2680},"认证和授权",[120,2682,2684],{"className":189,"code":2683,"language":191,"meta":125,"style":125},"server.setRequestHandler(\"initialize\", async (request) => {\n  const apiKey = request.params.clientInfo?.apiKey;\n\n  if (!isValidApiKey(apiKey)) {\n    throw new Error(\"Invalid API key\");\n  }\n\n  return {\n    protocolVersion: \"2024-11-05\",\n    capabilities: {\n      tools: {},\n    },\n    serverInfo: {\n      name: \"secure-server\",\n      version: \"1.0.0\",\n    },\n  };\n});\n",[127,2685,2686,2711,2723,2727,2742,2758,2762,2766,2772,2782,2786,2790,2794,2799,2809,2818,2822,2826],{"__ignoreMap":125},[130,2687,2688,2690,2692,2694,2697,2699,2701,2703,2705,2707,2709],{"class":132,"line":133},[130,2689,336],{"class":202},[130,2691,339],{"class":143},[130,2693,342],{"class":202},[130,2695,2696],{"class":147},"\"initialize\"",[130,2698,348],{"class":202},[130,2700,351],{"class":198},[130,2702,537],{"class":202},[130,2704,541],{"class":540},[130,2706,544],{"class":202},[130,2708,357],{"class":198},[130,2710,360],{"class":202},[130,2712,2713,2715,2718,2720],{"class":132,"line":140},[130,2714,1921],{"class":198},[130,2716,2717],{"class":238}," apiKey",[130,2719,242],{"class":198},[130,2721,2722],{"class":202}," request.params.clientInfo?.apiKey;\n",[130,2724,2725],{"class":132,"line":154},[130,2726,158],{"emptyLinePlaceholder":157},[130,2728,2729,2731,2733,2736,2739],{"class":132,"line":161},[130,2730,554],{"class":198},[130,2732,537],{"class":202},[130,2734,2735],{"class":198},"!",[130,2737,2738],{"class":143},"isValidApiKey",[130,2740,2741],{"class":202},"(apiKey)) {\n",[130,2743,2744,2747,2749,2751,2753,2756],{"class":132,"line":167},[130,2745,2746],{"class":198},"    throw",[130,2748,245],{"class":198},[130,2750,667],{"class":143},[130,2752,342],{"class":202},[130,2754,2755],{"class":147},"\"Invalid API key\"",[130,2757,319],{"class":202},[130,2759,2760],{"class":132,"line":259},[130,2761,656],{"class":202},[130,2763,2764],{"class":132,"line":271},[130,2765,158],{"emptyLinePlaceholder":157},[130,2767,2768,2770],{"class":132,"line":282},[130,2769,366],{"class":198},[130,2771,360],{"class":202},[130,2773,2774,2777,2780],{"class":132,"line":288},[130,2775,2776],{"class":202},"    protocolVersion: ",[130,2778,2779],{"class":147},"\"2024-11-05\"",[130,2781,268],{"class":202},[130,2783,2784],{"class":132,"line":293},[130,2785,296],{"class":202},[130,2787,2788],{"class":132,"line":299},[130,2789,302],{"class":202},[130,2791,2792],{"class":132,"line":305},[130,2793,308],{"class":202},[130,2795,2796],{"class":132,"line":311},[130,2797,2798],{"class":202},"    serverInfo: {\n",[130,2800,2801,2804,2807],{"class":132,"line":316},[130,2802,2803],{"class":202},"      name: ",[130,2805,2806],{"class":147},"\"secure-server\"",[130,2808,268],{"class":202},[130,2810,2811,2814,2816],{"class":132,"line":322},[130,2812,2813],{"class":202},"      version: ",[130,2815,277],{"class":147},[130,2817,268],{"class":202},[130,2819,2820],{"class":132,"line":327},[130,2821,308],{"class":202},[130,2823,2824],{"class":132,"line":333},[130,2825,501],{"class":202},[130,2827,2828],{"class":132,"line":363},[130,2829,507],{"class":202},[29,2831,2832],{"id":2832},"实战案例",[50,2834,2836],{"id":2835},"案例-1github-api-服务器","案例 1：GitHub API 服务器",[120,2838,2840],{"className":189,"code":2839,"language":191,"meta":125,"style":125},"import { Octokit } from \"@octokit\u002Frest\";\n\nconst octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });\n\nserver.setRequestHandler(\"tools\u002Flist\", async () => {\n  return {\n    tools: [\n      {\n        name: \"create_issue\",\n        description: \"创建 GitHub Issue\",\n        inputSchema: {\n          type: \"object\",\n          properties: {\n            owner: { type: \"string\" },\n            repo: { type: \"string\" },\n            title: { type: \"string\" },\n            body: { type: \"string\" },\n          },\n          required: [\"owner\", \"repo\", \"title\"],\n        },\n      },\n      {\n        name: \"list_prs\",\n        description: \"列出 Pull Requests\",\n        inputSchema: {\n          type: \"object\",\n          properties: {\n            owner: { type: \"string\" },\n            repo: { type: \"string\" },\n            state: {\n              type: \"string\",\n              enum: [\"open\", \"closed\", \"all\"],\n              default: \"open\",\n            },\n          },\n          required: [\"owner\", \"repo\"],\n        },\n      },\n    ],\n  };\n});\n\nserver.setRequestHandler(\"tools\u002Fcall\", async (request) => {\n  const { name, arguments: args } = request.params;\n\n  if (name === \"create_issue\") {\n    const result = await octokit.issues.create({\n      owner: args.owner,\n      repo: args.repo,\n      title: args.title,\n      body: args.body,\n    });\n\n    return {\n      content: [\n        {\n          type: \"text\",\n          text: `Issue 创建成功：${result.data.html_url}`,\n        },\n      ],\n    };\n  }\n\n  if (name === \"list_prs\") {\n    const result = await octokit.pulls.list({\n      owner: args.owner,\n      repo: args.repo,\n      state: args.state,\n    });\n\n    const prs = result.data\n      .map((pr) => `#${pr.number}: ${pr.title} (${pr.state})`)\n      .join(\"\\n\");\n\n    return {\n      content: [\n        {\n          type: \"text\",\n          text: prs,\n        },\n      ],\n    };\n  }\n});\n",[127,2841,2842,2856,2860,2883,2887,2907,2913,2917,2921,2930,2939,2943,2951,2955,2965,2974,2983,2992,2996,3015,3019,3023,3027,3036,3045,3049,3057,3061,3069,3077,3082,3090,3110,3119,3123,3127,3139,3143,3147,3151,3155,3159,3163,3187,3214,3218,3232,3251,3256,3261,3266,3271,3275,3279,3285,3289,3293,3301,3326,3331,3336,3341,3346,3351,3365,3384,3389,3394,3400,3405,3410,3423,3477,3496,3501,3508,3513,3518,3527,3533,3538,3543,3548,3553],{"__ignoreMap":125},[130,2843,2844,2846,2849,2851,2854],{"class":132,"line":133},[130,2845,199],{"class":198},[130,2847,2848],{"class":202}," { Octokit } ",[130,2850,206],{"class":198},[130,2852,2853],{"class":147}," \"@octokit\u002Frest\"",[130,2855,212],{"class":202},[130,2857,2858],{"class":132,"line":140},[130,2859,158],{"emptyLinePlaceholder":157},[130,2861,2862,2864,2867,2869,2871,2874,2877,2880],{"class":132,"line":154},[130,2863,235],{"class":198},[130,2865,2866],{"class":238}," octokit",[130,2868,242],{"class":198},[130,2870,245],{"class":198},[130,2872,2873],{"class":143}," Octokit",[130,2875,2876],{"class":202},"({ auth: process.env.",[130,2878,2879],{"class":238},"GITHUB_TOKEN",[130,2881,2882],{"class":202}," });\n",[130,2884,2885],{"class":132,"line":161},[130,2886,158],{"emptyLinePlaceholder":157},[130,2888,2889,2891,2893,2895,2897,2899,2901,2903,2905],{"class":132,"line":167},[130,2890,336],{"class":202},[130,2892,339],{"class":143},[130,2894,342],{"class":202},[130,2896,345],{"class":147},[130,2898,348],{"class":202},[130,2900,351],{"class":198},[130,2902,354],{"class":202},[130,2904,357],{"class":198},[130,2906,360],{"class":202},[130,2908,2909,2911],{"class":132,"line":259},[130,2910,366],{"class":198},[130,2912,360],{"class":202},[130,2914,2915],{"class":132,"line":271},[130,2916,374],{"class":202},[130,2918,2919],{"class":132,"line":282},[130,2920,380],{"class":202},[130,2922,2923,2925,2928],{"class":132,"line":288},[130,2924,386],{"class":202},[130,2926,2927],{"class":147},"\"create_issue\"",[130,2929,268],{"class":202},[130,2931,2932,2934,2937],{"class":132,"line":293},[130,2933,397],{"class":202},[130,2935,2936],{"class":147},"\"创建 GitHub Issue\"",[130,2938,268],{"class":202},[130,2940,2941],{"class":132,"line":299},[130,2942,408],{"class":202},[130,2944,2945,2947,2949],{"class":132,"line":305},[130,2946,414],{"class":202},[130,2948,417],{"class":147},[130,2950,268],{"class":202},[130,2952,2953],{"class":132,"line":311},[130,2954,425],{"class":202},[130,2956,2957,2960,2962],{"class":132,"line":316},[130,2958,2959],{"class":202},"            owner: { type: ",[130,2961,440],{"class":147},[130,2963,2964],{"class":202}," },\n",[130,2966,2967,2970,2972],{"class":132,"line":322},[130,2968,2969],{"class":202},"            repo: { type: ",[130,2971,440],{"class":147},[130,2973,2964],{"class":202},[130,2975,2976,2979,2981],{"class":132,"line":327},[130,2977,2978],{"class":202},"            title: { type: ",[130,2980,440],{"class":147},[130,2982,2964],{"class":202},[130,2984,2985,2988,2990],{"class":132,"line":333},[130,2986,2987],{"class":202},"            body: { type: ",[130,2989,440],{"class":147},[130,2991,2964],{"class":202},[130,2993,2994],{"class":132,"line":363},[130,2995,465],{"class":202},[130,2997,2998,3000,3003,3005,3008,3010,3013],{"class":132,"line":371},[130,2999,471],{"class":202},[130,3001,3002],{"class":147},"\"owner\"",[130,3004,348],{"class":202},[130,3006,3007],{"class":147},"\"repo\"",[130,3009,348],{"class":202},[130,3011,3012],{"class":147},"\"title\"",[130,3014,477],{"class":202},[130,3016,3017],{"class":132,"line":377},[130,3018,483],{"class":202},[130,3020,3021],{"class":132,"line":383},[130,3022,489],{"class":202},[130,3024,3025],{"class":132,"line":394},[130,3026,380],{"class":202},[130,3028,3029,3031,3034],{"class":132,"line":405},[130,3030,386],{"class":202},[130,3032,3033],{"class":147},"\"list_prs\"",[130,3035,268],{"class":202},[130,3037,3038,3040,3043],{"class":132,"line":411},[130,3039,397],{"class":202},[130,3041,3042],{"class":147},"\"列出 Pull Requests\"",[130,3044,268],{"class":202},[130,3046,3047],{"class":132,"line":422},[130,3048,408],{"class":202},[130,3050,3051,3053,3055],{"class":132,"line":428},[130,3052,414],{"class":202},[130,3054,417],{"class":147},[130,3056,268],{"class":202},[130,3058,3059],{"class":132,"line":434},[130,3060,425],{"class":202},[130,3062,3063,3065,3067],{"class":132,"line":445},[130,3064,2959],{"class":202},[130,3066,440],{"class":147},[130,3068,2964],{"class":202},[130,3070,3071,3073,3075],{"class":132,"line":456},[130,3072,2969],{"class":202},[130,3074,440],{"class":147},[130,3076,2964],{"class":202},[130,3078,3079],{"class":132,"line":462},[130,3080,3081],{"class":202},"            state: {\n",[130,3083,3084,3086,3088],{"class":132,"line":468},[130,3085,437],{"class":202},[130,3087,440],{"class":147},[130,3089,268],{"class":202},[130,3091,3092,3095,3098,3100,3103,3105,3108],{"class":132,"line":480},[130,3093,3094],{"class":202},"              enum: [",[130,3096,3097],{"class":147},"\"open\"",[130,3099,348],{"class":202},[130,3101,3102],{"class":147},"\"closed\"",[130,3104,348],{"class":202},[130,3106,3107],{"class":147},"\"all\"",[130,3109,477],{"class":202},[130,3111,3112,3115,3117],{"class":132,"line":486},[130,3113,3114],{"class":202},"              default: ",[130,3116,3097],{"class":147},[130,3118,268],{"class":202},[130,3120,3121],{"class":132,"line":492},[130,3122,459],{"class":202},[130,3124,3125],{"class":132,"line":498},[130,3126,465],{"class":202},[130,3128,3129,3131,3133,3135,3137],{"class":132,"line":504},[130,3130,471],{"class":202},[130,3132,3002],{"class":147},[130,3134,348],{"class":202},[130,3136,3007],{"class":147},[130,3138,477],{"class":202},[130,3140,3141],{"class":132,"line":510},[130,3142,483],{"class":202},[130,3144,3145],{"class":132,"line":515},[130,3146,489],{"class":202},[130,3148,3149],{"class":132,"line":521},[130,3150,495],{"class":202},[130,3152,3153],{"class":132,"line":551},[130,3154,501],{"class":202},[130,3156,3157],{"class":132,"line":569},[130,3158,507],{"class":202},[130,3160,3161],{"class":132,"line":583},[130,3162,158],{"emptyLinePlaceholder":157},[130,3164,3165,3167,3169,3171,3173,3175,3177,3179,3181,3183,3185],{"class":132,"line":589},[130,3166,336],{"class":202},[130,3168,339],{"class":143},[130,3170,342],{"class":202},[130,3172,530],{"class":147},[130,3174,348],{"class":202},[130,3176,351],{"class":198},[130,3178,537],{"class":202},[130,3180,541],{"class":540},[130,3182,544],{"class":202},[130,3184,357],{"class":198},[130,3186,360],{"class":202},[130,3188,3189,3191,3194,3196,3198,3201,3203,3206,3209,3211],{"class":132,"line":597},[130,3190,1921],{"class":198},[130,3192,3193],{"class":202}," { ",[130,3195,1097],{"class":238},[130,3197,348],{"class":202},[130,3199,3200],{"class":540},"arguments",[130,3202,872],{"class":202},[130,3204,3205],{"class":238},"args",[130,3207,3208],{"class":202}," } ",[130,3210,787],{"class":198},[130,3212,3213],{"class":202}," request.params;\n",[130,3215,3216],{"class":132,"line":603},[130,3217,158],{"emptyLinePlaceholder":157},[130,3219,3220,3222,3225,3227,3230],{"class":132,"line":609},[130,3221,554],{"class":198},[130,3223,3224],{"class":202}," (name ",[130,3226,560],{"class":198},[130,3228,3229],{"class":147}," \"create_issue\"",[130,3231,566],{"class":202},[130,3233,3234,3236,3239,3241,3243,3246,3249],{"class":132,"line":619},[130,3235,572],{"class":198},[130,3237,3238],{"class":238}," result",[130,3240,242],{"class":198},[130,3242,1985],{"class":198},[130,3244,3245],{"class":202}," octokit.issues.",[130,3247,3248],{"class":143},"create",[130,3250,2495],{"class":202},[130,3252,3253],{"class":132,"line":636},[130,3254,3255],{"class":202},"      owner: args.owner,\n",[130,3257,3258],{"class":132,"line":641},[130,3259,3260],{"class":202},"      repo: args.repo,\n",[130,3262,3263],{"class":132,"line":647},[130,3264,3265],{"class":202},"      title: args.title,\n",[130,3267,3268],{"class":132,"line":653},[130,3269,3270],{"class":202},"      body: args.body,\n",[130,3272,3273],{"class":132,"line":659},[130,3274,2657],{"class":202},[130,3276,3277],{"class":132,"line":677},[130,3278,158],{"emptyLinePlaceholder":157},[130,3280,3281,3283],{"class":132,"line":682},[130,3282,592],{"class":198},[130,3284,360],{"class":202},[130,3286,3287],{"class":132,"line":687},[130,3288,600],{"class":202},[130,3290,3291],{"class":132,"line":693},[130,3292,606],{"class":202},[130,3294,3295,3297,3299],{"class":132,"line":711},[130,3296,414],{"class":202},[130,3298,614],{"class":147},[130,3300,268],{"class":202},[130,3302,3304,3306,3309,3312,3314,3317,3319,3322,3324],{"class":132,"line":3303},58,[130,3305,622],{"class":202},[130,3307,3308],{"class":147},"`Issue 创建成功：${",[130,3310,3311],{"class":202},"result",[130,3313,1719],{"class":147},[130,3315,3316],{"class":202},"data",[130,3318,1719],{"class":147},[130,3320,3321],{"class":202},"html_url",[130,3323,1725],{"class":147},[130,3325,268],{"class":202},[130,3327,3329],{"class":132,"line":3328},59,[130,3330,483],{"class":202},[130,3332,3334],{"class":132,"line":3333},60,[130,3335,644],{"class":202},[130,3337,3339],{"class":132,"line":3338},61,[130,3340,650],{"class":202},[130,3342,3344],{"class":132,"line":3343},62,[130,3345,656],{"class":202},[130,3347,3349],{"class":132,"line":3348},63,[130,3350,158],{"emptyLinePlaceholder":157},[130,3352,3354,3356,3358,3360,3363],{"class":132,"line":3353},64,[130,3355,554],{"class":198},[130,3357,3224],{"class":202},[130,3359,560],{"class":198},[130,3361,3362],{"class":147}," \"list_prs\"",[130,3364,566],{"class":202},[130,3366,3368,3370,3372,3374,3376,3379,3382],{"class":132,"line":3367},65,[130,3369,572],{"class":198},[130,3371,3238],{"class":238},[130,3373,242],{"class":198},[130,3375,1985],{"class":198},[130,3377,3378],{"class":202}," octokit.pulls.",[130,3380,3381],{"class":143},"list",[130,3383,2495],{"class":202},[130,3385,3387],{"class":132,"line":3386},66,[130,3388,3255],{"class":202},[130,3390,3392],{"class":132,"line":3391},67,[130,3393,3260],{"class":202},[130,3395,3397],{"class":132,"line":3396},68,[130,3398,3399],{"class":202},"      state: args.state,\n",[130,3401,3403],{"class":132,"line":3402},69,[130,3404,2657],{"class":202},[130,3406,3408],{"class":132,"line":3407},70,[130,3409,158],{"emptyLinePlaceholder":157},[130,3411,3413,3415,3418,3420],{"class":132,"line":3412},71,[130,3414,572],{"class":198},[130,3416,3417],{"class":238}," prs",[130,3419,242],{"class":198},[130,3421,3422],{"class":202}," result.data\n",[130,3424,3426,3429,3432,3435,3438,3440,3442,3445,3447,3449,3452,3455,3457,3459,3462,3465,3467,3469,3472,3475],{"class":132,"line":3425},72,[130,3427,3428],{"class":202},"      .",[130,3430,3431],{"class":143},"map",[130,3433,3434],{"class":202},"((",[130,3436,3437],{"class":540},"pr",[130,3439,544],{"class":202},[130,3441,357],{"class":198},[130,3443,3444],{"class":147}," `#${",[130,3446,3437],{"class":202},[130,3448,1719],{"class":147},[130,3450,3451],{"class":202},"number",[130,3453,3454],{"class":147},"}: ${",[130,3456,3437],{"class":202},[130,3458,1719],{"class":147},[130,3460,3461],{"class":202},"title",[130,3463,3464],{"class":147},"} (${",[130,3466,3437],{"class":202},[130,3468,1719],{"class":147},[130,3470,3471],{"class":202},"state",[130,3473,3474],{"class":147},"})`",[130,3476,795],{"class":202},[130,3478,3480,3482,3485,3487,3489,3492,3494],{"class":132,"line":3479},73,[130,3481,3428],{"class":202},[130,3483,3484],{"class":143},"join",[130,3486,342],{"class":202},[130,3488,1056],{"class":147},[130,3490,3491],{"class":238},"\\n",[130,3493,1056],{"class":147},[130,3495,319],{"class":202},[130,3497,3499],{"class":132,"line":3498},74,[130,3500,158],{"emptyLinePlaceholder":157},[130,3502,3504,3506],{"class":132,"line":3503},75,[130,3505,592],{"class":198},[130,3507,360],{"class":202},[130,3509,3511],{"class":132,"line":3510},76,[130,3512,600],{"class":202},[130,3514,3516],{"class":132,"line":3515},77,[130,3517,606],{"class":202},[130,3519,3521,3523,3525],{"class":132,"line":3520},78,[130,3522,414],{"class":202},[130,3524,614],{"class":147},[130,3526,268],{"class":202},[130,3528,3530],{"class":132,"line":3529},79,[130,3531,3532],{"class":202},"          text: prs,\n",[130,3534,3536],{"class":132,"line":3535},80,[130,3537,483],{"class":202},[130,3539,3541],{"class":132,"line":3540},81,[130,3542,644],{"class":202},[130,3544,3546],{"class":132,"line":3545},82,[130,3547,650],{"class":202},[130,3549,3551],{"class":132,"line":3550},83,[130,3552,656],{"class":202},[130,3554,3556],{"class":132,"line":3555},84,[130,3557,507],{"class":202},[50,3559,3561],{"id":3560},"案例-2数据库查询服务器","案例 2：数据库查询服务器",[120,3563,3565],{"className":735,"code":3564,"language":737,"meta":125,"style":125},"import sqlite3\nfrom mcp.server import Server\nfrom mcp.types import Tool, TextContent\n\napp = Server(\"database-server\")\n\n@app.list_tools()\nasync def list_tools() -> list[Tool]:\n    return [\n        Tool(\n            name=\"query_db\",\n            description=\"执行 SQL 查询\",\n            inputSchema={\n                \"type\": \"object\",\n                \"properties\": {\n                    \"sql\": {\n                        \"type\": \"string\",\n                        \"description\": \"SQL 查询语句\"\n                    }\n                },\n                \"required\": [\"sql\"]\n            }\n        )\n    ]\n\n@app.call_tool()\nasync def call_tool(name: str, arguments: dict) -> list[TextContent]:\n    if name == \"query_db\":\n        conn = sqlite3.connect(\"data.db\")\n        cursor = conn.cursor()\n\n        try:\n            cursor.execute(arguments[\"sql\"])\n            results = cursor.fetchall()\n\n            # 格式化结果\n            output = \"\\n\".join(str(row) for row in results)\n\n            return [TextContent(type=\"text\", text=output)]\n        except Exception as e:\n            return [TextContent(type=\"text\", text=f\"错误：{e}\")]\n        finally:\n            conn.close()\n",[127,3566,3567,3574,3584,3594,3598,3611,3615,3621,3631,3637,3641,3652,3663,3671,3681,3687,3694,3704,3713,3717,3721,3732,3736,3740,3744,3748,3754,3772,3785,3800,3810,3814,3821,3831,3841,3845,3850,3884,3888,3913,3927,3962,3969],{"__ignoreMap":125},[130,3568,3569,3571],{"class":132,"line":133},[130,3570,199],{"class":198},[130,3572,3573],{"class":202}," sqlite3\n",[130,3575,3576,3578,3580,3582],{"class":132,"line":140},[130,3577,206],{"class":198},[130,3579,746],{"class":202},[130,3581,199],{"class":198},[130,3583,751],{"class":202},[130,3585,3586,3588,3590,3592],{"class":132,"line":154},[130,3587,206],{"class":198},[130,3589,770],{"class":202},[130,3591,199],{"class":198},[130,3593,775],{"class":202},[130,3595,3596],{"class":132,"line":161},[130,3597,158],{"emptyLinePlaceholder":157},[130,3599,3600,3602,3604,3606,3609],{"class":132,"line":167},[130,3601,784],{"class":202},[130,3603,787],{"class":198},[130,3605,790],{"class":202},[130,3607,3608],{"class":147},"\"database-server\"",[130,3610,795],{"class":202},[130,3612,3613],{"class":132,"line":259},[130,3614,158],{"emptyLinePlaceholder":157},[130,3616,3617,3619],{"class":132,"line":271},[130,3618,804],{"class":143},[130,3620,807],{"class":202},[130,3622,3623,3625,3627,3629],{"class":132,"line":282},[130,3624,351],{"class":198},[130,3626,814],{"class":198},[130,3628,817],{"class":143},[130,3630,820],{"class":202},[130,3632,3633,3635],{"class":132,"line":288},[130,3634,592],{"class":198},[130,3636,827],{"class":202},[130,3638,3639],{"class":132,"line":293},[130,3640,832],{"class":202},[130,3642,3643,3645,3647,3650],{"class":132,"line":299},[130,3644,837],{"class":540},[130,3646,787],{"class":198},[130,3648,3649],{"class":147},"\"query_db\"",[130,3651,268],{"class":202},[130,3653,3654,3656,3658,3661],{"class":132,"line":305},[130,3655,848],{"class":540},[130,3657,787],{"class":198},[130,3659,3660],{"class":147},"\"执行 SQL 查询\"",[130,3662,268],{"class":202},[130,3664,3665,3667,3669],{"class":132,"line":311},[130,3666,859],{"class":540},[130,3668,787],{"class":198},[130,3670,864],{"class":202},[130,3672,3673,3675,3677,3679],{"class":132,"line":316},[130,3674,869],{"class":147},[130,3676,872],{"class":202},[130,3678,417],{"class":147},[130,3680,268],{"class":202},[130,3682,3683,3685],{"class":132,"line":322},[130,3684,881],{"class":147},[130,3686,884],{"class":202},[130,3688,3689,3692],{"class":132,"line":327},[130,3690,3691],{"class":147},"                    \"sql\"",[130,3693,884],{"class":202},[130,3695,3696,3698,3700,3702],{"class":132,"line":333},[130,3697,896],{"class":147},[130,3699,872],{"class":202},[130,3701,440],{"class":147},[130,3703,268],{"class":202},[130,3705,3706,3708,3710],{"class":132,"line":363},[130,3707,907],{"class":147},[130,3709,872],{"class":202},[130,3711,3712],{"class":147},"\"SQL 查询语句\"\n",[130,3714,3715],{"class":132,"line":371},[130,3716,917],{"class":202},[130,3718,3719],{"class":132,"line":377},[130,3720,922],{"class":202},[130,3722,3723,3725,3727,3730],{"class":132,"line":383},[130,3724,927],{"class":147},[130,3726,930],{"class":202},[130,3728,3729],{"class":147},"\"sql\"",[130,3731,935],{"class":202},[130,3733,3734],{"class":132,"line":394},[130,3735,940],{"class":202},[130,3737,3738],{"class":132,"line":405},[130,3739,945],{"class":202},[130,3741,3742],{"class":132,"line":411},[130,3743,950],{"class":202},[130,3745,3746],{"class":132,"line":422},[130,3747,158],{"emptyLinePlaceholder":157},[130,3749,3750,3752],{"class":132,"line":428},[130,3751,959],{"class":143},[130,3753,807],{"class":202},[130,3755,3756,3758,3760,3762,3764,3766,3768,3770],{"class":132,"line":434},[130,3757,351],{"class":198},[130,3759,814],{"class":198},[130,3761,970],{"class":143},[130,3763,973],{"class":202},[130,3765,976],{"class":238},[130,3767,979],{"class":202},[130,3769,982],{"class":238},[130,3771,985],{"class":202},[130,3773,3774,3776,3778,3780,3783],{"class":132,"line":445},[130,3775,990],{"class":198},[130,3777,993],{"class":202},[130,3779,996],{"class":198},[130,3781,3782],{"class":147}," \"query_db\"",[130,3784,1001],{"class":202},[130,3786,3787,3790,3792,3795,3798],{"class":132,"line":456},[130,3788,3789],{"class":202},"        conn ",[130,3791,787],{"class":198},[130,3793,3794],{"class":202}," sqlite3.connect(",[130,3796,3797],{"class":147},"\"data.db\"",[130,3799,795],{"class":202},[130,3801,3802,3805,3807],{"class":132,"line":462},[130,3803,3804],{"class":202},"        cursor ",[130,3806,787],{"class":198},[130,3808,3809],{"class":202}," conn.cursor()\n",[130,3811,3812],{"class":132,"line":468},[130,3813,158],{"emptyLinePlaceholder":157},[130,3815,3816,3819],{"class":132,"line":480},[130,3817,3818],{"class":198},"        try",[130,3820,1001],{"class":202},[130,3822,3823,3826,3828],{"class":132,"line":486},[130,3824,3825],{"class":202},"            cursor.execute(arguments[",[130,3827,3729],{"class":147},[130,3829,3830],{"class":202},"])\n",[130,3832,3833,3836,3838],{"class":132,"line":492},[130,3834,3835],{"class":202},"            results ",[130,3837,787],{"class":198},[130,3839,3840],{"class":202}," cursor.fetchall()\n",[130,3842,3843],{"class":132,"line":498},[130,3844,158],{"emptyLinePlaceholder":157},[130,3846,3847],{"class":132,"line":504},[130,3848,3849],{"class":136},"            # 格式化结果\n",[130,3851,3852,3855,3857,3860,3862,3864,3867,3869,3872,3875,3878,3881],{"class":132,"line":510},[130,3853,3854],{"class":202},"            output ",[130,3856,787],{"class":198},[130,3858,3859],{"class":147}," \"",[130,3861,3491],{"class":238},[130,3863,1056],{"class":147},[130,3865,3866],{"class":202},".join(",[130,3868,976],{"class":238},[130,3870,3871],{"class":202},"(row) ",[130,3873,3874],{"class":198},"for",[130,3876,3877],{"class":202}," row ",[130,3879,3880],{"class":198},"in",[130,3882,3883],{"class":202}," results)\n",[130,3885,3886],{"class":132,"line":515},[130,3887,158],{"emptyLinePlaceholder":157},[130,3889,3890,3893,3896,3899,3901,3903,3905,3908,3910],{"class":132,"line":521},[130,3891,3892],{"class":198},"            return",[130,3894,3895],{"class":202}," [TextContent(",[130,3897,3898],{"class":540},"type",[130,3900,787],{"class":198},[130,3902,614],{"class":147},[130,3904,348],{"class":202},[130,3906,3907],{"class":540},"text",[130,3909,787],{"class":198},[130,3911,3912],{"class":202},"output)]\n",[130,3914,3915,3918,3921,3924],{"class":132,"line":551},[130,3916,3917],{"class":198},"        except",[130,3919,3920],{"class":238}," Exception",[130,3922,3923],{"class":198}," as",[130,3925,3926],{"class":202}," e:\n",[130,3928,3929,3931,3933,3935,3937,3939,3941,3943,3945,3947,3950,3952,3955,3957,3959],{"class":132,"line":569},[130,3930,3892],{"class":198},[130,3932,3895],{"class":202},[130,3934,3898],{"class":540},[130,3936,787],{"class":198},[130,3938,614],{"class":147},[130,3940,348],{"class":202},[130,3942,3907],{"class":540},[130,3944,787],{"class":198},[130,3946,1053],{"class":198},[130,3948,3949],{"class":147},"\"错误：",[130,3951,1059],{"class":238},[130,3953,3954],{"class":202},"e",[130,3956,1064],{"class":238},[130,3958,1056],{"class":147},[130,3960,3961],{"class":202},")]\n",[130,3963,3964,3967],{"class":132,"line":583},[130,3965,3966],{"class":198},"        finally",[130,3968,1001],{"class":202},[130,3970,3971],{"class":132,"line":589},[130,3972,3973],{"class":202},"            conn.close()\n",[50,3975,3977],{"id":3976},"案例-3文件系统服务器","案例 3：文件系统服务器",[120,3979,3981],{"className":189,"code":3980,"language":191,"meta":125,"style":125},"import fs from \"fs\u002Fpromises\";\nimport path from \"path\";\n\nconst WORKSPACE = process.env.WORKSPACE_DIR || process.cwd();\n\nserver.setRequestHandler(\"tools\u002Flist\", async () => {\n  return {\n    tools: [\n      {\n        name: \"read_file\",\n        description: \"读取文件内容\",\n        inputSchema: {\n          type: \"object\",\n          properties: {\n            path: { type: \"string\" },\n          },\n          required: [\"path\"],\n        },\n      },\n      {\n        name: \"write_file\",\n        description: \"写入文件\",\n        inputSchema: {\n          type: \"object\",\n          properties: {\n            path: { type: \"string\" },\n            content: { type: \"string\" },\n          },\n          required: [\"path\", \"content\"],\n        },\n      },\n      {\n        name: \"list_directory\",\n        description: \"列出目录内容\",\n        inputSchema: {\n          type: \"object\",\n          properties: {\n            path: { type: \"string\" },\n          },\n          required: [\"path\"],\n        },\n      },\n    ],\n  };\n});\n\nserver.setRequestHandler(\"tools\u002Fcall\", async (request) => {\n  const { name, arguments: args } = request.params;\n  const fullPath = path.join(WORKSPACE, args.path);\n\n  \u002F\u002F 安全检查：防止路径遍历\n  if (!fullPath.startsWith(WORKSPACE)) {\n    throw new Error(\"Access denied: path outside workspace\");\n  }\n\n  if (name === \"read_file\") {\n    const content = await fs.readFile(fullPath, \"utf-8\");\n    return {\n      content: [{ type: \"text\", text: content }],\n    };\n  }\n\n  if (name === \"write_file\") {\n    await fs.writeFile(fullPath, args.content, \"utf-8\");\n    return {\n      content: [{ type: \"text\", text: \"文件写入成功\" }],\n    };\n  }\n\n  if (name === \"list_directory\") {\n    const files = await fs.readdir(fullPath);\n    return {\n      content: [{ type: \"text\", text: files.join(\"\\n\") }],\n    };\n  }\n});\n",[127,3982,3983,3997,4011,4015,4041,4045,4065,4071,4075,4079,4088,4097,4101,4109,4113,4122,4126,4135,4139,4143,4147,4156,4165,4169,4177,4181,4189,4198,4202,4215,4219,4223,4227,4236,4245,4249,4257,4261,4269,4273,4281,4285,4289,4293,4297,4301,4305,4329,4351,4373,4377,4382,4401,4416,4420,4424,4437,4458,4464,4474,4478,4482,4486,4499,4516,4522,4537,4541,4545,4549,4562,4581,4587,4609,4613,4617],{"__ignoreMap":125},[130,3984,3985,3987,3990,3992,3995],{"class":132,"line":133},[130,3986,199],{"class":198},[130,3988,3989],{"class":202}," fs ",[130,3991,206],{"class":198},[130,3993,3994],{"class":147}," \"fs\u002Fpromises\"",[130,3996,212],{"class":202},[130,3998,3999,4001,4004,4006,4009],{"class":132,"line":140},[130,4000,199],{"class":198},[130,4002,4003],{"class":202}," path ",[130,4005,206],{"class":198},[130,4007,4008],{"class":147}," \"path\"",[130,4010,212],{"class":202},[130,4012,4013],{"class":132,"line":154},[130,4014,158],{"emptyLinePlaceholder":157},[130,4016,4017,4019,4022,4024,4027,4030,4033,4036,4039],{"class":132,"line":161},[130,4018,235],{"class":198},[130,4020,4021],{"class":238}," WORKSPACE",[130,4023,242],{"class":198},[130,4025,4026],{"class":202}," process.env.",[130,4028,4029],{"class":238},"WORKSPACE_DIR",[130,4031,4032],{"class":198}," ||",[130,4034,4035],{"class":202}," process.",[130,4037,4038],{"class":143},"cwd",[130,4040,708],{"class":202},[130,4042,4043],{"class":132,"line":167},[130,4044,158],{"emptyLinePlaceholder":157},[130,4046,4047,4049,4051,4053,4055,4057,4059,4061,4063],{"class":132,"line":259},[130,4048,336],{"class":202},[130,4050,339],{"class":143},[130,4052,342],{"class":202},[130,4054,345],{"class":147},[130,4056,348],{"class":202},[130,4058,351],{"class":198},[130,4060,354],{"class":202},[130,4062,357],{"class":198},[130,4064,360],{"class":202},[130,4066,4067,4069],{"class":132,"line":271},[130,4068,366],{"class":198},[130,4070,360],{"class":202},[130,4072,4073],{"class":132,"line":282},[130,4074,374],{"class":202},[130,4076,4077],{"class":132,"line":288},[130,4078,380],{"class":202},[130,4080,4081,4083,4086],{"class":132,"line":293},[130,4082,386],{"class":202},[130,4084,4085],{"class":147},"\"read_file\"",[130,4087,268],{"class":202},[130,4089,4090,4092,4095],{"class":132,"line":299},[130,4091,397],{"class":202},[130,4093,4094],{"class":147},"\"读取文件内容\"",[130,4096,268],{"class":202},[130,4098,4099],{"class":132,"line":305},[130,4100,408],{"class":202},[130,4102,4103,4105,4107],{"class":132,"line":311},[130,4104,414],{"class":202},[130,4106,417],{"class":147},[130,4108,268],{"class":202},[130,4110,4111],{"class":132,"line":316},[130,4112,425],{"class":202},[130,4114,4115,4118,4120],{"class":132,"line":322},[130,4116,4117],{"class":202},"            path: { type: ",[130,4119,440],{"class":147},[130,4121,2964],{"class":202},[130,4123,4124],{"class":132,"line":327},[130,4125,465],{"class":202},[130,4127,4128,4130,4133],{"class":132,"line":333},[130,4129,471],{"class":202},[130,4131,4132],{"class":147},"\"path\"",[130,4134,477],{"class":202},[130,4136,4137],{"class":132,"line":363},[130,4138,483],{"class":202},[130,4140,4141],{"class":132,"line":371},[130,4142,489],{"class":202},[130,4144,4145],{"class":132,"line":377},[130,4146,380],{"class":202},[130,4148,4149,4151,4154],{"class":132,"line":383},[130,4150,386],{"class":202},[130,4152,4153],{"class":147},"\"write_file\"",[130,4155,268],{"class":202},[130,4157,4158,4160,4163],{"class":132,"line":394},[130,4159,397],{"class":202},[130,4161,4162],{"class":147},"\"写入文件\"",[130,4164,268],{"class":202},[130,4166,4167],{"class":132,"line":405},[130,4168,408],{"class":202},[130,4170,4171,4173,4175],{"class":132,"line":411},[130,4172,414],{"class":202},[130,4174,417],{"class":147},[130,4176,268],{"class":202},[130,4178,4179],{"class":132,"line":422},[130,4180,425],{"class":202},[130,4182,4183,4185,4187],{"class":132,"line":428},[130,4184,4117],{"class":202},[130,4186,440],{"class":147},[130,4188,2964],{"class":202},[130,4190,4191,4194,4196],{"class":132,"line":434},[130,4192,4193],{"class":202},"            content: { type: ",[130,4195,440],{"class":147},[130,4197,2964],{"class":202},[130,4199,4200],{"class":132,"line":445},[130,4201,465],{"class":202},[130,4203,4204,4206,4208,4210,4213],{"class":132,"line":456},[130,4205,471],{"class":202},[130,4207,4132],{"class":147},[130,4209,348],{"class":202},[130,4211,4212],{"class":147},"\"content\"",[130,4214,477],{"class":202},[130,4216,4217],{"class":132,"line":462},[130,4218,483],{"class":202},[130,4220,4221],{"class":132,"line":468},[130,4222,489],{"class":202},[130,4224,4225],{"class":132,"line":480},[130,4226,380],{"class":202},[130,4228,4229,4231,4234],{"class":132,"line":486},[130,4230,386],{"class":202},[130,4232,4233],{"class":147},"\"list_directory\"",[130,4235,268],{"class":202},[130,4237,4238,4240,4243],{"class":132,"line":492},[130,4239,397],{"class":202},[130,4241,4242],{"class":147},"\"列出目录内容\"",[130,4244,268],{"class":202},[130,4246,4247],{"class":132,"line":498},[130,4248,408],{"class":202},[130,4250,4251,4253,4255],{"class":132,"line":504},[130,4252,414],{"class":202},[130,4254,417],{"class":147},[130,4256,268],{"class":202},[130,4258,4259],{"class":132,"line":510},[130,4260,425],{"class":202},[130,4262,4263,4265,4267],{"class":132,"line":515},[130,4264,4117],{"class":202},[130,4266,440],{"class":147},[130,4268,2964],{"class":202},[130,4270,4271],{"class":132,"line":521},[130,4272,465],{"class":202},[130,4274,4275,4277,4279],{"class":132,"line":551},[130,4276,471],{"class":202},[130,4278,4132],{"class":147},[130,4280,477],{"class":202},[130,4282,4283],{"class":132,"line":569},[130,4284,483],{"class":202},[130,4286,4287],{"class":132,"line":583},[130,4288,489],{"class":202},[130,4290,4291],{"class":132,"line":589},[130,4292,495],{"class":202},[130,4294,4295],{"class":132,"line":597},[130,4296,501],{"class":202},[130,4298,4299],{"class":132,"line":603},[130,4300,507],{"class":202},[130,4302,4303],{"class":132,"line":609},[130,4304,158],{"emptyLinePlaceholder":157},[130,4306,4307,4309,4311,4313,4315,4317,4319,4321,4323,4325,4327],{"class":132,"line":619},[130,4308,336],{"class":202},[130,4310,339],{"class":143},[130,4312,342],{"class":202},[130,4314,530],{"class":147},[130,4316,348],{"class":202},[130,4318,351],{"class":198},[130,4320,537],{"class":202},[130,4322,541],{"class":540},[130,4324,544],{"class":202},[130,4326,357],{"class":198},[130,4328,360],{"class":202},[130,4330,4331,4333,4335,4337,4339,4341,4343,4345,4347,4349],{"class":132,"line":636},[130,4332,1921],{"class":198},[130,4334,3193],{"class":202},[130,4336,1097],{"class":238},[130,4338,348],{"class":202},[130,4340,3200],{"class":540},[130,4342,872],{"class":202},[130,4344,3205],{"class":238},[130,4346,3208],{"class":202},[130,4348,787],{"class":198},[130,4350,3213],{"class":202},[130,4352,4353,4355,4358,4360,4363,4365,4367,4370],{"class":132,"line":641},[130,4354,1921],{"class":198},[130,4356,4357],{"class":238}," fullPath",[130,4359,242],{"class":198},[130,4361,4362],{"class":202}," path.",[130,4364,3484],{"class":143},[130,4366,342],{"class":202},[130,4368,4369],{"class":238},"WORKSPACE",[130,4371,4372],{"class":202},", args.path);\n",[130,4374,4375],{"class":132,"line":647},[130,4376,158],{"emptyLinePlaceholder":157},[130,4378,4379],{"class":132,"line":653},[130,4380,4381],{"class":136},"  \u002F\u002F 安全检查：防止路径遍历\n",[130,4383,4384,4386,4388,4390,4393,4395,4397,4399],{"class":132,"line":659},[130,4385,554],{"class":198},[130,4387,537],{"class":202},[130,4389,2735],{"class":198},[130,4391,4392],{"class":202},"fullPath.",[130,4394,1943],{"class":143},[130,4396,342],{"class":202},[130,4398,4369],{"class":238},[130,4400,1951],{"class":202},[130,4402,4403,4405,4407,4409,4411,4414],{"class":132,"line":677},[130,4404,2746],{"class":198},[130,4406,245],{"class":198},[130,4408,667],{"class":143},[130,4410,342],{"class":202},[130,4412,4413],{"class":147},"\"Access denied: path outside workspace\"",[130,4415,319],{"class":202},[130,4417,4418],{"class":132,"line":682},[130,4419,656],{"class":202},[130,4421,4422],{"class":132,"line":687},[130,4423,158],{"emptyLinePlaceholder":157},[130,4425,4426,4428,4430,4432,4435],{"class":132,"line":693},[130,4427,554],{"class":198},[130,4429,3224],{"class":202},[130,4431,560],{"class":198},[130,4433,4434],{"class":147}," \"read_file\"",[130,4436,566],{"class":202},[130,4438,4439,4441,4443,4445,4447,4449,4451,4454,4456],{"class":132,"line":711},[130,4440,572],{"class":198},[130,4442,1980],{"class":238},[130,4444,242],{"class":198},[130,4446,1985],{"class":198},[130,4448,1988],{"class":202},[130,4450,1991],{"class":143},[130,4452,4453],{"class":202},"(fullPath, ",[130,4455,1997],{"class":147},[130,4457,319],{"class":202},[130,4459,4460,4462],{"class":132,"line":3303},[130,4461,592],{"class":198},[130,4463,360],{"class":202},[130,4465,4466,4469,4471],{"class":132,"line":3328},[130,4467,4468],{"class":202},"      content: [{ type: ",[130,4470,614],{"class":147},[130,4472,4473],{"class":202},", text: content }],\n",[130,4475,4476],{"class":132,"line":3333},[130,4477,650],{"class":202},[130,4479,4480],{"class":132,"line":3338},[130,4481,656],{"class":202},[130,4483,4484],{"class":132,"line":3343},[130,4485,158],{"emptyLinePlaceholder":157},[130,4487,4488,4490,4492,4494,4497],{"class":132,"line":3348},[130,4489,554],{"class":198},[130,4491,3224],{"class":202},[130,4493,560],{"class":198},[130,4495,4496],{"class":147}," \"write_file\"",[130,4498,566],{"class":202},[130,4500,4501,4504,4506,4509,4512,4514],{"class":132,"line":3353},[130,4502,4503],{"class":198},"    await",[130,4505,1988],{"class":202},[130,4507,4508],{"class":143},"writeFile",[130,4510,4511],{"class":202},"(fullPath, args.content, ",[130,4513,1997],{"class":147},[130,4515,319],{"class":202},[130,4517,4518,4520],{"class":132,"line":3367},[130,4519,592],{"class":198},[130,4521,360],{"class":202},[130,4523,4524,4526,4528,4531,4534],{"class":132,"line":3386},[130,4525,4468],{"class":202},[130,4527,614],{"class":147},[130,4529,4530],{"class":202},", text: ",[130,4532,4533],{"class":147},"\"文件写入成功\"",[130,4535,4536],{"class":202}," }],\n",[130,4538,4539],{"class":132,"line":3391},[130,4540,650],{"class":202},[130,4542,4543],{"class":132,"line":3396},[130,4544,656],{"class":202},[130,4546,4547],{"class":132,"line":3402},[130,4548,158],{"emptyLinePlaceholder":157},[130,4550,4551,4553,4555,4557,4560],{"class":132,"line":3407},[130,4552,554],{"class":198},[130,4554,3224],{"class":202},[130,4556,560],{"class":198},[130,4558,4559],{"class":147}," \"list_directory\"",[130,4561,566],{"class":202},[130,4563,4564,4566,4569,4571,4573,4575,4578],{"class":132,"line":3412},[130,4565,572],{"class":198},[130,4567,4568],{"class":238}," files",[130,4570,242],{"class":198},[130,4572,1985],{"class":198},[130,4574,1988],{"class":202},[130,4576,4577],{"class":143},"readdir",[130,4579,4580],{"class":202},"(fullPath);\n",[130,4582,4583,4585],{"class":132,"line":3425},[130,4584,592],{"class":198},[130,4586,360],{"class":202},[130,4588,4589,4591,4593,4596,4598,4600,4602,4604,4606],{"class":132,"line":3479},[130,4590,4468],{"class":202},[130,4592,614],{"class":147},[130,4594,4595],{"class":202},", text: files.",[130,4597,3484],{"class":143},[130,4599,342],{"class":202},[130,4601,1056],{"class":147},[130,4603,3491],{"class":238},[130,4605,1056],{"class":147},[130,4607,4608],{"class":202},") }],\n",[130,4610,4611],{"class":132,"line":3498},[130,4612,650],{"class":202},[130,4614,4615],{"class":132,"line":3503},[130,4616,656],{"class":202},[130,4618,4619],{"class":132,"line":3510},[130,4620,507],{"class":202},[29,4622,4623],{"id":4623},"测试与调试",[50,4625,4627],{"id":4626},"使用-mcp-inspector","使用 MCP Inspector",[120,4629,4631],{"className":122,"code":4630,"language":124,"meta":125,"style":125},"npx @modelcontextprotocol\u002Finspector node server.js\n",[127,4632,4633],{"__ignoreMap":125},[130,4634,4635,4638,4641,4644],{"class":132,"line":133},[130,4636,4637],{"class":143},"npx",[130,4639,4640],{"class":147}," @modelcontextprotocol\u002Finspector",[130,4642,4643],{"class":147}," node",[130,4645,4646],{"class":147}," server.js\n",[22,4648,4649,4650,4653],{},"在浏览器中打开 ",[127,4651,4652],{},"http:\u002F\u002Flocalhost:5173","，可以：",[33,4655,4656,4659,4662],{},[36,4657,4658],{},"查看服务器信息",[36,4660,4661],{},"测试工具调用",[36,4663,4664],{},"查看日志输出",[50,4666,4667],{"id":4667},"单元测试",[120,4669,4671],{"className":189,"code":4670,"language":191,"meta":125,"style":125},"import { describe, it, expect } from \"vitest\";\nimport { Server } from \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002Findex.js\";\n\ndescribe(\"Weather Server\", () => {\n  it(\"should return weather data\", async () => {\n    const server = createWeatherServer();\n\n    const response = await server.request({\n      method: \"tools\u002Fcall\",\n      params: {\n        name: \"get_weather\",\n        arguments: { city: \"北京\" },\n      },\n    });\n\n    expect(response.content[0].text).toContain(\"北京\");\n  });\n});\n",[127,4672,4673,4687,4699,4703,4720,4740,4753,4757,4774,4782,4787,4795,4805,4809,4813,4817,4840,4844],{"__ignoreMap":125},[130,4674,4675,4677,4680,4682,4685],{"class":132,"line":133},[130,4676,199],{"class":198},[130,4678,4679],{"class":202}," { describe, it, expect } ",[130,4681,206],{"class":198},[130,4683,4684],{"class":147}," \"vitest\"",[130,4686,212],{"class":202},[130,4688,4689,4691,4693,4695,4697],{"class":132,"line":140},[130,4690,199],{"class":198},[130,4692,203],{"class":202},[130,4694,206],{"class":198},[130,4696,209],{"class":147},[130,4698,212],{"class":202},[130,4700,4701],{"class":132,"line":154},[130,4702,158],{"emptyLinePlaceholder":157},[130,4704,4705,4708,4710,4713,4716,4718],{"class":132,"line":161},[130,4706,4707],{"class":143},"describe",[130,4709,342],{"class":202},[130,4711,4712],{"class":147},"\"Weather Server\"",[130,4714,4715],{"class":202},", () ",[130,4717,357],{"class":198},[130,4719,360],{"class":202},[130,4721,4722,4725,4727,4730,4732,4734,4736,4738],{"class":132,"line":167},[130,4723,4724],{"class":143},"  it",[130,4726,342],{"class":202},[130,4728,4729],{"class":147},"\"should return weather data\"",[130,4731,348],{"class":202},[130,4733,351],{"class":198},[130,4735,354],{"class":202},[130,4737,357],{"class":198},[130,4739,360],{"class":202},[130,4741,4742,4744,4746,4748,4751],{"class":132,"line":259},[130,4743,572],{"class":198},[130,4745,239],{"class":238},[130,4747,242],{"class":198},[130,4749,4750],{"class":143}," createWeatherServer",[130,4752,708],{"class":202},[130,4754,4755],{"class":132,"line":271},[130,4756,158],{"emptyLinePlaceholder":157},[130,4758,4759,4761,4764,4766,4768,4770,4772],{"class":132,"line":282},[130,4760,572],{"class":198},[130,4762,4763],{"class":238}," response",[130,4765,242],{"class":198},[130,4767,1985],{"class":198},[130,4769,717],{"class":202},[130,4771,541],{"class":143},[130,4773,2495],{"class":202},[130,4775,4776,4778,4780],{"class":132,"line":288},[130,4777,2642],{"class":202},[130,4779,530],{"class":147},[130,4781,268],{"class":202},[130,4783,4784],{"class":132,"line":293},[130,4785,4786],{"class":202},"      params: {\n",[130,4788,4789,4791,4793],{"class":132,"line":299},[130,4790,386],{"class":202},[130,4792,389],{"class":147},[130,4794,268],{"class":202},[130,4796,4797,4800,4803],{"class":132,"line":305},[130,4798,4799],{"class":202},"        arguments: { city: ",[130,4801,4802],{"class":147},"\"北京\"",[130,4804,2964],{"class":202},[130,4806,4807],{"class":132,"line":311},[130,4808,489],{"class":202},[130,4810,4811],{"class":132,"line":316},[130,4812,2657],{"class":202},[130,4814,4815],{"class":132,"line":322},[130,4816,158],{"emptyLinePlaceholder":157},[130,4818,4819,4822,4825,4828,4831,4834,4836,4838],{"class":132,"line":327},[130,4820,4821],{"class":143},"    expect",[130,4823,4824],{"class":202},"(response.content[",[130,4826,4827],{"class":238},"0",[130,4829,4830],{"class":202},"].text).",[130,4832,4833],{"class":143},"toContain",[130,4835,342],{"class":202},[130,4837,4802],{"class":147},[130,4839,319],{"class":202},[130,4841,4842],{"class":132,"line":333},[130,4843,2662],{"class":202},[130,4845,4846],{"class":132,"line":363},[130,4847,507],{"class":202},[50,4849,4850],{"id":4850},"日志记录",[120,4852,4854],{"className":189,"code":4853,"language":191,"meta":125,"style":125},"import { Logger } from \"@modelcontextprotocol\u002Fsdk\u002Fshared\u002Flogger.js\";\n\nconst logger = new Logger(\"my-server\");\n\nserver.setRequestHandler(\"tools\u002Fcall\", async (request) => {\n  logger.info(`Tool called: ${request.params.name}`);\n  logger.debug(`Arguments: ${JSON.stringify(request.params.arguments)}`);\n\n  try {\n    \u002F\u002F 工具逻辑\n  } catch (error) {\n    logger.error(`Error: ${error.message}`);\n    throw error;\n  }\n});\n",[127,4855,4856,4870,4874,4895,4899,4923,4951,4990,4994,5000,5004,5012,5034,5041,5045],{"__ignoreMap":125},[130,4857,4858,4860,4863,4865,4868],{"class":132,"line":133},[130,4859,199],{"class":198},[130,4861,4862],{"class":202}," { Logger } ",[130,4864,206],{"class":198},[130,4866,4867],{"class":147}," \"@modelcontextprotocol\u002Fsdk\u002Fshared\u002Flogger.js\"",[130,4869,212],{"class":202},[130,4871,4872],{"class":132,"line":140},[130,4873,158],{"emptyLinePlaceholder":157},[130,4875,4876,4878,4881,4883,4885,4888,4890,4893],{"class":132,"line":154},[130,4877,235],{"class":198},[130,4879,4880],{"class":238}," logger",[130,4882,242],{"class":198},[130,4884,245],{"class":198},[130,4886,4887],{"class":143}," Logger",[130,4889,342],{"class":202},[130,4891,4892],{"class":147},"\"my-server\"",[130,4894,319],{"class":202},[130,4896,4897],{"class":132,"line":161},[130,4898,158],{"emptyLinePlaceholder":157},[130,4900,4901,4903,4905,4907,4909,4911,4913,4915,4917,4919,4921],{"class":132,"line":167},[130,4902,336],{"class":202},[130,4904,339],{"class":143},[130,4906,342],{"class":202},[130,4908,530],{"class":147},[130,4910,348],{"class":202},[130,4912,351],{"class":198},[130,4914,537],{"class":202},[130,4916,541],{"class":540},[130,4918,544],{"class":202},[130,4920,357],{"class":198},[130,4922,360],{"class":202},[130,4924,4925,4928,4931,4933,4936,4938,4940,4943,4945,4947,4949],{"class":132,"line":259},[130,4926,4927],{"class":202},"  logger.",[130,4929,4930],{"class":143},"info",[130,4932,342],{"class":202},[130,4934,4935],{"class":147},"`Tool called: ${",[130,4937,541],{"class":202},[130,4939,1719],{"class":147},[130,4941,4942],{"class":202},"params",[130,4944,1719],{"class":147},[130,4946,1097],{"class":202},[130,4948,1725],{"class":147},[130,4950,319],{"class":202},[130,4952,4953,4955,4958,4960,4963,4966,4968,4971,4973,4975,4977,4979,4981,4983,4986,4988],{"class":132,"line":271},[130,4954,4927],{"class":202},[130,4956,4957],{"class":143},"debug",[130,4959,342],{"class":202},[130,4961,4962],{"class":147},"`Arguments: ${",[130,4964,4965],{"class":238},"JSON",[130,4967,1719],{"class":147},[130,4969,4970],{"class":143},"stringify",[130,4972,342],{"class":147},[130,4974,541],{"class":202},[130,4976,1719],{"class":147},[130,4978,4942],{"class":202},[130,4980,1719],{"class":147},[130,4982,3200],{"class":202},[130,4984,4985],{"class":147},")",[130,4987,1725],{"class":147},[130,4989,319],{"class":202},[130,4991,4992],{"class":132,"line":282},[130,4993,158],{"emptyLinePlaceholder":157},[130,4995,4996,4998],{"class":132,"line":288},[130,4997,1666],{"class":198},[130,4999,360],{"class":202},[130,5001,5002],{"class":132,"line":293},[130,5003,1673],{"class":136},[130,5005,5006,5008,5010],{"class":132,"line":299},[130,5007,1678],{"class":202},[130,5009,1681],{"class":198},[130,5011,1684],{"class":202},[130,5013,5014,5017,5019,5021,5024,5026,5028,5030,5032],{"class":132,"line":305},[130,5015,5016],{"class":202},"    logger.",[130,5018,1716],{"class":143},[130,5020,342],{"class":202},[130,5022,5023],{"class":147},"`Error: ${",[130,5025,1716],{"class":202},[130,5027,1719],{"class":147},[130,5029,1722],{"class":202},[130,5031,1725],{"class":147},[130,5033,319],{"class":202},[130,5035,5036,5038],{"class":132,"line":311},[130,5037,2746],{"class":198},[130,5039,5040],{"class":202}," error;\n",[130,5042,5043],{"class":132,"line":316},[130,5044,656],{"class":202},[130,5046,5047],{"class":132,"line":322},[130,5048,507],{"class":202},[29,5050,5051],{"id":5051},"部署",[50,5053,5055],{"id":5054},"发布到-npm","发布到 npm",[120,5057,5059],{"className":1145,"code":5058,"language":1147,"meta":125,"style":125},"{\n  \"name\": \"mcp-server-weather\",\n  \"version\": \"1.0.0\",\n  \"bin\": {\n    \"mcp-server-weather\": \".\u002Fdist\u002Findex.js\"\n  },\n  \"files\": [\"dist\"]\n}\n",[127,5060,5061,5065,5077,5088,5095,5105,5109,5121],{"__ignoreMap":125},[130,5062,5063],{"class":132,"line":133},[130,5064,864],{"class":202},[130,5066,5067,5070,5072,5075],{"class":132,"line":140},[130,5068,5069],{"class":238},"  \"name\"",[130,5071,872],{"class":202},[130,5073,5074],{"class":147},"\"mcp-server-weather\"",[130,5076,268],{"class":202},[130,5078,5079,5082,5084,5086],{"class":132,"line":154},[130,5080,5081],{"class":238},"  \"version\"",[130,5083,872],{"class":202},[130,5085,277],{"class":147},[130,5087,268],{"class":202},[130,5089,5090,5093],{"class":132,"line":161},[130,5091,5092],{"class":238},"  \"bin\"",[130,5094,884],{"class":202},[130,5096,5097,5100,5102],{"class":132,"line":167},[130,5098,5099],{"class":238},"    \"mcp-server-weather\"",[130,5101,872],{"class":202},[130,5103,5104],{"class":147},"\".\u002Fdist\u002Findex.js\"\n",[130,5106,5107],{"class":132,"line":259},[130,5108,285],{"class":202},[130,5110,5111,5114,5116,5119],{"class":132,"line":271},[130,5112,5113],{"class":238},"  \"files\"",[130,5115,930],{"class":202},[130,5117,5118],{"class":147},"\"dist\"",[130,5120,935],{"class":202},[130,5122,5123],{"class":132,"line":282},[130,5124,1205],{"class":202},[22,5126,5127,5128,5130],{},"用户可以通过 ",[127,5129,4637],{}," 直接使用：",[120,5132,5134],{"className":1145,"code":5133,"language":1147,"meta":125,"style":125},"{\n  \"mcpServers\": {\n    \"weather\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"mcp-server-weather\"]\n    }\n  }\n}\n",[127,5135,5136,5140,5146,5152,5163,5178,5182,5186],{"__ignoreMap":125},[130,5137,5138],{"class":132,"line":133},[130,5139,864],{"class":202},[130,5141,5142,5144],{"class":132,"line":140},[130,5143,1158],{"class":238},[130,5145,884],{"class":202},[130,5147,5148,5150],{"class":132,"line":154},[130,5149,1165],{"class":238},[130,5151,884],{"class":202},[130,5153,5154,5156,5158,5161],{"class":132,"line":161},[130,5155,1172],{"class":238},[130,5157,872],{"class":202},[130,5159,5160],{"class":147},"\"npx\"",[130,5162,268],{"class":202},[130,5164,5165,5167,5169,5172,5174,5176],{"class":132,"line":167},[130,5166,1184],{"class":238},[130,5168,930],{"class":202},[130,5170,5171],{"class":147},"\"-y\"",[130,5173,348],{"class":202},[130,5175,5074],{"class":147},[130,5177,935],{"class":202},[130,5179,5180],{"class":132,"line":259},[130,5181,1196],{"class":202},[130,5183,5184],{"class":132,"line":271},[130,5185,656],{"class":202},[130,5187,5188],{"class":132,"line":282},[130,5189,1205],{"class":202},[50,5191,5193],{"id":5192},"发布到-pypi","发布到 PyPI",[120,5195,5197],{"className":735,"code":5196,"language":737,"meta":125,"style":125},"# setup.py\nfrom setuptools import setup\n\nsetup(\n    name=\"mcp-server-weather\",\n    version=\"1.0.0\",\n    py_modules=[\"server\"],\n    entry_points={\n        \"console_scripts\": [\n            \"mcp-server-weather=server:main\",\n        ],\n    },\n)\n",[127,5198,5199,5204,5216,5220,5225,5236,5247,5262,5271,5279,5286,5290,5294],{"__ignoreMap":125},[130,5200,5201],{"class":132,"line":133},[130,5202,5203],{"class":136},"# setup.py\n",[130,5205,5206,5208,5211,5213],{"class":132,"line":140},[130,5207,206],{"class":198},[130,5209,5210],{"class":202}," setuptools ",[130,5212,199],{"class":198},[130,5214,5215],{"class":202}," setup\n",[130,5217,5218],{"class":132,"line":154},[130,5219,158],{"emptyLinePlaceholder":157},[130,5221,5222],{"class":132,"line":161},[130,5223,5224],{"class":202},"setup(\n",[130,5226,5227,5230,5232,5234],{"class":132,"line":167},[130,5228,5229],{"class":540},"    name",[130,5231,787],{"class":198},[130,5233,5074],{"class":147},[130,5235,268],{"class":202},[130,5237,5238,5241,5243,5245],{"class":132,"line":259},[130,5239,5240],{"class":540},"    version",[130,5242,787],{"class":198},[130,5244,277],{"class":147},[130,5246,268],{"class":202},[130,5248,5249,5252,5254,5257,5260],{"class":132,"line":271},[130,5250,5251],{"class":540},"    py_modules",[130,5253,787],{"class":198},[130,5255,5256],{"class":202},"[",[130,5258,5259],{"class":147},"\"server\"",[130,5261,477],{"class":202},[130,5263,5264,5267,5269],{"class":132,"line":282},[130,5265,5266],{"class":540},"    entry_points",[130,5268,787],{"class":198},[130,5270,864],{"class":202},[130,5272,5273,5276],{"class":132,"line":288},[130,5274,5275],{"class":147},"        \"console_scripts\"",[130,5277,5278],{"class":202},": [\n",[130,5280,5281,5284],{"class":132,"line":293},[130,5282,5283],{"class":147},"            \"mcp-server-weather=server:main\"",[130,5285,268],{"class":202},[130,5287,5288],{"class":132,"line":299},[130,5289,2185],{"class":202},[130,5291,5292],{"class":132,"line":305},[130,5293,308],{"class":202},[130,5295,5296],{"class":132,"line":311},[130,5297,795],{"class":202},[22,5299,5127,5300,5303],{},[127,5301,5302],{},"uvx"," 使用：",[120,5305,5307],{"className":1145,"code":5306,"language":1147,"meta":125,"style":125},"{\n  \"mcpServers\": {\n    \"weather\": {\n      \"command\": \"uvx\",\n      \"args\": [\"mcp-server-weather\"]\n    }\n  }\n}\n",[127,5308,5309,5313,5319,5325,5336,5346,5350,5354],{"__ignoreMap":125},[130,5310,5311],{"class":132,"line":133},[130,5312,864],{"class":202},[130,5314,5315,5317],{"class":132,"line":140},[130,5316,1158],{"class":238},[130,5318,884],{"class":202},[130,5320,5321,5323],{"class":132,"line":154},[130,5322,1165],{"class":238},[130,5324,884],{"class":202},[130,5326,5327,5329,5331,5334],{"class":132,"line":161},[130,5328,1172],{"class":238},[130,5330,872],{"class":202},[130,5332,5333],{"class":147},"\"uvx\"",[130,5335,268],{"class":202},[130,5337,5338,5340,5342,5344],{"class":132,"line":167},[130,5339,1184],{"class":238},[130,5341,930],{"class":202},[130,5343,5074],{"class":147},[130,5345,935],{"class":202},[130,5347,5348],{"class":132,"line":259},[130,5349,1196],{"class":202},[130,5351,5352],{"class":132,"line":271},[130,5353,656],{"class":202},[130,5355,5356],{"class":132,"line":282},[130,5357,1205],{"class":202},[50,5359,5361],{"id":5360},"docker-部署","Docker 部署",[120,5363,5367],{"className":5364,"code":5365,"language":5366,"meta":125,"style":125},"language-dockerfile shiki shiki-themes github-light github-dark","FROM node:20-alpine\nWORKDIR \u002Fapp\nCOPY package*.json .\u002F\nRUN npm ci --production\nCOPY . .\nCMD [\"node\", \"server.js\"]\n","dockerfile",[127,5368,5369,5377,5385,5393,5401,5408],{"__ignoreMap":125},[130,5370,5371,5374],{"class":132,"line":133},[130,5372,5373],{"class":198},"FROM",[130,5375,5376],{"class":202}," node:20-alpine\n",[130,5378,5379,5382],{"class":132,"line":140},[130,5380,5381],{"class":198},"WORKDIR",[130,5383,5384],{"class":202}," \u002Fapp\n",[130,5386,5387,5390],{"class":132,"line":154},[130,5388,5389],{"class":198},"COPY",[130,5391,5392],{"class":202}," package*.json .\u002F\n",[130,5394,5395,5398],{"class":132,"line":161},[130,5396,5397],{"class":198},"RUN",[130,5399,5400],{"class":202}," npm ci --production\n",[130,5402,5403,5405],{"class":132,"line":167},[130,5404,5389],{"class":198},[130,5406,5407],{"class":202}," . .\n",[130,5409,5410,5413,5416,5418,5420,5422],{"class":132,"line":259},[130,5411,5412],{"class":198},"CMD",[130,5414,5415],{"class":202}," [",[130,5417,1177],{"class":147},[130,5419,348],{"class":202},[130,5421,1189],{"class":147},[130,5423,935],{"class":202},[22,5425,5426],{},"配置：",[120,5428,5430],{"className":1145,"code":5429,"language":1147,"meta":125,"style":125},"{\n  \"mcpServers\": {\n    \"weather\": {\n      \"command\": \"docker\",\n      \"args\": [\"run\", \"-i\", \"mcp-server-weather\"]\n    }\n  }\n}\n",[127,5431,5432,5436,5442,5448,5459,5479,5483,5487],{"__ignoreMap":125},[130,5433,5434],{"class":132,"line":133},[130,5435,864],{"class":202},[130,5437,5438,5440],{"class":132,"line":140},[130,5439,1158],{"class":238},[130,5441,884],{"class":202},[130,5443,5444,5446],{"class":132,"line":154},[130,5445,1165],{"class":238},[130,5447,884],{"class":202},[130,5449,5450,5452,5454,5457],{"class":132,"line":161},[130,5451,1172],{"class":238},[130,5453,872],{"class":202},[130,5455,5456],{"class":147},"\"docker\"",[130,5458,268],{"class":202},[130,5460,5461,5463,5465,5468,5470,5473,5475,5477],{"class":132,"line":167},[130,5462,1184],{"class":238},[130,5464,930],{"class":202},[130,5466,5467],{"class":147},"\"run\"",[130,5469,348],{"class":202},[130,5471,5472],{"class":147},"\"-i\"",[130,5474,348],{"class":202},[130,5476,5074],{"class":147},[130,5478,935],{"class":202},[130,5480,5481],{"class":132,"line":259},[130,5482,1196],{"class":202},[130,5484,5485],{"class":132,"line":271},[130,5486,656],{"class":202},[130,5488,5489],{"class":132,"line":282},[130,5490,1205],{"class":202},[29,5492,5493],{"id":5493},"最佳实践",[50,5495,5497],{"id":5496},"_1-清晰的工具描述","1. 清晰的工具描述",[120,5499,5501],{"className":189,"code":5500,"language":191,"meta":125,"style":125},"{\n  name: \"search_files\",\n  description: \"在指定目录搜索文件。支持通配符模式（如 *.js）和递归搜索。\",\n  \u002F\u002F 不好的描述：\n  \u002F\u002F description: \"搜索文件\"\n}\n",[127,5502,5503,5507,5517,5528,5533,5538],{"__ignoreMap":125},[130,5504,5505],{"class":132,"line":133},[130,5506,864],{"class":202},[130,5508,5509,5511,5513,5515],{"class":132,"line":140},[130,5510,1286],{"class":143},[130,5512,872],{"class":202},[130,5514,1291],{"class":147},[130,5516,268],{"class":202},[130,5518,5519,5521,5523,5526],{"class":132,"line":154},[130,5520,1298],{"class":143},[130,5522,872],{"class":202},[130,5524,5525],{"class":147},"\"在指定目录搜索文件。支持通配符模式（如 *.js）和递归搜索。\"",[130,5527,268],{"class":202},[130,5529,5530],{"class":132,"line":161},[130,5531,5532],{"class":136},"  \u002F\u002F 不好的描述：\n",[130,5534,5535],{"class":132,"line":167},[130,5536,5537],{"class":136},"  \u002F\u002F description: \"搜索文件\"\n",[130,5539,5540],{"class":132,"line":259},[130,5541,1205],{"class":202},[50,5543,5545],{"id":5544},"_2-详细的参数说明","2. 详细的参数说明",[120,5547,5549],{"className":189,"code":5548,"language":191,"meta":125,"style":125},"inputSchema: {\n  type: \"object\",\n  properties: {\n    query: {\n      type: \"string\",\n      description: \"搜索关键词。支持正则表达式，如 \u002Fpattern\u002Fi 表示不区分大小写。\",\n      \u002F\u002F 不好的描述：\n      \u002F\u002F description: \"查询\"\n    }\n  }\n}\n",[127,5550,5551,5558,5569,5576,5583,5594,5606,5611,5616,5620,5624],{"__ignoreMap":125},[130,5552,5553,5556],{"class":132,"line":133},[130,5554,5555],{"class":143},"inputSchema",[130,5557,884],{"class":202},[130,5559,5560,5563,5565,5567],{"class":132,"line":140},[130,5561,5562],{"class":143},"  type",[130,5564,872],{"class":202},[130,5566,417],{"class":147},[130,5568,268],{"class":202},[130,5570,5571,5574],{"class":132,"line":154},[130,5572,5573],{"class":143},"  properties",[130,5575,884],{"class":202},[130,5577,5578,5581],{"class":132,"line":161},[130,5579,5580],{"class":143},"    query",[130,5582,884],{"class":202},[130,5584,5585,5588,5590,5592],{"class":132,"line":167},[130,5586,5587],{"class":143},"      type",[130,5589,872],{"class":202},[130,5591,440],{"class":147},[130,5593,268],{"class":202},[130,5595,5596,5599,5601,5604],{"class":132,"line":259},[130,5597,5598],{"class":143},"      description",[130,5600,872],{"class":202},[130,5602,5603],{"class":147},"\"搜索关键词。支持正则表达式，如 \u002Fpattern\u002Fi 表示不区分大小写。\"",[130,5605,268],{"class":202},[130,5607,5608],{"class":132,"line":271},[130,5609,5610],{"class":136},"      \u002F\u002F 不好的描述：\n",[130,5612,5613],{"class":132,"line":282},[130,5614,5615],{"class":136},"      \u002F\u002F description: \"查询\"\n",[130,5617,5618],{"class":132,"line":288},[130,5619,1196],{"class":202},[130,5621,5622],{"class":132,"line":293},[130,5623,656],{"class":202},[130,5625,5626],{"class":132,"line":299},[130,5627,1205],{"class":202},[50,5629,5631],{"id":5630},"_3-合理的错误处理","3. 合理的错误处理",[120,5633,5635],{"className":189,"code":5634,"language":191,"meta":125,"style":125},"try {\n  \u002F\u002F 工具逻辑\n} catch (error) {\n  return {\n    content: [\n      {\n        type: \"text\",\n        text: `操作失败：${error.message}\\n\\n建议：检查文件路径是否正确`,\n      },\n    ],\n    isError: true,\n  };\n}\n",[127,5636,5637,5644,5649,5658,5664,5669,5673,5682,5706,5710,5714,5723,5727],{"__ignoreMap":125},[130,5638,5639,5642],{"class":132,"line":133},[130,5640,5641],{"class":198},"try",[130,5643,360],{"class":202},[130,5645,5646],{"class":132,"line":140},[130,5647,5648],{"class":136},"  \u002F\u002F 工具逻辑\n",[130,5650,5651,5654,5656],{"class":132,"line":154},[130,5652,5653],{"class":202},"} ",[130,5655,1681],{"class":198},[130,5657,1684],{"class":202},[130,5659,5660,5662],{"class":132,"line":161},[130,5661,366],{"class":198},[130,5663,360],{"class":202},[130,5665,5666],{"class":132,"line":167},[130,5667,5668],{"class":202},"    content: [\n",[130,5670,5671],{"class":132,"line":259},[130,5672,380],{"class":202},[130,5674,5675,5678,5680],{"class":132,"line":271},[130,5676,5677],{"class":202},"        type: ",[130,5679,614],{"class":147},[130,5681,268],{"class":202},[130,5683,5684,5687,5690,5692,5694,5696,5698,5701,5704],{"class":132,"line":282},[130,5685,5686],{"class":202},"        text: ",[130,5688,5689],{"class":147},"`操作失败：${",[130,5691,1716],{"class":202},[130,5693,1719],{"class":147},[130,5695,1722],{"class":202},[130,5697,1064],{"class":147},[130,5699,5700],{"class":238},"\\n\\n",[130,5702,5703],{"class":147},"建议：检查文件路径是否正确`",[130,5705,268],{"class":202},[130,5707,5708],{"class":132,"line":288},[130,5709,489],{"class":202},[130,5711,5712],{"class":132,"line":293},[130,5713,495],{"class":202},[130,5715,5716,5719,5721],{"class":132,"line":299},[130,5717,5718],{"class":202},"    isError: ",[130,5720,1743],{"class":238},[130,5722,268],{"class":202},[130,5724,5725],{"class":132,"line":305},[130,5726,501],{"class":202},[130,5728,5729],{"class":132,"line":311},[130,5730,1205],{"class":202},[50,5732,5734],{"id":5733},"_4-安全验证","4. 安全验证",[120,5736,5738],{"className":189,"code":5737,"language":191,"meta":125,"style":125},"\u002F\u002F 路径遍历防护\nif (!fullPath.startsWith(WORKSPACE)) {\n  throw new Error(\"Access denied\");\n}\n\n\u002F\u002F 输入验证\nif (!isValidEmail(args.email)) {\n  throw new Error(\"Invalid email format\");\n}\n\n\u002F\u002F 速率限制\nif (rateLimiter.isExceeded(clientId)) {\n  throw new Error(\"Rate limit exceeded\");\n}\n",[127,5739,5740,5745,5763,5778,5782,5786,5791,5805,5820,5824,5828,5833,5846,5861],{"__ignoreMap":125},[130,5741,5742],{"class":132,"line":133},[130,5743,5744],{"class":136},"\u002F\u002F 路径遍历防护\n",[130,5746,5747,5749,5751,5753,5755,5757,5759,5761],{"class":132,"line":140},[130,5748,1112],{"class":198},[130,5750,537],{"class":202},[130,5752,2735],{"class":198},[130,5754,4392],{"class":202},[130,5756,1943],{"class":143},[130,5758,342],{"class":202},[130,5760,4369],{"class":238},[130,5762,1951],{"class":202},[130,5764,5765,5767,5769,5771,5773,5776],{"class":132,"line":154},[130,5766,662],{"class":198},[130,5768,245],{"class":198},[130,5770,667],{"class":143},[130,5772,342],{"class":202},[130,5774,5775],{"class":147},"\"Access denied\"",[130,5777,319],{"class":202},[130,5779,5780],{"class":132,"line":161},[130,5781,1205],{"class":202},[130,5783,5784],{"class":132,"line":167},[130,5785,158],{"emptyLinePlaceholder":157},[130,5787,5788],{"class":132,"line":259},[130,5789,5790],{"class":136},"\u002F\u002F 输入验证\n",[130,5792,5793,5795,5797,5799,5802],{"class":132,"line":271},[130,5794,1112],{"class":198},[130,5796,537],{"class":202},[130,5798,2735],{"class":198},[130,5800,5801],{"class":143},"isValidEmail",[130,5803,5804],{"class":202},"(args.email)) {\n",[130,5806,5807,5809,5811,5813,5815,5818],{"class":132,"line":282},[130,5808,662],{"class":198},[130,5810,245],{"class":198},[130,5812,667],{"class":143},[130,5814,342],{"class":202},[130,5816,5817],{"class":147},"\"Invalid email format\"",[130,5819,319],{"class":202},[130,5821,5822],{"class":132,"line":288},[130,5823,1205],{"class":202},[130,5825,5826],{"class":132,"line":293},[130,5827,158],{"emptyLinePlaceholder":157},[130,5829,5830],{"class":132,"line":299},[130,5831,5832],{"class":136},"\u002F\u002F 速率限制\n",[130,5834,5835,5837,5840,5843],{"class":132,"line":305},[130,5836,1112],{"class":198},[130,5838,5839],{"class":202}," (rateLimiter.",[130,5841,5842],{"class":143},"isExceeded",[130,5844,5845],{"class":202},"(clientId)) {\n",[130,5847,5848,5850,5852,5854,5856,5859],{"class":132,"line":311},[130,5849,662],{"class":198},[130,5851,245],{"class":198},[130,5853,667],{"class":143},[130,5855,342],{"class":202},[130,5857,5858],{"class":147},"\"Rate limit exceeded\"",[130,5860,319],{"class":202},[130,5862,5863],{"class":132,"line":316},[130,5864,1205],{"class":202},[50,5866,5868],{"id":5867},"_5-性能优化","5. 性能优化",[120,5870,5872],{"className":189,"code":5871,"language":191,"meta":125,"style":125},"\u002F\u002F 缓存结果\nconst cache = new Map();\n\nserver.setRequestHandler(\"tools\u002Fcall\", async (request) => {\n  const cacheKey = JSON.stringify(request.params);\n\n  if (cache.has(cacheKey)) {\n    return cache.get(cacheKey);\n  }\n\n  const result = await expensiveOperation();\n  cache.set(cacheKey, result);\n\n  return result;\n});\n",[127,5873,5874,5879,5895,5899,5923,5942,5946,5959,5972,5976,5980,5995,6006,6010,6017],{"__ignoreMap":125},[130,5875,5876],{"class":132,"line":133},[130,5877,5878],{"class":136},"\u002F\u002F 缓存结果\n",[130,5880,5881,5883,5886,5888,5890,5893],{"class":132,"line":140},[130,5882,235],{"class":198},[130,5884,5885],{"class":238}," cache",[130,5887,242],{"class":198},[130,5889,245],{"class":198},[130,5891,5892],{"class":143}," Map",[130,5894,708],{"class":202},[130,5896,5897],{"class":132,"line":154},[130,5898,158],{"emptyLinePlaceholder":157},[130,5900,5901,5903,5905,5907,5909,5911,5913,5915,5917,5919,5921],{"class":132,"line":161},[130,5902,336],{"class":202},[130,5904,339],{"class":143},[130,5906,342],{"class":202},[130,5908,530],{"class":147},[130,5910,348],{"class":202},[130,5912,351],{"class":198},[130,5914,537],{"class":202},[130,5916,541],{"class":540},[130,5918,544],{"class":202},[130,5920,357],{"class":198},[130,5922,360],{"class":202},[130,5924,5925,5927,5930,5932,5935,5937,5939],{"class":132,"line":167},[130,5926,1921],{"class":198},[130,5928,5929],{"class":238}," cacheKey",[130,5931,242],{"class":198},[130,5933,5934],{"class":238}," JSON",[130,5936,1719],{"class":202},[130,5938,4970],{"class":143},[130,5940,5941],{"class":202},"(request.params);\n",[130,5943,5944],{"class":132,"line":259},[130,5945,158],{"emptyLinePlaceholder":157},[130,5947,5948,5950,5953,5956],{"class":132,"line":271},[130,5949,554],{"class":198},[130,5951,5952],{"class":202}," (cache.",[130,5954,5955],{"class":143},"has",[130,5957,5958],{"class":202},"(cacheKey)) {\n",[130,5960,5961,5963,5966,5969],{"class":132,"line":282},[130,5962,592],{"class":198},[130,5964,5965],{"class":202}," cache.",[130,5967,5968],{"class":143},"get",[130,5970,5971],{"class":202},"(cacheKey);\n",[130,5973,5974],{"class":132,"line":288},[130,5975,656],{"class":202},[130,5977,5978],{"class":132,"line":293},[130,5979,158],{"emptyLinePlaceholder":157},[130,5981,5982,5984,5986,5988,5990,5993],{"class":132,"line":299},[130,5983,1921],{"class":198},[130,5985,3238],{"class":238},[130,5987,242],{"class":198},[130,5989,1985],{"class":198},[130,5991,5992],{"class":143}," expensiveOperation",[130,5994,708],{"class":202},[130,5996,5997,6000,6003],{"class":132,"line":305},[130,5998,5999],{"class":202},"  cache.",[130,6001,6002],{"class":143},"set",[130,6004,6005],{"class":202},"(cacheKey, result);\n",[130,6007,6008],{"class":132,"line":311},[130,6009,158],{"emptyLinePlaceholder":157},[130,6011,6012,6014],{"class":132,"line":316},[130,6013,366],{"class":198},[130,6015,6016],{"class":202}," result;\n",[130,6018,6019],{"class":132,"line":322},[130,6020,507],{"class":202},[29,6022,6023],{"id":6023},"推荐开发顺序",[22,6025,6026],{},"建议按这个顺序推进：",[93,6028,6029,6032,6035,6038,6041],{},[36,6030,6031],{},"先做一个只暴露单个工具的最小服务器",[36,6033,6034],{},"再补输入校验和错误处理",[36,6036,6037],{},"再补资源与提示模板",[36,6039,6040],{},"再补日志、调试与测试",[36,6042,6043],{},"最后再做部署、权限和版本治理",[29,6045,6046],{"id":6046},"常见问题",[50,6048,6050],{"id":6049},"工具能跑但代理不会调用","工具能跑，但代理不会调用",[22,6052,6053],{},"优先检查：",[33,6055,6056,6059,6062,6065],{},[36,6057,6058],{},"工具描述是否清晰",[36,6060,6061],{},"输入 schema 是否合理",[36,6063,6064],{},"返回内容是否足够让模型理解下一步",[36,6066,6067],{},"客户端是否真的加载了该服务器",[50,6069,6071],{"id":6070},"该先做-tools-还是-resources","该先做 Tools 还是 Resources",[22,6073,6074],{},"如果你的能力更像“执行动作”，先做 Tools；如果主要是“提供内容”，先做 Resources。",[50,6076,6077],{"id":6077},"为什么服务器越写越重",[22,6079,6080],{},"通常说明把业务逻辑、适配层和协议层混在了一起。更稳的做法是把核心业务单独抽出来，MCP 只负责暴露接口。",[29,6082,6083],{"id":6083},"延伸阅读",[33,6085,6086,6093,6099],{},[36,6087,6088],{},[6089,6090,6092],"a",{"href":6091},"\u002Fdocs\u002Fmcp-guide","MCP 模型上下文协议",[36,6094,6095],{},[6089,6096,6098],{"href":6097},"\u002Fdocs\u002Fai-agents-cli","AI 终端代理与自主工具",[36,6100,6101],{},[6089,6102,6104],{"href":6103},"\u002Fdocs\u002Fai-coding-rules","AI 编程助手规则配置",[29,6106,6107],{"id":6107},"参考链接",[33,6109,6110,6118,6125,6132,6139,6145],{},[36,6111,6112],{},[6089,6113,6117],{"href":6114,"rel":6115},"https:\u002F\u002Fspec.modelcontextprotocol.io\u002F",[6116],"nofollow","MCP 协议规范",[36,6119,6120],{},[6089,6121,6124],{"href":6122,"rel":6123},"https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fsdk",[6116],"MCP SDK 文档",[36,6126,6127],{},[6089,6128,6131],{"href":6129,"rel":6130},"https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fservers",[6116],"MCP 服务器示例",[36,6133,6134],{},[6089,6135,6138],{"href":6136,"rel":6137},"https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Finspector",[6116],"MCP Inspector",[36,6140,6141],{},[6089,6142,6144],{"href":6143},"\u002Fdocs\u002Fnanobot#mcp-%E6%94%AF%E6%8C%81","nanobot MCP 集成",[36,6146,6147],{},[6089,6148,6150],{"href":6149},"\u002Fdocs\u002Fopenclaw#%E6%8A%80%E8%83%BD%E7%B3%BB%E7%BB%9F","OpenClaw 技能开发",[6152,6153,6154],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":125,"searchDepth":140,"depth":140,"links":6156},[6157,6158,6162,6168,6173,6177,6181,6186,6191,6196,6201,6208,6209,6214,6215],{"id":31,"depth":140,"text":31},{"id":47,"depth":140,"text":48,"children":6159},[6160,6161],{"id":52,"depth":154,"text":52},{"id":88,"depth":154,"text":88},{"id":115,"depth":140,"text":115,"children":6163},[6164,6165,6166,6167],{"id":118,"depth":154,"text":118},{"id":178,"depth":154,"text":179},{"id":726,"depth":154,"text":727},{"id":1139,"depth":154,"text":1139},{"id":1266,"depth":140,"text":1266,"children":6169},[6170,6171,6172],{"id":1269,"depth":154,"text":1269},{"id":1468,"depth":154,"text":1468},{"id":1632,"depth":154,"text":1632},{"id":1760,"depth":140,"text":1760,"children":6174},[6175,6176],{"id":1763,"depth":154,"text":1763},{"id":1886,"depth":154,"text":1886},{"id":2075,"depth":140,"text":2075,"children":6178},[6179,6180],{"id":2078,"depth":154,"text":2078},{"id":2204,"depth":154,"text":2204},{"id":2356,"depth":140,"text":2356,"children":6182},[6183,6184,6185],{"id":2359,"depth":154,"text":2359},{"id":2550,"depth":154,"text":2550},{"id":2680,"depth":154,"text":2680},{"id":2832,"depth":140,"text":2832,"children":6187},[6188,6189,6190],{"id":2835,"depth":154,"text":2836},{"id":3560,"depth":154,"text":3561},{"id":3976,"depth":154,"text":3977},{"id":4623,"depth":140,"text":4623,"children":6192},[6193,6194,6195],{"id":4626,"depth":154,"text":4627},{"id":4667,"depth":154,"text":4667},{"id":4850,"depth":154,"text":4850},{"id":5051,"depth":140,"text":5051,"children":6197},[6198,6199,6200],{"id":5054,"depth":154,"text":5055},{"id":5192,"depth":154,"text":5193},{"id":5360,"depth":154,"text":5361},{"id":5493,"depth":140,"text":5493,"children":6202},[6203,6204,6205,6206,6207],{"id":5496,"depth":154,"text":5497},{"id":5544,"depth":154,"text":5545},{"id":5630,"depth":154,"text":5631},{"id":5733,"depth":154,"text":5734},{"id":5867,"depth":154,"text":5868},{"id":6023,"depth":140,"text":6023},{"id":6046,"depth":140,"text":6046,"children":6210},[6211,6212,6213],{"id":6049,"depth":154,"text":6050},{"id":6070,"depth":154,"text":6071},{"id":6077,"depth":154,"text":6077},{"id":6083,"depth":140,"text":6083},{"id":6107,"depth":140,"text":6107},{"path":6217,"title":6218,"description":6219,"docType":8,"resourceKind":9,"categoryId":6220,"categoryLabel":6221,"updatedAt":12,"publishedAt":12,"icon":6222},"\u002Fdocs\u002Fcss-tricks","CSS 实用技巧","现代 CSS 特性、布局技巧、动画、暗色模式与常用代码片段","programming-languages","编程语言","i-carbon-application",{"path":6091,"title":6092,"description":6224,"docType":8,"resourceKind":9,"categoryId":10,"categoryLabel":11,"updatedAt":12,"publishedAt":12,"icon":13},"Model Context Protocol 概念、服务器配置、常用 MCP 服务器与自定义开发",[6226,6227,6228],"希望把零散经验整理成长期可复用工作流的人","正在使用 AI 工具、Agent 或自动化工作流的人","希望阅读时顺手建立自己的操作清单或收藏体系的人",[6230,6231,6232],"先浏览标题、摘要和目录，带着问题阅读会更高效","确认模型供应商、API Key、CLI 工具链与本地资源是否已准备好","如果页面里提到相关文档，尽量一起打开对照，效果通常更完整",[6234,6239,6243,6247],{"path":6235,"title":6236,"description":6237,"docType":8,"resourceKind":9,"categoryId":10,"categoryLabel":11,"updatedAt":6238,"publishedAt":6238,"icon":13},"\u002Fdocs\u002Fskills-guide","AI Agent Skills 指南","理解 skills 的作用、目录结构、编写方式，以及它与 MCP 的关系","2026-03-08",{"path":6240,"title":6241,"description":6242,"docType":8,"resourceKind":9,"categoryId":10,"categoryLabel":11,"updatedAt":12,"publishedAt":12,"icon":13},"\u002Fdocs\u002Fai-local-models","本地 AI 模型部署","Ollama、LM Studio、vLLM 本地大模型运行与 API 调用",{"path":6244,"title":6245,"description":6246,"docType":8,"resourceKind":9,"categoryId":10,"categoryLabel":11,"updatedAt":12,"publishedAt":12,"icon":13},"\u002Fdocs\u002Flocal-llm-deployment","本地 LLM 部署指南","使用 Ollama、vLLM、LM Studio 在本地运行大语言模型",{"path":6103,"title":6104,"description":6248,"docType":8,"resourceKind":9,"categoryId":10,"categoryLabel":11,"updatedAt":12,"publishedAt":12,"icon":13},"Cursor Rules、Claude Projects、Kiro Steering 等 AI 编程助手的规则与上下文配置",1776215713430]