TellWorldAI 世界档案
问档案English

首页›实践›实践

实践

从零写一个 MCP server

从零写一个 MCP 服务端(server):分清工具、资源和提示三种能力,选好传输方式,用调试器检查,再接入 Claude Desktop 和 Claude Code。

这篇适合谁

想通过 Model Context Protocol(MCP)让 AI 应用访问自己的数据或工具的开发者。需要会在终端里执行命令,并能写几行 Python 或 TypeScript。读完你应该理解 MCP server 对外暴露什么,能在本地跑起一个 server,用调试工具检查它,并把它接到一个客户端上。

MCP server 暴露什么

MCP server 是通过标准协议向 AI 应用暴露特定能力的程序。它的功能由三种基本构件提供:Tools、Resources 和 Prompts [2]。三者的区别在于由谁决定何时使用。

Tools 是 LLM 可以主动调用的函数。LLM 根据用户的请求判断何时使用。工具可以写数据库、调用外部 API、修改文件,或者触发其他逻辑 [2]。每个工具只完成一项操作,输入和输出都有明确定义,MCP 使用 JSON Schema 来校验它们 [2]。

Resources 是被动的数据源,提供只读的信息供上下文使用,例如文件内容、数据库结构或 API 文档。何时使用由应用决定 [2]。每个资源都有唯一的 URI,例如 file:///path/to/document.md,并声明自己的 MIME 类型。资源支持两种发现方式:URI 固定的直接资源,以及 URI 动态的资源模板(Resource Templates)[2]。

Prompts 是预先写好的指令模板,告诉模型去使用特定的工具和资源。它由用户控制,需要明确调用,不会自动触发 [2]。

当前协议版本是 2026-07-28 [5],每个请求都在 _meta 里声明它。

选择传输方式

MCP 有两种传输机制 [3]。stdio 把 server 作为本地进程运行,通过标准输入输出与它通信,没有网络开销,适用于同一台机器上的进程之间 [3]。Streamable HTTP 用 HTTP POST 发送客户端到服务端的消息,并可选择使用 Server-Sent Events,适用于远程 server。它支持标准的 HTTP 认证方式,包括 bearer token、API key 和自定义请求头;MCP 推荐用 OAuth 获取认证令牌 [3]。

有一条规则会让几乎所有第一次写 server 的人踩坑:stdio 类型的 server 绝不能写 stdout,否则会破坏 JSON-RPC 消息。TypeScript server 应使用 console.error(),Python server 应使用标准库的 logging 模块,它们都写到 stderr。基于 HTTP 的 server 则可以把日志写到 stdout [1]。

安装 SDK

官方 SDK 页面按功能完整度、协议支持和维护承诺把 SDK 分级,TypeScript 和 Python 都属于第一级 [4]。

Python SDK 要求 Python 3.11 或更新版本,支持 stdio、Streamable HTTP 和 SSE 三种传输 [8]。用 uv add "mcp[cli]" 或 pip install "mcp[cli]" 安装。cli 附加项会加入 mcp 命令行工具,提供 mcp dev、mcp run 和 mcp install [8]。

TypeScript 方面,稳定包是 @modelcontextprotocol/server 和 @modelcontextprotocol/client,实现 2026-07-28 版规范,可以在 Node.js、Bun 和 Deno 上运行。server 包用 npm install @modelcontextprotocol/server 安装 [9]。

用 Python 写第一个 server

Python SDK 的 README 用大约十五行给出了一个完整的 server [8]:

from mcp.server import MCPServer

mcp = MCPServer("Demo")


@mcp.tool()
def add(a: int, b: int) -> int:
    """Add two numbers."""
    return a + b


@mcp.resource("greeting://{name}")
def greeting(name: str) -> str:
    """Greet someone by name."""
    return f"Hello, {name}!"

add 是一个工具,greeting 是一个资源模板,因为它的 URI 中含有 {name} 参数。两者都是带类型标注和文档字符串的普通函数。这个 server 文件可以用下面的命令调试或通过 HTTP 提供服务 [8]:

uv run mcp dev server.py
uv run mcp run server.py --transport streamable-http

第一条命令在 MCP Inspector 里打开 server,第二条命令通过 HTTP 提供服务 [8]。

用 TypeScript 写第一个 server

官方 TypeScript 教程从 src/index.ts 开始,先写下面这些导入和常量 [1]:

import { McpServer } from "@modelcontextprotocol/server";
import { serveStdio } from "@modelcontextprotocol/server/stdio";
import { z } from "zod";

const NWS_API_BASE = "https://api.weather.gov";
const USER_AGENT = "weather-app/1.0";

