从零实现一个 MCP:原理、常见实现方式与实战
1. MCP 是什么?
MCP,全称 Model Context Protocol(模型上下文协议)。
它解决的问题很简单:
让 AI 使用统一的方式调用外部工具和数据。
比如 AI 想访问:
数据库
文件系统
GitHub
搜索引擎
公司内部 API
订单系统
以前每个平台都需要单独开发适配器。
有了 MCP 后:
LLM
↓
MCP Client
↓
MCP Server
↓
数据库 / API / 文件 / GitHub
可以简单理解为:
MCP 是 AI 与外部系统之间的标准接口。
2. MCP 的三个角色
MCP 主要有三个角色:
Host
Client
Server
Host
AI 应用本身,例如:
AI IDE
Agent
桌面 AI 应用
企业 AI 助手
Client
负责和 MCP Server 通信。
Server
真正提供能力。
例如:
MySQL MCP Server
GitHub MCP Server
Filesystem MCP Server
Order MCP Server
整体结构:
User
↓
LLM
↓
Host
↓
MCP Client
↓
MCP Server
↓
业务系统
3. MCP 最重要的三个能力
一个 MCP Server 最核心的是:
Tools
Resources
Prompts
Tool
Tool 用来执行操作。
例如:
get_user
search_order
create_order
send_email
可以理解为给 AI 调用的函数。
Resource
Resource 用来读取数据。
例如:
config://application
users://1001/profile
docs://readme
它更像:
文件
数据库记录
配置
文档
知识
Prompt
Prompt 是服务器提供的提示词模板。
例如:
/code_review
/analyze_user
/generate_report
简单记:
Tool = 做事情
Resource = 读数据
Prompt = 提示模板
4. 最简单的 Python MCP Server
安装:
pip install "mcp[cli]"
创建:
server.py
代码:
from mcp.server import MCPServer
mcp = MCPServer("demo")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
if __name__ == "__main__":
mcp.run()
这样就已经实现了一个 MCP Server。
核心就在:
@mcp.tool()
SDK 会自动根据:
def add(a: int, b: int) -> int
生成 Tool 的参数 Schema。
模型就能知道:
工具叫什么
工具有什么作用
需要什么参数
参数是什么类型
5. 再增加 Resource
@mcp.resource("config://application")
def get_config() -> str:
return """
app=demo
env=production
"""
动态 Resource:
@mcp.resource("users://{user_id}/profile")
def user_profile(user_id: str) -> str:
return f"User ID: {user_id}"
于是客户端可以访问:
users://1/profile
users://100/profile
6. 再增加 Prompt
@mcp.prompt()
def analyze_user(user_id: str) -> str:
return f"""
Analyze user {user_id}.
Focus on:
- status
- activity
- risk
"""
这样一个 Server 就同时拥有:
MCP Server
│
├── Tools
├── Resources
└── Prompts
7. MCP 常见实现方式
实际开发中,常见有几种。
方式一:stdio
适合本地程序。
AI Client
↕
stdio
↕
MCP Server
适合:
本地文件
Git
IDE
本地数据库
开发工具
优点:
简单
不用端口
不用部署 HTTP 服务
方式二:Streamable HTTP
适合远程服务。
AI Client
↓
HTTPS
↓
MCP Server
↓
业务系统
例如:
https://mcp.example.com/mcp
适合:
企业服务
云服务
SaaS
多人共享 MCP
Kubernetes
简单来说:
本地 MCP → stdio
远程 MCP → Streamable HTTP
8. TypeScript 实现 MCP
Node.js 项目也可以直接使用官方 SDK。
npm install @modelcontextprotocol/server
npm install zod
示例:
import { McpServer } from "@modelcontextprotocol/server";
import { serveStdio } from "@modelcontextprotocol/server/stdio";
import * as z from "zod/v4";
function createServer() {
const server = new McpServer({
name: "demo",
version: "1.0.0",
});
server.registerTool(
"add",
{
description: "Add two numbers",
inputSchema: z.object({
a: z.number(),
b: z.number(),
}),
},
async ({ a, b }) => ({
content: [
{
type: "text",
text: String(a + b),
},
],
}),
);
return server;
}
void serveStdio(createServer);
Python 和 TypeScript 思路本质是一样的:
注册 Tool
↓
定义 Schema
↓
MCP Client 发现
↓
LLM 调用
9. 企业项目最常见:把现有 API 包成 MCP
实际公司一般已经有:
User API
Order API
Payment API
Search API
没有必要重新写业务。
直接:
LLM
↓
MCP Server
↓
REST API
↓
现有业务系统
例如:
@mcp.tool()
async def get_order(order_id: str) -> dict:
"""Get order details."""
response = await http_client.get(
f"http://order-service/orders/{order_id}"
)
return response.json()
所以 MCP 很适合充当:
AI Adapter 层。
10. 数据库 MCP 不要直接暴露 SQL
一个常见错误是:
@mcp.tool()
def execute_sql(sql: str):
...
这等于让模型随便执行 SQL。
更合理的是:
@mcp.tool()
def get_user(user_id: int):
...
@mcp.tool()
def search_orders(status: str):
...
@mcp.tool()
def get_sales_summary():
...
原则是:
不要暴露数据库能力,要暴露业务能力。
11. Tool 怎么设计非常重要
MCP 最难的其实不是代码。
而是:
怎么设计一个让 LLM 容易理解的 Tool。
不要设计:
invoke_user_service
execute_api
operate_order
推荐:
get_user
search_orders
create_order
cancel_order
Tool 名称应该:
简单
明确
表达动作
Description 也非常重要。
差:
"""Search orders."""
更好:
"""
Search orders by order number,
customer name or product name.
Use this when the exact order ID
is unknown.
"""
因为 Tool Description 实际上也是给 LLM 看的说明书。
12. MCP 项目推荐分层
不要所有代码都放一个文件。
推荐:
mcp-server/
│
├── server.py
│
├── tools/
│ ├── users.py
│ └── orders.py
│
├── resources/
│
├── prompts/
│
├── services/
│ ├── user_service.py
│ └── order_service.py
│
└── clients/
└── api_client.py
其中:
Tools
↓
Services
↓
API / Database
Tool 层尽量保持简单:
@mcp.tool()
async def get_user(user_id: int):
return await user_service.get_user(user_id)
不要把几百行业务逻辑直接写进 Tool。
13. 生产环境架构
企业环境可以设计成:
AI Application
│
▼
MCP Client
│
HTTPS
│
▼
API Gateway
│
▼
MCP Server
│
┌──────────┼──────────┐
▼ ▼ ▼
User API Order API Search API
Gateway 可以统一处理:
鉴权
限流
日志
审计
监控
权限
MCP Server 主要负责:
Tool 定义
Schema
参数验证
协议转换
结果格式化
业务逻辑继续留在原来的 Service 中。
14. 一定注意权限问题
MCP Tool 是 AI 调用的。
但:
AI 不能决定权限。
例如:
delete_user
cancel_order
send_payment
deploy_production
Server 必须正常执行:
Authentication
↓
Authorization
↓
Policy Check
↓
Tool Execution
尤其是:
删除
支付
退款
部署
修改数据
这类 Tool,最好加入用户确认。
15. MCP 和 Agent 不是一回事
这个概念一定要分清。
MCP 负责:
提供工具和数据。
Agent 负责:
思考
选择 Tool
调用 Tool
读取结果
继续推理
完整过程:
User
↓
LLM
↓
需要查订单
↓
MCP Client
↓
search_order
↓
MCP Server
↓
Order API
↓
结果
↓
LLM
↓
最终回答
所以:
MCP ≠ Agent
更准确的是:
LLM
+
Agent Loop
+
MCP
+
业务系统
16. 最终总结
实现 MCP 最核心的东西其实并不多。
首先理解:
Tool → 执行动作
Resource → 提供数据
Prompt → 提供提示模板
然后选择通信方式:
本地:
Client
↕
stdio
↕
Server
远程:
Client
↕
Streamable HTTP
↕
Server
企业里最常见的架构则是:
LLM
↓
MCP
↓
现有 REST / RPC 服务
↓
Database
所以可以把 MCP Server 理解成:
专门为 AI 设计的一层 API。
普通 API 主要考虑:
程序员怎么调用。
MCP Tool 除此之外还必须考虑:
LLM 能不能理解?
LLM 能不能选对 Tool?
参数能不能填对?
调用是否安全?
这才是 MCP 真正值得研究的地方。
如果刚开始学 MCP,推荐按照:
写一个 Tool
↓
stdio 跑起来
↓
增加 Resource
↓
增加 Prompt
↓
接已有 REST API
↓
Streamable HTTP
↓
鉴权和生产部署
逐步学习。
等这一套跑通以后,再研究 MCP 底层 JSON-RPC、Gateway、异步 Task 等高级能力,会容易很多。