跳到主要内容

MCP Server 开发实战

问题

如何从零开发一个 MCP Server?TypeScript 和 Python SDK 怎么用?

答案

一、开发流程

二、TypeScript 完整示例

以下实现一个天气查询 MCP Server:

npm install @modelcontextprotocol/sdk zod
weather-server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

// 1. 创建 Server 实例
const server = new McpServer({
name: "weather-server",
version: "1.0.0",
});

// 2. 注册 Tool
server.tool(
"get_weather", // 工具名称
"获取指定城市的天气信息", // 描述(模型据此决定是否调用)
{
city: z.string().describe("城市名称"), // 参数 Schema(Zod)
unit: z.enum(["celsius", "fahrenheit"]).default("celsius"),
},
async ({ city, unit }) => {
// 3. 实现逻辑
const weather = await fetchWeather(city, unit);

return {
content: [
{
type: "text",
text: `${city} 当前天气:${weather.temp}°${unit === "celsius" ? "C" : "F"}${weather.condition}`,
},
],
};
}
);

// 4. 注册 Resource
server.resource(
"weather://cities",
"支持查询的城市列表",
async (uri) => ({
contents: [
{
uri: uri.href,
mimeType: "application/json",
text: JSON.stringify(["北京", "上海", "广州", "深圳"]),
},
],
})
);

// 5. 启动 Server(stdio 传输)
const transport = new StdioServerTransport();
await server.connect(transport);

三、Python 完整示例

pip install mcp
weather_server.py
from mcp.server.fastmcp import FastMCP

# 1. 创建 Server
mcp = FastMCP("weather-server")

# 2. 注册 Tool(装饰器语法)
@mcp.tool()
async def get_weather(city: str, unit: str = "celsius") -> str:
"""获取指定城市的天气信息

Args:
city: 城市名称
unit: 温度单位(celsius 或 fahrenheit)
"""
weather = await fetch_weather(city, unit)
symbol = "°C" if unit == "celsius" else "°F"
return f"{city} 当前天气:{weather['temp']}{symbol}{weather['condition']}"

# 3. 注册 Resource
@mcp.resource("weather://cities")
async def list_cities() -> str:
"""支持查询的城市列表"""
return json.dumps(["北京", "上海", "广州", "深圳"])

# 4. 注册 Prompt
@mcp.prompt()
async def weather_report(city: str) -> str:
"""生成天气报告的 Prompt 模板"""
return f"请查询 {city} 的天气信息,并生成一份简要的天气报告。"

# 5. 启动
mcp.run(transport="stdio")

四、配置到 Claude Desktop

claude_desktop_config.json
{
"mcpServers": {
"weather": {
"command": "node",
"args": ["/path/to/weather-server.js"],
"env": {
"API_KEY": "your-api-key"
}
}
}
}

五、错误处理

server.tool("risky_operation", "可能失败的操作", {}, async () => {
try {
const result = await doSomething();
return {
content: [{ type: "text", text: result }],
};
} catch (error) {
// 返回错误信息而非抛异常
return {
content: [{ type: "text", text: `操作失败:${error.message}` }],
isError: true, // 标记为错误
};
}
});

六、调试技巧

# 使用 MCP Inspector 调试
npx @modelcontextprotocol/inspector node ./weather-server.js

MCP Inspector 提供 Web UI,可以:

  • 查看 Server 注册的 Tools/Resources/Prompts
  • 手动调用工具并查看响应
  • 查看 JSON-RPC 消息日志

常见面试问题

Q1: MCP Server 开发有哪些最佳实践?

答案

  1. 工具命名:使用 动词_名词 格式(query_databasesend_email
  2. 描述精确:模型根据 description 决定是否调用,要具体说明用途和限制
  3. Schema 完整:类型、枚举、必填字段都要定义,减少模型幻觉
  4. 幂等性:工具调用应尽量幂等,防止重复执行问题
  5. 错误处理:用 isError: true 返回错误,不要抛未捕获异常

Q2: TypeScript SDK 和 Python SDK 有什么区别?

答案

  • TypeScript SDK:使用 Zod schema 定义参数,McpServer + server.tool() API
  • Python SDK:使用 FastMCP 高级 API,装饰器语法更简洁(@mcp.tool()
  • Python SDK 的参数 schema 自动从函数签名 + docstring 推断,开发体验更好
  • 两者功能完全对等

相关链接