这几行分别导入 server 类、stdio 传输和 Zod,两个常量分别是外部 API 的地址和 User-Agent。后面的工具按教程一步步加,不要直接照抄完整文件。

用 MCP Inspector 调试

MCP Inspector 是调试和测试 MCP server 的参考工具。它以单个包 @modelcontextprotocol/inspector 发布,用一个二进制文件提供 Web、CLI 和 TUI 三种客户端 [6]。它要求 Node 22.19.0 或更新版本,通过 npx 运行,不需要单独安装 [6]。

要针对本地 stdio server 打开网页界面,执行 npx @modelcontextprotocol/inspector node path/to/server/index.js [6]。要在命令行里列出 server 的工具,执行 npx @modelcontextprotocol/inspector --cli node path/to/server/index.js --method tools/list [6]。建议先跑第二条。它能证明 server 能正常启动并响应,然后再去接客户端。

接入 Claude Desktop

Claude Desktop 从 claude_desktop_config.json 读取本地 server 配置。这个文件在 macOS 上位于 ~/Library/Application Support/Claude/claude_desktop_config.json,Windows 上位于 %APPDATA%\Claude\claude_desktop_config.json,Linux 上位于 ~/.config/Claude/claude_desktop_config.json [7]。本地 server 放在 mcpServers 键下,包含 command 和 args 数组 [7]。文档中的 macOS 示例把 command 设为 "npx",args 里依次是 -y、@modelcontextprotocol/server-filesystem,以及允许 server 访问的目录 [7]。

接入 Claude Code

Claude Code 有自己的添加 server 命令。添加一个通过 HTTP 访问的远程 server,执行 claude mcp add --transport http claude-code-docs https://code.claude.com/docs/mcp [11]。添加本地 stdio server,执行 claude mcp add playwright -- npx -y @playwright/mcp@latest。-- 分隔符之后的所有内容都会交给 server,本地 server 默认使用 stdio 传输 [11]。

通用语法是 claude mcp add [options] <name> -- <command> [args...]。选项包括用于环境变量的 --env KEY=value,以及用于认证的 --header "Authorization: Bearer your-token" [12]。

用 claude mcp list 或会话中的 /mcp 检查连接 [11]。local 作用范围保存在 ~/.claude.json,project 保存在项目根目录的 .mcp.json,user 保存在 ~/.claude.json 的顶层 mcpServers 键下 [11]。

参考实现

modelcontextprotocol/servers 仓库收集了一批参考实现。其中维护中的参考 server 有 Everything、Fetch、Filesystem、Git、Memory、Sequential Thinking 和 Time [10]。TypeScript 的用 npx 启动,例如 npx -y @modelcontextprotocol/server-memory;Python 的用 uvx 启动,例如 uvx mcp-server-git,或者先 pip install mcp-server-git [10]。

这个仓库里的每个 server 都提供 stdio。只有 Everything 还提供 Streamable HTTP,地址类似 http://localhost:3001/mcp [10]。这些 server 是给开发者自己写 server 时参考的教学示例,不是可以直接上线的方案 [10]。读它们来学习写法,不要原样部署。

限制和常见问题

  • 多余的输出会弄坏 stdio server。 stdio server 绝不能往 stdout 写内容,否则会破坏 JSON-RPC 消息。TypeScript server 用 console.error(),Python server 用标准库的 logging 模块,它们都写到 stderr [1]。

下一步

想深入理解三种构件,读 server 概念页面 [2]。想看完整的 TypeScript server,读构建教程 [1]。Python SDK 的 README 讲解装饰器和 mcp 命令行工具 [8]。Inspector 页面讲解 Web、CLI 和 TUI 三种客户端 [6]。Claude Code 的 MCP 页面讲解作用范围和配置 [11][12]。

来源

  1. 1
    Build an MCP serverModel Context Protocol
  2. 2
    Understanding MCP serversModel Context Protocol
  3. 3
    Architecture overviewModel Context Protocol
  4. 4
    SDKsModel Context Protocol
  5. 5
    VersioningModel Context Protocol
  6. 6
    MCP InspectorModel Context Protocol
  7. 7
    Connect to local MCP serversModel Context Protocol
  8. 8
    MCP Python SDK READMEmodelcontextprotocol (GitHub)
  9. 9
    MCP TypeScript SDK READMEmodelcontextprotocol (GitHub)
  10. 10
    Model Context Protocol servers READMEmodelcontextprotocol (GitHub)
  11. 11
    MCP quickstart (Claude Code)Anthropic (Claude Code Docs)
  12. 12
    MCP (Claude Code)Anthropic (Claude Code Docs)

引用本页: 从零写一个 MCP server. TellWorld, https://www.tellworld.net/zh/practice/practice-mcp-server. 更新于 2026-11-14

相关动态