MCP 协议开发指南:我用它给 AI 接上了公司的所有内部工具
先解释一下 MCP 是什么
MCP,全称 Model Context Protocol,是 Anthropic 开源的一套协议。用来解决什么问题?
一句话:让 AI 能调用你的工具。
再具体一点:你公司的 Jira、数据库、GitLab、Slack、内部 API——这些工具 AI 本来调不了。MCP 就是在这中间搭了座桥,让 AI 能像调用函数一样调用这些工具。
举个例子。没有 MCP:你说"帮我查一下 bug #1234 的状态",AI 说"我查不了"。有 MCP:AI 直接调 Jira API,查到结果,告诉你"bug #1234 是 Open 状态,assign 给张三,优先级 P0"。
这玩意儿我花了两周时间接入公司内部系统,踩了不少坑。今天把完整流程写出来。
MCP 的核心概念
MCP 有三个角色:
Host(宿主):运行 AI 的地方——Cursor、Claude Desktop、Codex。
Client(客户端):Host 内部的 MCP 客户端,负责管理连接。
Server(服务端):你写的工具暴露层。每个 Server 暴露一组 Tool。
交互流程:
1. Host 启动时,Client 连接所有配置的 Server
2. AI 需要调用工具时,Client 把请求转发给对应 Server
3. Server 执行工具,返回结果
4. AI 根据结果继续推理
说白了:Server 是翻译官,把"AI 想做的事"翻译成"工具能执行的命令"。
实战:给 AI 接上 Jira
我第一个接的是 Jira。效果:AI 能查 bug、建 issue、评论、改状态。
Step 1:写 Server
# jira_server.py
from mcp.server import Server, Tool
from mcp.types import TextContent
import requests
server = Server("jira-server")
@server.tool()
async def get_issue(issue_key: str) -> list[TextContent]:
"""Get Jira issue details by key"""
resp = requests.get(
f"https://your-domain.atlassian.net/rest/api/3/issue/{issue_key}",
auth=("email@company.com", JIRA_API_TOKEN)
)
issue = resp.json()
summary = issue["fields"]["summary"]
status = issue["fields"]["status"]["name"]
assignee = issue["fields"]["assignee"]["displayName"]
return [TextContent(
type="text",
text=f"Issue {issue_key}: {summary}\nStatus: {status}\nAssignee: {assignee}"
)]
@server.tool()
async def create_issue(project: str, summary: str, description: str) -> list[TextContent]:
"""Create a new Jira issue"""
resp = requests.post(
f"https://your-domain.atlassian.net/rest/api/3/issue",
auth=("email@company.com", JIRA_API_TOKEN),
json={
"fields": {
"project": {"key": project},
"summary": summary,
"description": {"type": "doc", "version": 1,
"content": [{"type": "paragraph", "content": [{"type": "text", "text": description}]}]},
"issuetype": {"name": "Bug"}
}
}
)
key = resp.json()["key"]
return [TextContent(type="text", text=f"Created issue {key}")]Step 2:配置 Cursor
在项目根目录创建 .cursor/mcp.json:
{
"mcpServers": {
"jira": {
"command": "python3",
"args": ["/path/to/jira_server.py"],
"env": {
"JIRA_API_TOKEN": "your-token"
}
}
}
}重启 Cursor,AI 就能调 Jira 了。
Step 3:实测
我说:"查一下 PROJ-456 的状态,如果是 Open 就 assign 给我,然后创建一个子任务。"
AI 的执行:
1. 调 get_issue("PROJ-456") → 发现是 Open,assignee 为空
2. 调 assign_issue("PROJ-456", "我") → 分配成功
3. 调 create_subtask("PROJ-456", "修复登录超时问题") → 创建成功
大概 30 秒。如果手动操作,光 Jira 页面就得打开三个标签页。
踩坑记录
坑 1:Server 启动失败,日志很难找
MCP Server 是子进程,崩溃了不会在主界面显示错误。排查方法:
- 在 Cursor 设置里开 MCP 调试日志
- Server 代码里加 try/except 把错误写到文件
坑 2:Tool 描述写不好,AI 调不对
AI 根据 Tool 的 docstring 决定调哪个。如果你的 docstring 写"处理数据",AI 不知道什么时候该调用。
正确的写法:"Get Jira issue details by key. Returns summary, status, and assignee."
坑 3:认证信息泄露风险
API token 写在配置文件里,会被 AI 读到。解决方案:用环境变量,不要硬编码。MCP 的 env 字段就是干这个的。
坑 4:并发问题
同时开了 3 个 MCP Server,偶尔会互相阻塞。原因是 Python 的全局解释器锁(GIL)。解决方案:每个 Server 用独立进程,或者用异步框架。
什么时候该用 MCP?
适合 MCP 的场景:
- 企业内部的工具集成(Jira、GitLab、数据库)
- 需要多步骤工具调用的复杂工作流
- 团队共享的工具集
不适合 MCP 的场景:
- 简单的单次 API 调用(直接用 Function Calling)
- 临时性的实验(写个脚本更快)
最后
MCP 的价值不在于技术本身——协议很简单。价值在于"标准化"。
在 MCP 之前,每个 AI 工具都有自己的插件机制。Cursor 有 Cursor 的方式,Claude Desktop 有 Claude 的方式,Codex 有 Codex 的方式。开发者要给每个工具写一遍集成。
MCP 统一了这个协议。写一次 Server,所有支持 MCP 的工具都能用。
说实话,这才是 AI 工具该有的样子——不是封闭的孤岛,而是开放的生态。
#MCP #AI开发 #工具集成 #Claude #Cursor
读者评论 5