MCP Server 入门开发 + 协议调试 + 生产级部署
从 Hello World 到实用 Server 的距离
第 02 篇的 demo server 能运行,但只有echo和add两个玩具工具。生产级 Server 需要解决 5 个额外的工程问题:
- 多个工具如何协作,共享数据
- 用户输入如何验证(LLM 也会传错参数)
- 工具执行失败时如何正确返回错误
- 日志写到哪里(写错地方会破坏协议)
- Resources 如何让 LLM 获取上下文数据
Demo 是一个完整的 Jira Server,内置 mock 数据,不需要真实账号就能运行。
Server 结构总览
demo_jira_server.py 工具(4 个): search_issues(query, project?, status?, max_results?) get_issue(issue_key) create_issue(project, summary, description?, priority?, issue_type?) update_issue(issue_key, status?, assignee?, priority?) 资源(1 个): jira://projects → 项目列表(LLM 读取后知道有哪些合法 project key) Prompts(1 个): bug_analysis → Bug 分析报告模板模式 1:多工具协作
4 个工具共享同一个内存数据存储ISSUES,形成完整的读写闭环:
# 共享的数据层(生产环境对应真实数据库/API)ISSUES:dict[str,dict]={"PROJ-101":{"key":"PROJ-101","summary":"NullPointerException in parseInput() when config is null","status":"Open","priority":"P1","issue_type":"Bug",...},...}# search_issues:查询# get_issue:精确读取# create_issue:写入新 Issue(递增 ID)# update_issue:修改已有 Issue设计决策:把验证逻辑提取为共用函数validate_issue_key(),get_issue和update_issue都调用它,不重复写:
defvalidate_issue_key(key:str)->str|None:"""Return error message if key is invalid, None if valid."""ifnotkeyor"-"notinkey:returnf"Invalid issue key format: '{key}'. Expected format: PROJECT-123"project=key.split("-")[0]ifprojectnotinPROJECTS:returnf"Unknown project: '{project}'. Available projects:{', '.join(PROJECTS)}"