一文掌握 MCP 上下文協(xié)議:從理論到實(shí)踐
MCP
模型上下文協(xié)議(Model Context Protocol,簡稱 MCP)是一種開放標(biāo)準(zhǔn),旨在標(biāo)準(zhǔn)化大型語言模型(LLM)與外部數(shù)據(jù)源和工具之間的交互方式。由 Anthropic 于 2024 年 11 月推出,MCP 通過定義統(tǒng)一的接口,使 AI 應(yīng)用能夠安全、靈活地訪問和操作本地及遠(yuǎn)程數(shù)據(jù)資源,提升模型的功能性和可擴(kuò)展性。
圖片
Transports(傳輸層)
在 MCP 協(xié)議中,傳輸層提供了客戶端與服務(wù)器之間通信的基礎(chǔ),其負(fù)責(zé)處理消息的發(fā)送與接收的底層機(jī)制。
消息格式
MCP 協(xié)議使用 JSON-RPC 2.0 作為消息傳輸格式,包含以下三種類型的 JSON-RPC 消息:
- Request 請求:
{
"jsonrpc": "2.0",
"id": 1, // 請求 ID(數(shù)字或字符串)
"method": "string", // 方法名
"params": {} // 可選,參數(shù)對象
}
- Response 響應(yīng):
{
"jsonrpc": "2.0",
"id": 1, // 對應(yīng)請求的 ID
"result": {}, // 可選,成功結(jié)果
"error": { // 可選,錯(cuò)誤信息
"code": 123,
"message": "錯(cuò)誤描述",
"data": {} // 可選,附加數(shù)據(jù)
}
}
- Notification通知:
{
"jsonrpc": "2.0",
"method": "string", // 通知方法名
"params": {} // 可選,參數(shù)對象
}
內(nèi)置傳輸類型
MCP 協(xié)議內(nèi)置了兩種標(biāo)準(zhǔn)傳輸方式:標(biāo)準(zhǔn)輸入/輸出(stdio) 和 Server-Sent Events(SSE) 。
標(biāo)準(zhǔn)輸入/輸出(stdio)
stdio 傳輸通過 標(biāo)準(zhǔn)輸入輸出流 實(shí)現(xiàn)客戶端與服務(wù)器之間的通信,適用于本地集成與命令行工具。
推薦在以下場景使用 stdio:
- 構(gòu)建命令行工具
- 本地系統(tǒng)集成
- 簡單進(jìn)程間通信
- 與 shell 腳本協(xié)作
Go server 示例:
s := server.NewMCPServer(
"My Server", // Server name
"1.0.0", // Version
)
if err := server.ServeStdio(s); err != nil {
log.Fatalf("Server error: %v", err)
}
Server-Sent Events (SSE)
SSE 傳輸 通過 HTTP POST 請求實(shí)現(xiàn) 客戶端到服務(wù)器通信,同時(shí)支持 服務(wù)器到客戶端流式傳輸 。
推薦在以下場景使用 SSE:
- 僅需要服務(wù)器到客戶端的流式通信
- 運(yùn)行在受限網(wǎng)絡(luò)環(huán)境
- 實(shí)現(xiàn)簡單的推送更新
Go server 示例:
s := server.NewMCPServer(
"My Server", // Server name
"1.0.0", // Version
)
sseServer := server.NewSSEServer(s)
err := sseServer.Start(":8080")
if err != nil {
panic(err)
}
MCP 的通用架構(gòu)
MCP 遵循 CS 架構(gòu)(client-server),具體包含的組件如下:
- Host 主機(jī):發(fā)起連接 LLM 的應(yīng)用程序,例如 Claude for Desktop 或其他的 AI 應(yīng)用。
- MCP Client 客戶端:運(yùn)行在主機(jī)里的客戶端,與 MCP Server 服務(wù)器保持 1:1 連接,負(fù)責(zé)協(xié)議通信。
- MCP Server 服務(wù)器:負(fù)責(zé)向客戶端提供 資源、提示 和 工具 的服務(wù)器。
圖片
MCP 客戶端
客戶端可以實(shí)現(xiàn)額外的功能來與 MCP 服務(wù)器進(jìn)行交互。
Roots 根
Roots 是MCP 協(xié)議中的一個(gè)概念,用于界定服務(wù)器可操作的邊界??蛻舳丝梢远x Roots,以告知服務(wù)器相關(guān)的資源信息及其位置。
root 是客戶端建議服務(wù)器應(yīng)關(guān)注的 URI。當(dāng) 客戶端 連接到服務(wù)器時(shí),它會(huì)聲明 服務(wù)器 應(yīng)處理哪些 root。雖然這些 root 主要是文件系統(tǒng)路徑,但 root 也可以是 HTTP URL。
# 文件系統(tǒng)路徑
file:///home/chenmingyong/workspace
# HTTP URL
https://chenmingyong.cn/
功能
Roots 有以下幾個(gè)功能:
- 引導(dǎo):指示服務(wù)器相關(guān)資源及其位置。
- 明確歸屬:清楚標(biāo)識(shí)哪些資源屬于當(dāng)前工作區(qū)。
- 便于管理:支持同時(shí)處理多個(gè)不同的資源。
工作機(jī)制
當(dāng)客戶端具備 Roots 功能時(shí),通常會(huì):
- 在連接服務(wù)器時(shí)聲明自身的 Roots 支持能力
- 向服務(wù)器發(fā)送建議的 Roots 列表
- 在 Roots 發(fā)生變更時(shí)(若協(xié)議支持)主動(dòng)通知服務(wù)器
示例
{
"roots": [
{
"uri": "file:///home/chenmingyong/workspace/frontend",
"name": "Frontend Repository"
},
{
"uri": "https://chenmingyong.cn/",
"name": "API Endpoint"
}
]
}
Sampling 采樣
采樣是 MCP 協(xié)議中一項(xiàng)強(qiáng)大的功能,允許服務(wù)器通過客戶端向 LLM 大模型請求補(bǔ)全結(jié)果,從而實(shí)現(xiàn)更復(fù)雜的代理行為,同時(shí)確保安全性與隱私性。
工作原理
采樣流程遵循以下步驟:
- 服務(wù)器發(fā)送請求:服務(wù)器向客戶端發(fā)送 sampling/createMessage 請求。
- 客戶端審核請求:客戶端收到請求后可以對其審查和修改。
- 客戶端發(fā)起采樣:客戶端向 LLM 發(fā)送采樣請求。
- 客戶端審核結(jié)果:客戶端審核 LLM 返回的補(bǔ)全內(nèi)容。
- 客戶端返回結(jié)果:客戶端將最終結(jié)果發(fā)送回服務(wù)器。
圖片
這種 人機(jī)協(xié)作(Human-in-the-loop) 設(shè)計(jì),確保用戶能控制 LLM 看到的內(nèi)容以及生成的結(jié)果,兼顧自動(dòng)化與安全性。
消息格式
采樣請求使用同一的消息結(jié)構(gòu),示例如下:
{
"messages": [
{
"role": "user" | "assistant", // 消息角色
"content": {
"type": "text" | "image", // 內(nèi)容類型
// 文本內(nèi)容
"text": "string",
// 圖片內(nèi)容
"data": "string", // Base64 編碼
"mimeType": "string" // MIME 類型
}
}
],
"modelPreferences": { // 可選,模型偏好設(shè)置
"hints": [ // 模型提示
{
"name": "string" // 建議的模型名稱
}
],
"costPriority": 0.0, // 降低成本的優(yōu)先級 (0-1)
"speedPriority": 0.0, // 低延遲的優(yōu)先級 (0-1)
"intelligencePriority": 0.0 // 模型能力的優(yōu)先級 (0-1)
},
"systemPrompt": "string", // 可選,系統(tǒng)提示詞
"includeContext": "none" | "thisServer" | "allServers", // 上下文包含范圍
"temperature": 0.0, // 隨機(jī)性控制
"maxTokens": 100, // 最大生成 Token 數(shù)
"stopSequences": ["string"], // 停止序列
"metadata": {} // 其他元數(shù)據(jù)
}
響應(yīng)格式
客戶端返回采樣結(jié)果的結(jié)構(gòu)如下:
{
"model": "string", // 使用的模型名稱
"stopReason": "endTurn" | "stopSequence" | "maxTokens" | "string", // 停止原因
"role": "user" | "assistant", // 消息角色
"content": {
"type": "text" | "image", // 內(nèi)容類型
"text": "string", // 文本內(nèi)容
"data": "string", // 圖片內(nèi)容 (Base64)
"mimeType": "string" // MIME 類型
}
}
示例請求
以下是一個(gè)示例采樣請求:
{
"method": "sampling/createMessage",
"params": {
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": "當(dāng)前目錄下有哪些文件?"
}
}
],
"systemPrompt": "你是一名文件系統(tǒng)助手。",
"includeContext": "thisServer",
"maxTokens": 100
}
}
MCP 服務(wù)器
在 MCP 協(xié)議中,服務(wù)器提供了為 LLM 大模型添加上下文的基礎(chǔ)構(gòu)件。通過 Propmts(提示詞)、Resources(資源)和 Tools(工具)這三種 原語(Primitives), 客戶端、服務(wù)器與語言模型之間能夠?qū)崿F(xiàn) 高效且靈活的交互。
Prompts 提示詞
提示詞 允許服務(wù)器定義可復(fù)用的提示詞模板和工作流,客戶端可以輕松將這些模板呈現(xiàn)給用戶或 LLM。
提示詞結(jié)構(gòu)
一個(gè)提示詞的結(jié)構(gòu)定義如下所示:
{
"name": "string", // 提示詞唯一標(biāo)識(shí)符
"description": "string", // 可選,人類可讀的描述
"arguments": [ // 可選參數(shù)列表
{
"name": "string", // 參數(shù)標(biāo)識(shí)符
"description": "string", // 可選,參數(shù)描述
"required": "boolean" // 是否為必填參數(shù)
}
]
}
獲取提示詞
客戶端可以通過調(diào)用 prompts/list 獲取可用的提示詞列表:
請求示例:
{
method: "prompts/list"
}
響應(yīng)示例:
{
"prompts": [
{
"name": "analyze-code", // 提示詞唯一標(biāo)識(shí)符
"description": "分析代碼以發(fā)現(xiàn)潛在改進(jìn)點(diǎn)", // 提示詞描述
"arguments": [
{
"name": "language", // 參數(shù)名稱
"description": "編程語言", // 參數(shù)描述
"required": true // 是否必填
}
]
}
]
}
獲取提示詞詳情
如果客戶端要使用提示詞,需要通過 prompts/get 接口獲取提示詞詳情。
請求示例:
{
"method": "prompts/get",
"params": {
"name": "analyze-code", // 要使用的提示詞名稱
"arguments": {
"language": "go" // 動(dòng)態(tài)參數(shù)
}
}
}
響應(yīng)示例:
{
"description": "分析 Go 代碼以發(fā)現(xiàn)潛在改進(jìn)點(diǎn)", // 提示詞描述
"messages": [
{
"role": "user", // 消息發(fā)送方
"content": {
"type": "text", // 內(nèi)容類型
"text": "請分析以下 Go 代碼,找出可能的改進(jìn)空間:\n\n```go\npackage main\n\nimport "fmt"\n\nfunc main() {\n\n fmt.Println("Hello, World!")\n}\n```"
}
}
]
}
動(dòng)態(tài)提示詞
提示詞不僅可以是靜態(tài)模板,也支持根據(jù)參數(shù)動(dòng)態(tài)生成內(nèi)容,甚至可以嵌入 資源上下文。
提示詞定義示例:
{
"name": "analyze-project", // 提示詞名稱
"description": "分析項(xiàng)目日志與代碼", // 描述
"arguments": [
{
"name": "timeframe", // 參數(shù)名稱
"description": "要分析的日志時(shí)間范圍", // 參數(shù)描述
"required": true // 是否必填
},
{
"name": "fileUri", // 參數(shù)名稱
"description": "待審查的代碼文件 URI", // 參數(shù)描述
"required": true // 是否必填
}
]
}
prompts/get 請求返回示例:
{
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": "請分析以下系統(tǒng)日志和代碼文件,找出潛在問題:"
}
},
{
"role": "user",
"content": {
"type": "resource",
"resource": {
"uri": "logs://chenmingyong/recent?timeframe=1h", // 資源 URI
"text": "[2024-03-14 15:32:11] ERROR: network.py:127 連接超時(shí)\n[2024-03-14 15:32:15] WARN: 正在重試連接 (第 2/3 次)\n[2024-03-14 15:32:20] ERROR: 達(dá)到最大重試次數(shù)",
"mimeType": "text/plain" // 資源類型
}
}
},
{
"role": "user",
"content": {
"type": "resource",
"resource": {
"uri": "file:///path/chenmingyong/code.py", // 代碼文件 URI
"text": "def connect_to_service(timeout=30):\n retries = 3\n for attempt in range(retries):\n try:\n return establish_connection(timeout)\n except TimeoutError:\n if attempt == retries - 1:\n raise\n time.sleep(5)\n\ndef establish_connection(timeout):\n # 連接實(shí)現(xiàn)\n pass",
"mimeType": "text/x-python"
}
}
}
]
}
多輪提示工作流
提示詞還支持定義多輪對話流程,通過預(yù)設(shè)的多步提示,引導(dǎo)用戶完成復(fù)雜任務(wù)。
const debugWorkflow = {
name: "debug-error",
async getMessages(error: string) {
return [
{
role: "user",
content: {
type: "text",
text: `我遇到了一個(gè)錯(cuò)誤:${error}`
}
},
{
role: "assistant",
content: {
type: "text",
text: "我來幫你分析這個(gè)錯(cuò)誤。你之前嘗試過哪些操作?"
}
},
{
role: "user",
content: {
type: "text",
text: "我嘗試重啟服務(wù),但錯(cuò)誤依然存在。"
}
}
];
}
};
Resources 資源
Resources(資源)是 MCP 協(xié)議中的核心原語之一,服務(wù)器通過它可以向客戶端提供可讀的數(shù)據(jù)或內(nèi)容,用作 LLM 交互的上下文信息。
資源 URI
每個(gè)資源通過 URI 進(jìn)行標(biāo)識(shí),格式如下:
[協(xié)議]://[主機(jī)]/[路徑]
示例:
file:///home/chenmingyong/documents/go.pdf
postgres://database/chenmingyong/schema
screen://localhost/chenmingyong/display1
具體的協(xié)議(protocol)與路徑結(jié)構(gòu)由 MCP 服務(wù)器自行定義,服務(wù)器也可以設(shè)計(jì)自定義的 URI 格式。
資源類型
資源內(nèi)容分為兩種類型:
文本類型
包含 UTF_8 編碼的文本數(shù)據(jù),例如:
- 源代碼
- 配置文件
- 日志文件
- JSON / XML 數(shù)據(jù)
- 普通文本
二進(jìn)制資源
包含 Base64 編碼的原始二進(jìn)制數(shù)據(jù),例如:
- 圖片
- PDF 文件
- 音頻 / 視頻文件
- 其他非文本格式
獲取資源列表
客戶端可以通過調(diào)用服務(wù)器的 resources/list 獲取資源列表,每個(gè)資源包含以下信息:
{
"uri": "string", // 資源唯一標(biāo)識(shí)符
"name": "string", // 資源名稱(人類可讀)
"description": "string", // 可選,資源描述
"mimeType": "string" // 可選,資源 MIME 類型
}
對于動(dòng)態(tài)資源,服務(wù)器可以通過 URI 模板方式暴露資源,客戶端可根據(jù)模板構(gòu)建有效的資源 URI:
{
"uriTemplate": "string", // 符合 RFC 6570 的 URI 模板
"name": "string", // 模板名稱(人類可讀)
"description": "string", // 可選,模板描述
"mimeType": "string" // 可選,匹配資源的 MIME 類型
}
獲取資源詳情
客戶端可以通過 resources/read 接口讀取資源內(nèi)容,只需傳入資源的 URI。
服務(wù)器會(huì)返回資源內(nèi)容列表:
{
contents: [
{
uri: string; // 資源唯一標(biāo)識(shí)符
mimeType?: string; // 可選,資源 MIME 類型
// 以下二選一
text?: string; // 文本資源
blob?: string; // 二進(jìn)制資源
}
]
}
資源更新
MCP 支持通過兩種方式通知資源變更。
列表變更
當(dāng)可用資源列表發(fā)生變更時(shí),服務(wù)器會(huì)通過 notifications/resources/list_changed 通知客戶端。
內(nèi)容變更
客戶端可以訂閱特定資源的更新流程如下:
- 客戶端發(fā)送 resources/subscribe 請求,指定資源 URI
- 資源發(fā)生變更時(shí),服務(wù)器通過 notifications/resources/updated 通知客戶端
- 客戶端可通過 resources/read 獲取最新內(nèi)容
- 客戶端可通過 resources/unsubscribe 取消訂閱
Tools 工具
Tools(工具) 是 MCP 協(xié)議中的一項(xiàng)關(guān)鍵原語,服務(wù)器可通過它向客戶端暴露可執(zhí)行功能,供 LLM 使用(通常需要用戶批準(zhǔn),確保人類參與決策)。Tools 的核心概念包括:
- 發(fā)現(xiàn)(Discovery):客戶端可通過 tools/list 接口獲取可用工具列表。
- 調(diào)用(Invocation):客戶端可通過 tools/call接口發(fā)起工具調(diào)用請求,由服務(wù)器執(zhí)行具體操作并返回結(jié)果。
- 靈活性(Flexibility):工具既可以是簡單的計(jì)算函數(shù),也可以是復(fù)雜的 API 集成。
工具結(jié)構(gòu)定義
每個(gè)工具的結(jié)構(gòu)定義如下所示:
{
"name": "string", // 工具唯一標(biāo)識(shí)符
"description": "string", // 可選,工具描述
"inputSchema": { // 工具參數(shù)的 JSON Schema
"type": "object",
"properties": { ... } // 工具參數(shù)定義
}
}
工具實(shí)現(xiàn)示例
- 與本地系統(tǒng)交互的工具
{
"name": "execute_command", // 工具名稱
"description": "執(zhí)行 shell 命令", // 描述
"inputSchema": {
"type": "object",
"properties": {
"command": { "type": "string" }, // 命令名稱
"args": {
"type": "array",
"items": { "type": "string" } // 命令參數(shù)
}
}
}
}
- 外部 API 集成類工具
{
"name": "github_create_issue", // 工具名稱
"description": "在 GitHub 創(chuàng)建 Issue", // 描述
"inputSchema": {
"type": "object",
"properties": {
"title": { "type": "string" }, // Issue 標(biāo)題
"body": { "type": "string" }, // Issue 內(nèi)容
"labels": {
"type": "array",
"items": { "type": "string" } // Issue 標(biāo)簽
}
}
}
}
MCP Server 原語控制層級
每個(gè)原語的 控制層級 可總結(jié)如下:
原語 | 控制方 | Description 描述 | Example 示例 |
Prompts | 用戶控制 | 由用戶選擇調(diào)用的交互式模板 | 斜杠命令(/command)、菜單選項(xiàng) |
Resources | 應(yīng)用控制 | 由客戶端附加并管理的上下文數(shù)據(jù) | 文件內(nèi)容,git 歷史記錄 |
Tools | 模型控制 | 暴露給 LLM 以便其執(zhí)行操作的功能接口 | API POST 請求、文件寫入 |
服務(wù)器實(shí)現(xiàn)
以下是基于 Go 語言實(shí)現(xiàn)的 MCP 服務(wù)器代碼示例:
package main
import (
"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("執(zhí)行基本的算術(shù)運(yùn)算"),
mcp.WithString("operation",
mcp.Required(),
mcp.Description("要執(zhí)行的算術(shù)運(yùn)算類型"),
mcp.Enum("add", "subtract", "multiply", "divide"), // 保持英文
),
mcp.WithNumber("x",
mcp.Required(),
mcp.Description("第一個(gè)數(shù)字"),
),
mcp.WithNumber("y",
mcp.Required(),
mcp.Description("第二個(gè)數(shù)字"),
),
)
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 {
returnnil, errors.New("不允許除以零")
}
result = x / y
}
return mcp.FormatNumberResult(result), nil
})
}
// 添加資源
{
// 靜態(tài)資源示例 - 暴露一個(gè) README 文件
resource := mcp.NewResource(
"docs://readme",
"項(xiàng)目說明文檔",
mcp.WithResourceDescription("項(xiàng)目的 README 文件"),
mcp.WithMIMEType("text/markdown"),
)
// 添加資源及其處理函數(shù)
s.AddResource(resource, func(ctx context.Context, request mcp.ReadResourceRequest) ([]mcp.ResourceContents, error) {
content, err := os.ReadFile("README.md")
if err != nil {
returnnil, err
}
return []mcp.ResourceContents{
mcp.TextResourceContents{
URI: "docs://readme",
MIMEType: "text/markdown",
Text: string(content),
},
}, nil
})
}
// 添加提示詞
{
// 簡單問候提示
s.AddPrompt(mcp.NewPrompt("greeting",
mcp.WithPromptDescription("一個(gè)友好的問候提示"),
mcp.WithArgument("name",
mcp.ArgumentDescription("要問候的人的名字"),
),
), func(ctx context.Context, request mcp.GetPromptRequest) (*mcp.GetPromptResult, error) {
name := request.Params.Arguments["name"]
if name == "" {
name = "朋友"
}
return mcp.NewGetPromptResult(
"友好的問候",
[]mcp.PromptMessage{
mcp.NewPromptMessage(
mcp.RoleAssistant,
mcp.NewTextContent(fmt.Sprintf("你好,%s!今天有什么可以幫您的嗎?", name)),
),
},
), nil
})
}
// 啟動(dòng)基于 stdio 傳輸類型的服務(wù)
if err := server.ServeStdio(s); err != nil {
fmt.Printf("Server error: %v\n", err)
}
}
上述代碼示例演示了如何創(chuàng)建一個(gè) MCP Server,并展示了添加工具、資源和提示詞的方法。
需要注意的是,由于 mcp-go 庫當(dāng)前尚未支持 Sampling(采樣)功能,示例中未包含該功能的相關(guān)用法。
客戶端實(shí)現(xiàn)
基于上面定義的服務(wù)器,以下是基于 Go 語言實(shí)現(xiàn)的 MCP 客戶端代碼示例:
package main
import (
"context"
"fmt"
"time"
"github.com/mark3labs/mcp-go/client"
"github.com/mark3labs/mcp-go/mcp"
)
func main() {
// 創(chuàng)建一個(gè)基于 stdio 的MCP客戶端
mcpClient, err := client.NewStdioMCPClient(
"./client/server",
[]string{},
)
if err != nil {
panic(err)
}
defer mcpClient.Close()
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
fmt.Println("初始化 mcp 客戶端...")
initRequest := mcp.InitializeRequest{}
initRequest.Params.ProtocolVersion = mcp.LATEST_PROTOCOL_VERSION
initRequest.Params.ClientInfo = mcp.Implementation{
Name: "Client Demo",
Version: "1.0.0",
}
// 初始化MCP客戶端并連接到服務(wù)器
initResult, err := mcpClient.Initialize(ctx, initRequest)
if err != nil {
panic(err)
}
fmt.Printf(
"\n初始化成功,服務(wù)器信息: %s %s\n\n",
initResult.ServerInfo.Name,
initResult.ServerInfo.Version,
)
// 從服務(wù)器獲取提示詞列表
fmt.Println("提示詞列表:")
promptsRequest := mcp.ListPromptsRequest{}
prompts, err := mcpClient.ListPrompts(ctx, promptsRequest)
if err != nil {
panic(err)
}
for _, prompt := range prompts.Prompts {
fmt.Printf("- %s: %s\n", prompt.Name, prompt.Description)
fmt.Println("參數(shù):", prompt.Arguments)
}
// 從服務(wù)器獲取資源列表
fmt.Println()
fmt.Println("資源列表:")
resourcesRequest := mcp.ListResourcesRequest{}
resources, err := mcpClient.ListResources(ctx, resourcesRequest)
if err != nil {
panic(err)
}
for _, resource := range resources.Resources {
fmt.Printf("- uri: %s, name: %s, description: %s, MIME類型: %s\n", resource.URI, resource.Name, resource.Description, resource.MIMEType)
}
// 從服務(wù)器獲取工具列表
fmt.Println()
fmt.Println("可用工具列表:")
toolsRequest := mcp.ListToolsRequest{}
tools, err := mcpClient.ListTools(ctx, toolsRequest)
if err != nil {
panic(err)
}
for _, tool := range tools.Tools {
fmt.Printf("- %s: %s\n", tool.Name, tool.Description)
fmt.Println("參數(shù):", tool.InputSchema.Properties)
}
fmt.Println()
// 調(diào)用工具
fmt.Println("調(diào)用工具: calculate")
toolRequest := mcp.CallToolRequest{
Request: mcp.Request{
Method: "tools/call",
},
}
toolRequest.Params.Name = "calculate"
toolRequest.Params.Arguments = map[string]any{
"operation": "add",
"x": 1,
"y": 1,
}
// Call the tool
result, err := mcpClient.CallTool(ctx, toolRequest)
if err != nil {
panic(err)
}
fmt.Println("調(diào)用工具結(jié)果:", result.Content[0].(mcp.TextContent).Text)
}
運(yùn)行上述代碼的結(jié)果如下所示:
初始化 mcp 客戶端...
初始化成功,服務(wù)器信息: Server Demo 1.0.0
提示詞列表:
- greeting: 一個(gè)友好的問候提示
參數(shù): [{name 要問候的人的名字 false}]
資源列表:
- uri: docs://readme, name: 項(xiàng)目說明文檔, description: 項(xiàng)目的 README 文件, MIME類型: text/markdown
可用工具列表:
- calculate: 執(zhí)行基本的算術(shù)運(yùn)算
參數(shù): map[operation:map[description:要執(zhí)行的算術(shù)運(yùn)算類型 enum:[add subtract multiply divide] type:string] x:map[description:第一個(gè)數(shù)字 type:number] y:map[description:第二個(gè)數(shù)字 type:number]]
調(diào)用工具: calculate
調(diào)用工具結(jié)果: 2.00
提示詞、資源以及工具列表和之前定義 MCP Server 時(shí)所設(shè)置的數(shù)據(jù)一致。
★
若想獲取完整代碼鏈接,可關(guān)注本公眾號,回復(fù) MCP。
小結(jié)
本文介紹了 模型上下文協(xié)議(Model Context Protocol,MCP),一種用于規(guī)范大型語言模型(LLM)與外部數(shù)據(jù)源及工具之間交互的開放標(biāo)準(zhǔn)。內(nèi)容涵蓋了 MCP 協(xié)議的整體架構(gòu)(客戶端與服務(wù)器的一對一連接模式)、消息傳輸機(jī)制(采用 JSON-RPC 2.0 格式)、以及客戶端與服務(wù)器支持的核心原語,包括:
- 客戶端原語:roots(根路徑)、sampling(采樣)
- 服務(wù)器原語:prompts(提示詞)、resources(資源)、tools(工具)
- Server原語的控制層級分類
最后,本文提供了基于 Go 語言 的 MCP 客戶端與服務(wù)器的示例實(shí)現(xiàn),幫助開發(fā)者快速理解和應(yīng)用該協(xié)議。