MCP 实战:从零开始实现自己的 MCP Server
上一篇中介绍了 Agent、Function Calling、MCP 等概念,这篇则分享如何实现自己的 MCP Server,并将其添加到 Cline 进行验证。
1. 什么是 MCP
图源:https://blog.dailydoseofds.com/p/visual-guide-to-model-context-protocol
详细概念参考上文: 一文搞懂 Agent&Function Calling&MCP&A2A 是什么。
1.1 Model Context Protocol
MCP(Model Context Protocol) 是由 Anthropic 推出的一项开放标准协议,旨在解决不同大模型与不同外部工具集成的标准化问题。官方解释是“其目标是为大型语言模型提供一种开放、标准化的方式,以便与外部数据源、工具和服务进行连接。”
它规定了上下文与请求的结构化传递方式,并要求通信格式符合 JSON-RPC 2.0 标准。
简单理解,MCP 相当于大模型领域的“HTTP 协议”,其并不绑定任何大模型,这意味着用户可以在支持 MCP 的工具中,用任何大模型调用 MCP 服务。
英文版描述:
The Model Context Protocol (MCP) is an open protocol that enables seamless integration between LLM applications and external data sources and tools. Whether you’re building an AI-powered IDE, enhancing a chat interface, or creating custom AI workflows, MCP provides a standardized way to connect LLMs with the context they need.
一句话描述:MCP 是一种开放、标准化的协议,以便大型语言模型能够与外部数据源、工具和服务进行连接。
1.2 General Architecture
架构如下:
MCP 涉及到 5 个组件或角色:
MCP Hosts: 真正使用 MCP 的程序,例如 Claude Desktop, IDEs 或者其他 AI 工具
MCP Clients: 实现 MCP 协议的客户端,维持和 MCP Server 之间的 1:1 连接
MCP Servers: 实现 MCP 协议的服务端,通过 MCP 协议公开某些功能,MCP服务器可以提供以下类型的功能:
Resources: 客户端可以读取的类似文件的数据(如API响应或文件内容)
Tools: 工具:可以由LLM调用的函数(经用户批准)
Prompts: 帮助用户完成特定任务的预先编写的模板
…
Local Data Sources: 本地数据源,MCP 服务可以安全访问的本地文件、数据库和其他服务
Remote Services: 远程服务,MCP 服务可以连接的外部系统
需要重点关注的就是 MCP Host、MCP Client 以及 MCP Server 三部分,Local Data Sources、Remote Services 可以看做是 MCP Server 自身实现功能的一部分。
MCP Host 就是直接跟用户交互的应用程序,例如 Claude,而 MCP Client 一般是直接集成在 MCP Host 里,这样应用程序既可以和用户交互,也可以调用 MCP Server。
MCP Server 就是提供 Resources、Tools、 Prompts 等等功能的服务端,可以简单理解为把 Function Calling 中的函数封装为了服务,满足 MCP 标准从而实现功能复用。
2. 实现自己的 MCP Server
作为一个 Gopher,这里选择的是 MCP 的 Go 语言实现:mcp-go 这个库。
2.1 安装
go get github.com/mark3labs/mcp-go
2.2 Stdio 类型 MCP Server
以下是一个简单的 Stdio 类型的 MCP Server,提供了一个名为 calculate
的 tool,接收 x、y 以及 operation 三个参数。
package main
import (
"context"
"fmt"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
)
func main() {
// Create a new MCP server
s := server.NewMCPServer(
"Calculator Demo",
"1.0.0",
server.WithToolCapabilities(false),
server.WithRecovery(),
)
// Add a calculator tool
calculatorTool := mcp.NewTool("calculate",
mcp.WithDescription("Perform basic arithmetic operations"),
mcp.WithString("operation",
mcp.Required(),
mcp.Description("The operation to perform (add, subtract, multiply, divide)"),
mcp.Enum("add", "subtract", "multiply", "divide"),
),
mcp.WithNumber("x",
mcp.Required(),
mcp.Description("First number"),
),
mcp.WithNumber("y",
mcp.Required(),
mcp.Description("Second number"),
),
)
// Add the calculator handler
s.AddTool(calculatorTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// Using helper functions for type-safe argument access
op, err := request.RequireString("operation")
if err != nil {
return mcp.NewToolResultError(err.Error()), nil
}
x, err := request.RequireFloat("x")
if err != nil {
return mcp.NewToolResultError(err.Error()), nil
}
y, err := request.RequireFloat("y")
if err != nil {
return mcp.NewToolResultError(err.Error()), nil
}
var result float64
switch op {
case "add":
result = x + y
case "subtract":
result = x - y
case "multiply":
result = x * y
case "divide":
if y == 0 {
return mcp.NewToolResultError("cannot divide by zero"), nil
}
result = x / y
}
return mcp.NewToolResultText(fmt.Sprintf("%.2f", result)), nil
})
// Start the server
if err := server.ServeStdio(s); err != nil {
fmt.Printf("Server error: %v\n", err)
}
}
接下来就可以开始验证我们的 MCP Server 了。
2.3 SSE 类型 MCP Server
SSE 类型的 MCP Server 和 Stdio 主要区别在 MCP Hosts(MCP Client) 如何与 MCP Server 做交互。
实际上代码很简单,只需要改动一点点:
Stdio 是这样启动服务的
// Start the server
if err := server.ServeStdio(s); err != nil {
fmt.Printf("Server error: %v\n", err)
}
SSE 则是这样:
// 创建基于 SSE 的服务器实例
sseServer := server.NewSSEServer(s)
// 启动服务器,监听指定端口(如 :8080)
err := sseServer.Start(":8080")
if err != nil {
panic(err)
}
然后启动服务
go run cmd/main.go
3. MCP Hosts 配置 MCP Server
3.1 安装 Cline
在验证 MCP Server 之前我们先安装一个 MCP Hosts,这里选择的是 Cline,大家也可以选择其他的。
首先在 VS Code 中安装 Cline 插件。
安装之后在侧边栏点击图标即可打开
3.2 配置模型
在 Cline 最下方有一个配置模型的地方,点开填写相关信息即可。
如果没有可用模型,可以到 DeepSeek 官网 注册。
3.3 配置 MCP Server
接下来就开始配置 MCP Server 了,将我们本地跑的 MCP Server 配置到 Cline 里。
在 Cline 中点击服务器图标即,再在弹出窗口中点击齿轮图标即可进入 MCP Server 配置界面
点击 Configure
之后就可以在 json 文件中配置了,我们这里启动的是 Stdio 类型的 MCP Server,也就是输入输出分别使用 Stdin 和 Stdout 的,只需要配置启动命令即可:
先 go build cmd/main.go 即可
{
"mcpServers": {
"mymcp": {
"command": "/Users/lixueduan/17x/projects/i-mcp/cmd/main",
"args": [
],
"disabled": false,
"autoApprove": []
}
}
}
对于 SSE 类型 MCP Server 则是
{
"mcpServers": {
"mymcp": {
"url": "http://localhost:8080/sse",
"disabled": false
}
}
}
如果出现小绿点则说明 MCP Server 可以正常使用了。
3.4 验证
至此,就可以开始验证 MCP Server 了。
问 Cline 一个问题
帮我计算 1+1
此时 MCP Hosts(Cline) 会自动携带问题和我们 MCP Server 的信息发送给 LLM,然后 LLM 根据思考会得出要调用前面我们配置的 mymcp 这个 MCP Server 中的 名为 calculate
的 tool,参数 x、y 以及 operation 分别是 1、1 和 add。
可以看到,最终的结果和预想的是一致的
我们点击 Approve 之后 Cline 就会去调用 MCP 了。
其中 MCP Server 返回的结果是 2.00,然后模型整合后返回最终的结果为:
The result of 1 + 1 is 2.00
至此,我们就完成了一个 Stdio 类型的 MCP Server 的开发和验证。
4. MCP 工作流程
整个工作流程如下图所示:
该过程涉及到 3 个角色:
1)MCP Server:也就是我们实现的 MCP 服务
2)LLM:大模型,DeepSeek、ChatGPT 或者自己部署的其他模型都可以
3)Cline(MCP Hosts):在 MCP Server 和 LLM 之间交互,可以看做是一个 Agent
流程如下:
1)配置 MCP Server 到 Cline 之后,Cline 会获取该 MCP Server 提供的能力
2)用户给 Cline 发送任务
3)Cline 会带着问题和上一步获取到的信息发送给 LLM
4)LLM 根据问题和 MCP 信息决定该调用哪个 MCP Server 的哪个 tool,具体通过
<use_mcp_tool> </use_mcp_tool>
标记,例如:<use_mcp_tool> <server_name>mymcp</server_name> <tool_name>calculate</tool_name> <arguments> { "operation": "add", "x": 1,"y": 1} </arguments> </use_mcp_tool>
5)Cline 解析 XML 并调用对应 MCP Server 拿到结果
6)Cline 将 MCP Server 结果返回给 LLM
7)LLM 整合后返回最终结果给 Cline
8)Cline 将最终结果展现给用户
MCP Hosts 会和大模型有两次交互,另外根据 MCP Hosts 实现不同,MCP 可以依赖或者不依赖 FunctionCalling。
主要就是要把本地支持的函数信息告诉 LLM,可以在system提示词里也可以使用functionCalling 放到 functiions 里面,最终效果都是一样的。
支持functionCalling的模型
输入:函数放到 functions 里
输出:output.tool_use 里面就是要调用的工具
对不支持functionCalling的模型
输入:函数放到提示词里,一般在system部分
输出:使用xml标签,比如<user_mcp_tool><use_mcp_tool/> 之类的格式指定要调用的函数的参数信息
可以对于不支持 functionCalling的 LLM 也可以达到同样的效果。
5. 小结
本文通过实战演示了 Anthropic 开源协议 MCP 的核心价值 —— 通过标准化接口实现大模型与外部工具的解耦集成。我们基于 Go 语言实现了两种典型部署形态的 MCP Server:
Stdio 类型:通过进程的标准输入输出完成交互,方便本地工具集成。
SSE 类型:采用 Server-Sent Events 技术实现长连接通信,支持远程接入。
从架构层面看,MCP 定义的三方角色(MCP Server 提供工具能力、LLM 负责逻辑决策、MCP Hosts 协调交互流程)形成了清晰的职责分层。这不仅让工具开发者可专注于功能实现(如本文的计算器工具),也让模型开发者能聚焦算法优化,最终通过标准化协议推动大模型生态从 “烟囱式开发” 向 “组件化协同” 演进。
随着更多工具接入 MCP 生态,这种标准化交互协议将成为连接大模型与垂直领域数据的 “数字桥梁”,为企业级 AI 应用开发提供更高效的基础设施。
最后再贴一下工作流程: