[控场AI]
· 9 分钟阅读· 4,770 字

MCP服务器是什么?从零构建到生产级部署全解析

MCP服务器是什么?从零构建到生产级部署全解析

MCP服务器本质是向AI暴露标准化工具接口,远程部署时OAuth 2.1认证是生产级产品的必需品。

MCP(模型上下文协议)的核心是为AI模型提供可调用的函数列表——模型本身只能输出文本,工具调用由宿主代码代为执行。MCP作为标准协议解决了"每个应用重复造工具管道"的问题,被比作AI工具的USB-C接口。本地stdio模式适合个人试玩,远程HTTP模式才是真正面向产品的选择。一旦上线,访问控制就成为核心难题:约四分之一的公开MCP服务器完全无认证,静态API密钥也存在无法按用户追溯和撤销的安全隐患。官方规范推荐OAuth 2.1配合PKCE,配合FastMCP框架与现成的身份平台(如Descope),开发者无需从零实现登录、令牌签名等逻辑,即可快速构建支持多用户、细粒度scope权限隔离的生产级MCP服务器。

MCP服务器的本质:给AI一份可调用的函数清单

很多人把MCP(Model Context Protocol,模型上下文协议)讲得云里雾里,但剥开外壳,它其实简单得出奇——MCP服务器就是一个向AI模型提供"允许调用的函数列表"的程序。

理解这一点,先要认清语言模型的天然局限。一个大模型本身什么也做不了:它读不了你的文件、查不了你的日历、也无法访问数据库。它唯一能干的事情就是接收文本、输出文本。所以要让模型"做事",你必须给它工具,而工具本质上就是一个有名字、有描述、有输入输出参数的函数。

关键在于:模型从不直接调用工具。当模型想调用某个工具时,它只是输出一段文本,说明它想调用哪个工具、传什么参数。你的代码接收到这个请求后执行函数,再把结果以文本形式回传给模型。整个过程模型始终在处理文本,所有交互都通过JSON来回传递。

为什么需要一个标准协议

在MCP出现之前,存在一个明显的重复造轮子问题:每个应用都要自己搭建这套工具管道,而且每个模型、每个工具的做法都不一样。你为Claude构建的GitHub工具,在Cursor里用不了,在ChatGPT里也用不了。智能体越来越多,重复劳动也越来越多。

MCP正是为解决这个痛点而生。它的思路是:工具只写一次,做成MCP服务器,任何支持MCP的应用都能直接使用。人们喜欢把它比作"AI工具的USB-C接口",一个插头几乎适配所有设备,这个类比相当贴切。

这里有两个角色需要分清:

  • MCP服务器:你的代码,负责暴露工具。
  • MCP客户端:模型所在的应用,比如Claude Desktop、Cursor,或任何AI智能体。

当客户端启动时,它会问服务器"你有哪些工具",服务器返回一份包含名称和描述的列表交给模型。当模型想调用某个工具时,客户端向服务器发请求,服务器运行函数并返回结果。

这是你可以去登录的地址

本地运行 vs 远程运行

MCP服务器有两种主要运行方式,理解它们的差异对做产品至关重要。

第一种是本地运行。客户端把你的服务器作为子进程启动,运行在你自己的机器上,通过标准输入输出(stdio)直接通信。比如Claude Desktop会执行类似 python myserver.py 的命令,然后把JSON管道输入进去。大约90%的教程都在展示这种方式——用于个人用途很好,但别人需要访问时就完全行不通。

第二种是远程运行。你的服务器跑在互联网上,有一个URL,客户端通过HTTP连接它。几乎所有真正的产品都是这么做的——GitHub、Notion、Stripe的MCP服务器本质上都是一个URL。如果你要为别人构建产品,或想从手机、笔记本、工作电脑等不同设备使用工具,远程才是首选方案。

在实践中,从本地切换到远程其实只需改动很少的代码:把默认的stdio传输方式改成指定transport、host和port,服务器就变成了一个跑在HTTP上的普通服务,用Uvicorn等启动后即可对外提供URL。

这是我的服务器名称

stdio(标准输入输出)是操作系统为进程提供的最基础通信管道:stdin接收输入、stdout输出结果、stderr输出错误。MCP本地模式利用这一机制,让客户端以"父进程"身份启动服务器子进程,双方通过管道传递JSON消息,整个通信过程完全发生在本机内存中,无需网络栈。这种方式配置极为简单,延迟几乎为零,也不存在网络暴露面——但其代价是强绑定:服务器必须和客户端运行在同一台机器上,无法共享给他人,也无法从多台设备访问。远程模式改用HTTP/SSE(Server-Sent Events)或WebSocket传输,将同样的JSON消息结构搬到网络上,换来了可扩展性和多用户支持,但随之引入了认证、TLS加密等网络服务的全套安全课题。

远程部署绕不开的坎:访问控制

一旦MCP服务器上了互联网,一个本地版本从未有过的问题就冒出来了——访问控制。任何拿到URL的人都能调用你的工具,而这些工具会读数据、写数据、甚至删除东西。因此每个请求你都必须回答三个问题:谁在调用?他们被允许做什么?他们代表谁在做?

视频作者提到一个令人震惊的数据:今年的一次安全审计发现,大约四分之一的公开MCP服务器完全没有认证;而在有认证的那些里,大多数使用的是静态API密钥——一个长期有效、所有人共享的密钥。

静态密钥的问题很致命:如果五个不同的智能体用同一个密钥访问服务器,你根本无法区分是哪个用户、哪个智能体做了什么;一旦其中一个被攻破,你无法单独撤销,只能销毁密钥、一次性中断所有智能体。这对短期项目还行,但生产环境绝对不行。

OAuth 2.1:官方规范给出的正确答案

