面向开发者 2026年7月21日 · 8 分钟阅读

如何构建 MCP Server:开发者指南

从选择 SDK、定义第一个 tool,到选择传输方式、在真实 Agent 接入之前完成测试 —— 从一个空文件夹到一个可用的 MCP Server 的实操步骤。

摘要

构建一个 MCP Server 主要就是三件事:注册一个名称和描述清晰的 tool,选一种传输方式(本地用 stdio,远程用 Streamable HTTP),再用官方的 MCP Inspector 测试一遍,然后才把真实 Agent 接上来。官方 SDK 覆盖十种语言,共用同一套 conformance 测试,所以语言的选择反而不是重点,真正重要的是 tool 本身的设计 —— 范围窄、描述清楚、数量少,远胜过一个试图什么都做的"万能" tool。本文会带着一份可运行的代码示例,逐步讲清楚每一步,以及大多数教程会跳过的传输方式和设计取舍。

你真的需要自己build一个吗?

在写任何代码之前,先确认一下你打算build的 Server 是不是已经有人做过了。截至 2026 年年中,公开注册表追踪到的 MCP Server 数量约为 9,400 个,仅四个月内就增长了 38%,2025 年底时这个数字还只是约 6,800(Digital Applied,2026)。对于常见类别 —— CRM、数据库、搜索、日历 —— 已经存在兼容 Server 的概率很高,直接接入只需几分钟,而不是几天。如果你想先了解协议本身,《什么是 MCP Server?》完整讲解了它是如何运作的;本文假设你已经知道 MCP Server 是什么、想要自己build一个 —— 通常是因为你要暴露的是某些专有的东西:一个内部 API、一份特定的数据、一个商品目录,是公开生态里目前还没有覆盖到的。

选择语言和 SDK

MCP 并不绑定某一种语言。Model Context Protocol 组织由 Linux Foundation 治理,官方维护着 TypeScript、Python、Java、Kotlin、C#、Go、PHP、Ruby、Rust、Swift 十种语言的 SDK,全部基于同一套 conformance 测试构建 —— 用其中任何一种语言写出来的 Server,说的都是完全相同的协议。实践中,大多数新建的 Server 用 Python 或 TypeScript 编写,主要是因为两者都提供了高层的、基于装饰器的 API,几行代码就能把一个普通函数变成一个描述完整的 MCP tool。如果你现有的后端已经是 Java、Go 或 Rust,没有任何协议层面的理由要求你为了加一个 MCP Server 就换语言 —— 适合你技术栈的 SDK 早就存在了。

一个 Server 能暴露的三种东西

MCP Server 暴露的是三种基本单元的某种组合 —— tools(Agent 可以调用的函数)、resources(Agent 可以读取的数据)、prompts(可复用的指令模板)。《什么是 MCP Server?》对这三者有更完整的讲解;实际情况是,绝大多数 Server —— 包括你即将build的这个 —— 几乎只暴露 tools,因为这才能让 Agent 真正采取行动,而不只是读取一段静态数据。

一步步build一个最小可用的 Server

一个最小 Server 的结构在各语言 SDK 之间基本一致:创建一个 Server 实例,注册一个或多个 tool,然后运行它。下面是用官方 Python SDK 的高层 API 写出的一份完整、可运行的示例:

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("product-search")

@mcp.tool()
async def search_products(query: str, max_price: float | None = None) -> str:
    """Search for purchasable products matching a query.

    Args:
        query: What the user is looking for, e.g. "wireless earbuds"
        max_price: Optional upper price bound in USD
    """
    results = await run_search(query, max_price)
    return format_results(results)

if __name__ == "__main__":
    mcp.run(transport="stdio")

这里真正起作用的有四处:@mcp.tool() 装饰器,它注册这个函数,并从类型注解自动生成 JSON schema;docstring,它会成为这个 tool 的描述 —— 也就是 Agent 真正会读、用来判断何时调用它的那段文字;类型注解,定义了哪些参数是必填、哪些是可选;以及 mcp.run(),它会让 Server 以你选定的传输方式启动监听。运行起来,它就是一个可用的 MCP Server 了。本文接下来要讲的,是如何让它好到真正可以上线。

选择传输方式:stdio 还是 Streamable HTTP

一个 MCP Server 只需要选定一种传输方式,而这个决定主要取决于谁会来调用它。stdio —— Server 作为本地子进程运行,通过标准输入/输出与唯一的客户端通信 —— 是任何由单个用户在本地运行的场景的默认选择,比如 Claude Desktop 或某个 CLI Agent。上面的示例用的就是它,也是从零到一个可用 Server 最快的路径。

对于任何远程场景 —— 别人的 Agent 会通过网络连接的 Server —— 当前的标准是 Streamable HTTP,它在 2025-03-26 的协议修订版本中引入,并延续到了 2025 年 11 月的修订版本中。它用单一端点取代了最初 2024-11-05 版协议中那种双端点的 HTTP+SSE 传输方式:客户端通过 POST 发送 JSON-RPC 消息,Server 要么直接返回结果,要么将响应升级为 Server-Sent Events 流以处理耗时较长的调用。HTTP+SSE 目前已被正式标记为弃用 —— 各平台都在按真实的截止日期下线它(比如 Atlassian 的 Rovo MCP Server 就在 2026-06-30 下线了它)—— 所以在 2026 年,已经没有太多理由再基于它去build一个新的远程 Server。如果你的 Server 需要同时服务多个客户端,从第一天起就直接基于 Streamable HTTP 来build。

在别人之前先测试它

