MCP 简介 模型上下文协议(Model Context Protocol,简称 MCP)是一种开放标准,旨在标准化大型语言模型(LLM)与外部数据源和工具之间的交互方式。
由 Anthropic 于 2024 年 11 月推出,MCP 通过定义统一的接口,使 AI 应用能够安全、灵活地访问和操作本地及远程数据资源。
Transports(传输层) 消息格式 MCP 协议使用 JSON-RPC 2.0 作为消息传输格式:
Request 请求:
1 2 3 4 5 6 { "jsonrpc" : "2.0" , "id" : 1 , "method" : "string" , "params" : { } }
Response 响应:
1 2 3 4 5 6 { "jsonrpc" : "2.0" , "id" : 1 , "result" : { } , "error" : { "code" : 123 , "message" : "错误描述" } }
Notification 通知:
1 2 3 4 5 { "jsonrpc" : "2.0" , "method" : "string" , "params" : { } }
内置传输类型 标准输入/输出(stdio) stdio 通过标准输入输出流实现通信,适用于本地集成与命令行工具。
Go server 示例:
1 2 3 4 s := server.NewMCPServer("My Server" , "1.0.0" ) if err := server.ServeStdio(s); err != nil { log.Fatalf("Server error: %v" , err) }
Server-Sent Events (SSE) SSE 通过 HTTP POST 请求实现客户端到服务器通信,支持服务器到客户端流式传输。
Go server 示例:
1 2 sseServer := server.NewSSEServer(s) err := sseServer.Start(":8080" )
MCP 的通用架构 MCP 遵循 CS 架构:
Host 主机 :发起连接 LLM 的应用程序
MCP Client 客户端 :与 MCP Server 保持 1:1 连接
MCP Server 服务器 :提供资源、提示和工具
MCP 客户端 Roots 根 Roots 用于界定服务器可操作的边界,可以是文件系统路径或 HTTP URL。
1 2 3 4 5 6 7 8 { "roots" : [ { "uri" : "file:///home/workspace/frontend" , "name" : "Frontend Repository" } ] }
Sampling 采样 采样允许服务器通过客户端向 LLM 请求补全结果,实现更复杂的代理行为。
工作原理:
服务器发送 sampling/createMessage 请求
客户端审核请求
客户端向 LLM 发送采样请求
客户端审核结果
客户端返回最终结果
采样请求示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 { "messages" : [ { "role" : "user" , "content" : { "type" : "text" , "text" : "当前目录下有哪些文件?" } } ] , "maxTokens" : 100 , "systemPrompt" : "你是一名文件系统助手。" }
MCP 服务器 Prompts 提示词 提示词允许服务器定义可复用的提示词模板和工作流。
结构定义:
1 2 3 4 5 6 7 8 9 10 11 { "name" : "analyze-code" , "description" : "分析代码以发现潜在改进点" , "arguments" : [ { "name" : "language" , "description" : "编程语言" , "required" : true } ] }
Resources 资源 资源是 MCP 协议的核心原语,服务器通过它向客户端提供可读数据。
资源 URI 格式:
1 2 3 [协议]://[主机]/[路径] file:///home/user/documents/go.pdf postgres://database/user/schema
工具是 MCP 协议中暴露给 LLM 的可执行功能。
工具结构:
1 2 3 4 5 6 7 8 9 10 11 12 { "name" : "github_create_issue" , "description" : "在 GitHub 创建 Issue" , "inputSchema" : { "type" : "object" , "properties" : { "title" : { "type" : "string" } , "body" : { "type" : "string" } , "labels" : { "type" : "array" , "items" : { "type" : "string" } } } } }
原语控制层级
原语
控制方
描述
示例
Prompts
用户控制
交互式模板
斜杠命令(/command)
Resources
应用控制
上下文数据
文件内容、git 历史
Tools
模型控制
功能接口
API 请求、文件写入
服务器实现(Go) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 package mainimport ( "context" "errors" "fmt" "os" "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" ) func main () { s := server.NewMCPServer("Server Demo" , "1.0.0" ) calculatorTool := mcp.NewTool("calculate" , mcp.WithDescription("执行基本的算术运算" ), mcp.WithString("operation" , mcp.Required(), mcp.Description("运算类型" ), mcp.Enum("add" , "subtract" , "multiply" , "divide" ), ), mcp.WithNumber("x" , mcp.Required(), mcp.Description("第一个数字" )), mcp.WithNumber("y" , mcp.Required(), mcp.Description("第二个数字" )), ) s.AddTool(calculatorTool, func (ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error ) { op := request.Params.Arguments["operation" ].(string ) x := request.Params.Arguments["x" ].(float64 ) y := request.Params.Arguments["y" ].(float64 ) 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 nil , errors.New("不允许除以零" ) } result = x / y } return mcp.FormatNumberResult(result), nil }) resource := mcp.NewResource("docs://readme" , "项目说明文档" ) s.AddResource(resource, func (ctx context.Context, request mcp.ReadResourceRequest) ([]mcp.ResourceContents, error ) { content, err := os.ReadFile("README.md" ) if err != nil { return nil , err } return []mcp.ResourceContents{ mcp.TextResourceContents{URI: "docs://readme" , Text: string (content)}, }, nil }) if err := server.ServeStdio(s); err != nil { fmt.Printf("Server error: %v\n" , err) } }
客户端实现(Go) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 package mainimport ( "context" "fmt" "time" "github.com/mark3labs/mcp-go/client" "github.com/mark3labs/mcp-go/mcp" ) func main () { mcpClient, err := client.NewStdioMCPClient("./server" , []string {}) if err != nil { panic (err) } defer mcpClient.Close() ctx, cancel := context.WithTimeout(context.Background(), 30 *time.Second) defer cancel() initResult, err := mcpClient.Initialize(ctx, mcp.InitializeRequest{}) fmt.Printf("服务器信息: %s %s\n" , initResult.ServerInfo.Name, initResult.ServerInfo.Version) tools, _ := mcpClient.ListTools(ctx, mcp.ListToolsRequest{}) for _, tool := range tools.Tools { fmt.Printf("- %s: %s\n" , tool.Name, tool.Description) } result, _ := mcpClient.CallTool(ctx, mcp.CallToolRequest{ Params: mcp.CallToolParams{ Name: "calculate" , Arguments: map [string ]any{"operation" : "add" , "x" : 1 , "y" : 1 }, }, }) fmt.Println("结果:" , result.Content[0 ].(mcp.TextContent).Text) }
运行结果:
1 2 3 初始化成功,服务器信息: Server Demo 1.0.0 可用工具: calculate 调用工具结果: 2.00
小结 本文介绍了 MCP 协议的核心内容:
客户端原语 :roots(根路径)、sampling(采样)
服务器原语 :prompts(提示词)、resources(资源)、tools(工具)
Server 原语控制层级 :用户控制、应用控制、模型控制
通过 Go 语言的客户端与服务器示例,帮助开发者快速理解和应用该协议。