概述
大概是24年开始听说,mcp 协议。刚开始听说时不太感兴趣。主要的原因是太过自然了。往大了说,虽然 mcp 和 rag 的实现细节差距很大,本质上都是从模型外部获取信息和计算能力。这篇blog记录我从mcp server helloworld 到学习其实现的过程。
hello world
使用cursor。通过下面的提示词,生成了一个能计算加减乘除的 mcp server,并直接在 cursor 中使用。
-
写一个 mcp server,提供简单的 加减乘除 计算功能,用python3 实现。
-
给出cursor 使用这个mcp server 的配置示例。
配置比较短,就这这里贴一下:
{ > "mcpServers": { "calculator": { "command": "python", "args": ["D:/work/code/mcp_hello_world/server.py"], "env": {}, "autoApprove": ["add", "subtract", "multiply", "divide"], "disabled": false } } }通过代码的变更,故意加上一个magic number,验证了 mcp server 是生效的。
如何实现?
在协议设计方面,对程序员来说太熟悉了。比较感兴趣的是,如何粘合llm和mcp server,llm的输入输出是文字,mcp server的输入输出是rpc调用,个人直觉是通过提示词工程做的,结果果真如此。
注意,下面的文本绘图是我个人的理解,未全部通过看代码&调试证实,因segfragment的mermaid代码版本过低,渲染顺序不是自上而下。
Backend 层
MCP Protocol 协议层
GUI/Text UI 层
-
输入需求
-
查询能力
-
返回能力
-
传入参数
-
输出参数
-
调用服务
-
返回结果
-
反馈结果
LLM Model
MCP Client
MCP Server
用户
我先从 modelcontextprotocol 中寻找对应提示词,在cursor 输入指令,没有找到相关代码:
分析这个工程。
给出 "Client 先向 LLM 发送包含 MCP 调用规则的提示词,强制 LLM 输出符合 MCP 规范的 JSON 格式(而非自然语言),示例提示词" 相关的文件。 -
不在protocol中定义提示词,那只能是client中了。于是从sdk代码中找到了一个例子。
commit_hash:a9cc822a1051b1bd2b6b9b57e9e4136406983b61
python-sdk\examples\clients\simple-chatbot\main.py:331
async def start(self) -> None:
"""Main chat session handler."""
try:
for server in self.servers:
try:
await server.initialize()
except Exception as e:
logging.error(f"Failed to initialize server: {e}")
await self.cleanup_servers()
return
all_tools = []
for server in self.servers:
tools = await server.list_tools()
all_tools.extend(tools)
tools_description = "\n".join([tool.format_for_llm() for tool in all_tools])
system_message = (
"You are a helpful assistant with access to these tools:\n\n"
f"{tools_description}\n"
"Choose the appropriate tool based on the user's question. "
"If no tool is needed, reply directly.\n\n"
"IMPORTANT: When you need to use a tool, you must ONLY respond with "
"the exact JSON object format below, nothing else:\n"
"{\n"
' "tool": "tool-name",\n'
' "arguments": {\n'
' "argument-name": "value"\n'
" }\n"
"}\n\n"
"After receiving a tool's response:\n"
"1. Transform the raw data into a natural, conversational response\n"
"2. Keep responses concise but informative\n"
"3. Focus on the most relevant information\n"
"4. Use appropriate context from the user's question\n"
"5. Avoid simply repeating the raw data\n\n"
"Please use only the tools that are explicitly defined above."
)
上述代码只是example,无法证明实际的实现也是如此。我找了google python-genai的代码,发现llm 的api已经将 tools封装了。openai 家的也是如此:
openai function-calling。
只阅读了 google python-genai 的代码,tools参数在sdk层只是通过 json rpc 将参数传递给 llm server 服务。提示词拼装(如果有)的部分很可能在闭源的 llm server 服务中。
总结
- cursor 等 ai 编码工具对 快速生成demo,寻找xx实现,总结代码等细分场景效果很好。
- 鉴于llm的输入是token, 即自然语言,mcp-server 和 llm-server 的胶水层大概率是 隐藏在 llm-server 服务的提示词工程。
行业拓展
分享一个面向研发人群使用的前后端分离的低代码软件------JNPF。
基于 Java Boot/.Net Core双引擎,它适配国产化,支持主流数据库和操作系统,提供五十几种高频预制组件,内置了常用的后台管理系统使用场景和实用模版,通过简单的拖拉拽操作,开发者能够高效完成软件开发,提高开发效率,减少代码编写工作。
JNPF基于SpringBoot+Vue.js,提供了一个适合所有水平用户的低代码学习平台,无论是有经验的开发者还是编程新手,都可以在这里找到适合自己的学习路径。
此外,JNPF支持全源码交付,完全支持根据公司、项目需求、业务需求进行二次改造开发或内网部署,具备多角色门户、登录认证、组织管理、角色授权、表单设计、流程设计、页面配置、报表设计、门户配置、代码生成工具等开箱即用的在线服务。