在把真实 Agent 接到你的 Server 之前,先用 MCP Inspector 测试一下 —— 这是与各语言 SDK 一起维护的官方可视化测试工具,GitHub 星标超过 10,000。对着你的 Server 运行 npx @modelcontextprotocol/inspector,它会打开一个浏览器界面,直接调用 tools/listtools/call,让你看到 Agent 实际会看到的完整 schema,并用测试参数手动触发每一个 tool,而不必等自动化流程来验证。它能在几分钟内帮你发现大多数会让人尴尬的 bug —— 缺失的描述、和函数签名对不上的 schema、抛出异常而不是返回可用错误信息的 tool —— 而不是等一个困惑的 Agent 自己"脑补"出各种绕过方式之后才发现。

设计出 Agent 真的会正确调用的 tool

一个能跑起来的 Server,和一个 Agent 能用好的 Server,是两回事。有几件事比看上去更重要:

  • docstring 是写给模型看的,不是写给同事看的。Agent 判断是否调用一个 tool,几乎完全依据它的名称和描述 —— 像"处理商品相关事务"这样模糊的措辞,比一句带具体例子的精确描述,更容易被跳过或用错。
  • 一个 tool,一件事。一个 manage_products tool 如果靠一个 action 参数("search"、"create"、"delete")来区分行为,会迫使 Agent 去猜正确的参数组合;三个各自职责清晰、边界明确的独立 tool,反而更容易被模型正确选中。
  • 用结构化方式失败,而不是抛异常。返回一段清晰、可读的错误字符串或对象,而不是让未处理的异常直接让调用崩溃 —— 如果 Agent 能理解出了什么问题,它往往可以换一种方式重试并恢复。
  • 参数数量尽量少。每一个参数都需要 Agent 从对话中正确推断出来;两三个命名清晰的参数,几乎总是比一个八个字段的配置对象表现更好。

这些道理并非 MCP 独有 —— 和写好一个 REST API 需要的是同一套纪律 —— 只是在这里更重要,因为不会有人先读文档再发起第一次调用。

上线:部署并被发现

一旦它能正常工作、在 Inspector 里测试通过,就可以像部署其他任何长期运行的进程或 HTTP 服务一样部署它 —— 容器、带持久端点的 serverless 函数,用你团队已经在用的方式即可。真正 MCP 特有的一步是"被找到":把它提交到官方 MCP Registry(registry.modelcontextprotocol.io),并为了触达更多开发者,同时登记到 PulseMCP、Smithery 这类社区目录 —— 大多数开发者实际上都是通过这些渠道找到可以接入的 Server,而不是自己一个个去翻 GitHub。

IntentLink 在其中扮演什么角色

IntentLink 自己的 Server 就是上述大部分实践在生产环境中的真实案例:它基于 Streamable HTTP 搭建,只暴露少量范围清晰的 tool(search_productssearch_travel),而且每条返回结果都已经附带一个可直接使用、可跟踪的购买链接 —— 所以一次 tool 调用可以直接走向真实交易,而不只是给出一个建议。如果你正在为自己的产品build一个 Server,又想在不自己搭建整套联盟营销集成的情况下把商业化能力加进去,这篇快速上手指南用几分钟讲清楚了如何通过 MCP 或 REST 接入。

常见问题

我build第一个 MCP Server 该用什么语言?

大多数情况下选 Python 或 TypeScript —— 两者都有高层 SDK(比如 Python 里 FastMCP 风格的装饰器),几行代码就能把一个普通函数变成描述完整的 tool。如果你团队现有的后端是 Java、Go、C#、Kotlin、Rust、Swift 或 PHP,直接用那个语言就好;Model Context Protocol 官方为每一种都维护了 SDK,它们说的是完全相同的协议。

我需要用 FastMCP 或其他框架吗,还是官方 SDK 就够了?

官方 SDK 对几乎所有 Server 来说都已经够用。像 FastMCP 这样的高层封装其实就在官方 Python SDK 内部,而不是一个独立的第三方依赖 —— 它是那套基于装饰器的 API(@mcp.tool()),而不是 SDK 之外的另一个选项。

我该用 stdio 还是 Streamable HTTP?

凡是由单个用户或单个客户端在本地运行的场景,比如某个 CLI Agent 或 Claude Desktop,用 stdio。凡是需要多个客户端通过网络连接的远程场景,用 Streamable HTTP —— 它是当前的标准,取代了 MCP 最初 2024-11-05 版协议中已被弃用的 HTTP+SSE 传输方式。

在接入真实 Agent 之前,我该怎么测试一个 Server?

对着它运行 MCP Inspector(npx @modelcontextprotocol/inspector)。这是官方的测试工具,会给你一个浏览器界面,直接调用 tools/listtools/call,让你在任何 Agent 真正接入之前,先验证 schema、用测试参数试一遍每个 tool。

一个 Server 应该暴露多少个 tool?

按实际需要,越少越好。范围窄、职责单一的 tool 比一个靠 mode 参数区分行为的"万能" tool 更容易被模型正确选中 —— 大多数设计得好的 Server 只暴露几个 tool,而不是几十个。

我该在哪里发布 MCP Server,好让 Agent 能找到它?

提交到官方 MCP Registry(registry.modelcontextprotocol.io),并登记到 PulseMCP、Smithery 这类社区目录以获得更广泛的曝光 —— 大多数开发者都是通过这些渠道找到可以接入的 Server,而不是逐个去搜索。

正在构建 Agent? 几分钟内即可上线你的第一个变现意图。

资料来源:Digital Applied,《MCP Ecosystem H1 2026 Retrospective: Adoption Data Points》(2026);Model Context Protocol 官方规范与 SDK 文档,modelcontextprotocol.io(2026)。

继续阅读