MCP官方规范对此已有解决方案,和所有严肃应用一样:OAuth,具体是OAuth 2.1配合PKCE。听起来吓人,但你几乎永远不需要自己实现它,只需理解它的流程。

最关键的一点是:你的MCP服务器永远不负责登录任何东西。当客户端在没有有效令牌的情况下调用服务器时,服务器只返回401未授权,并附带一个地址——这个地址指向"授权服务器"。用户随后到授权服务器完成登录(用Google、邮箱等你配置的任意方式),看到一个授权确认界面并批准操作。

授权服务器生成一个令牌交给客户端,之后该客户端在每一个请求中都带上这个令牌。你的服务器校验令牌签名、确认它是发给这个特定服务器的、检查令牌里包含哪些权限(术语叫作用域 scope),然后才执行工具。

令牌里通常包含scope、用户ID等信息,这意味着你的服务器可以"代表某个用户"执行操作,从而真正实现多用户扩展。此外,客户端需要先在授权服务器上注册自己,规范里的"动态客户端注册"会自动处理这一步,你无需手动配置。

PKCE(Proof Key for Code Exchange,代码交换证明密钥)是OAuth 2.1的重要配套机制,专门用于防止"授权码拦截攻击"。其原理是:客户端在发起授权请求前,本地随机生成一个"代码验证器"(code_verifier),并对其进行哈希处理得到"代码挑战"(code_challenge);授权服务器完成登录后返回授权码时,会记住这个code_challenge;客户端用授权码换取令牌时,必须同时提交原始code_verifier,服务器验证哈希匹配后才颁发令牌。这样即使授权码在传输中被截获,攻击者因没有code_verifier也无法换取令牌。对于AI智能体这类无法安全存储客户端密钥的"公共客户端",PKCE是保障令牌交换安全性的核心手段,也是OAuth 2.1相比2.0的重要改进之一。

动手实现:用Python和FastMCP构建

构建MCP服务器并没有想象中复杂。你可以引入FastMCP这样的框架(也可以不用框架),框架为你做的核心工作就是确保服务器遵循MCP协议——说到底,我们做的只是一个有固定请求/响应结构的普通API。协议的完整细节可在 modelcontextprotocol.io 查阅。

实操流程大致是:

  1. 用 pip/uv 安装 FastMCP。
  2. 编写普通的Python函数(比如连接Postgres数据库来添加、删除、列出笔记)。
  3. 用 @mcp.tool 装饰器标注这些函数,FastMCP会自动把它们加入可用工具列表。

你只需装饰几个不同的函数

一个实用细节:务必为工具添加文档字符串(docstring)并给参数和返回值加类型提示。docstring会作为工具描述告诉模型这个函数干什么,类型提示则让模型知道该用什么类型的参数调用、会得到什么返回。这两点能显著提升AI模型调用工具的质量。

在Cursor中接入本地服务器,只需进入设置的Tools & MCP,添加自定义配置,指定执行命令(Python用 uv,Node.js用 node)和参数即可。连接成功后,在代理窗口里就能让AI调用"列出笔记\、"添加笔记"、"删除笔记"等工具。

FastMCP是对MCP Python SDK的高层封装,核心设计理念是"约定优于配置":开发者只需编写普通Python函数并加上@mcp.tool装饰器,框架会自动完成工具注册、JSON Schema生成、请求路由和协议握手等底层工作。相比直接使用官方SDK,FastMCP大幅减少了样板代码。值得注意的是,类型提示在这里不仅是代码风格问题,而是有实质意义的——FastMCP会将Python的类型注解(如str、int、list[str])自动转换为JSON Schema中的type字段,模型依赖这份Schema来决定如何构造参数;docstring则直接成为工具的description字段,是模型判断"该不该调用这个工具"的主要依据。因此,写清晰的文档字符串和严格的类型提示,实际上是在直接优化AI的工具选择和调用质量。

集成身份认证:借助现成工具处理OAuth

把服务器改成远程后,前面提到的"无访问控制"问题就必须解决——笔记没有按用户隔离,任何人都能增删。作者选择接入Descope这类提供"代理身份中心(Agentic Identity Hub)"的工具,而非从零实现登录页、授权界面、令牌签名、客户端注册和刷新逻辑。

集成的大致步骤是:

  • 在控制台创建一个MCP服务器,填入服务器URL(注意末尾要带 /mcp)。
  • 定义scope,比如 Notes Read(允许读取)和 Notes Write(允许修改创建)。
  • 拿到授权服务器的 well-known URL,配置进环境变量。
  • 在代码里用SDK创建一个OAuth Provider,传入配置URL、基础URL和支持的scope,挂到FastMCP上。

然后我们有一个

改造后的工具函数会先获取当前用户(从令牌的claims里读取sub/用户ID),再检查用户是否拥有对应scope,从而实现真正的权限隔离——每条笔记都与登录用户关联。

实测效果很直观:用Google账号登录后,Cursor会走完整的OAuth流程,弹出登录页和授权确认界面;授权后即可创建、查询笔记。换一个Google账号登录,就完全看不到第一个账号的笔记,权限隔离生效。控制台里还能直接管理用户、禁用账号,甚至通过Connections把GitHub、Slack、Notion等第三方账号的OAuth也交给平台托管。

小结

MCP的核心其实一句话就能概括:一个向AI暴露标准化工具接口的程序。真正把它做成产品的分水岭不在"如何写工具",而在"如何安全地暴露工具"。本地stdio模式适合个人试玩,远程HTTP模式才面向真实用户;而远程模式一旦上线,OAuth 2.1 + PKCE的认证授权就从"可选项"变成"必需品"。理解协议原理、善用FastMCP这类框架和现成的身份平台,你就能绕开繁琐细节,构建出可扩展、面向多用户的生产级MCP服务器。

分享:

相关推荐