一文弄懂用Go實現MCP服務的示例代碼
最近這段時間,AI領域里有一個非常熱門的概念——MCP(模型上下文協議)。Anthropic推出的這一開放標準旨在為大型語言模型和AI助手提供統(tǒng)一的接口,使其能夠輕松操作外部工具并完成更復雜的任務。
本文將帶你速覽MCP的核心概念,并以Go語言為例,介紹如何開發(fā)MCP服務端和客戶端。
為什么MCP如此重要?
在過去,如果想要讓AI處理特定的數據,通常只能依賴于預訓練數據或者手動上傳數據,這既麻煩又低效。即便對于強大的AI模型而言,也存在數據隔離的問題,無法直接訪問新的數據源,每次更新數據都需要重新訓練或上傳?,F在,MCP解決了這個問題,它使得AI不再局限于靜態(tài)知識庫,而是能夠像人類一樣調用搜索引擎、訪問本地文件、連接API服務等,極大提升了AI的動態(tài)交互能力。
MCP總體架構
MCP的核心是“客戶端-服務器”架構,其中MCP客戶端可以連接到多個服務器。客戶端是指希望通過MCP訪問數據的應用程序,如CLI工具、IDE插件或AI應用。

使用mcp-go構建MCP服務端與客戶端
要開始使用Go語言構建MCP項目,首先需要安裝mcp-go庫,這是Go語言實現的Model Context Protocol庫,支持LLM應用與外部數據源和工具之間的無縫集成。
go get github.com/mark3labs/mcp-go
構建MCP服務端
接下來,我們將演示如何使用mcp-go提供的server模塊來構建一個通過stdio方式連接的MCP服務器。
創(chuàng)建Server對象
s := server.NewMCPServer("My Server", "1.0.0")
添加工具(Tools)
例如,我們可以創(chuàng)建一個簡單的計算器工具,這次我們實現乘法和除法功能:
calculatorTool := mcp.NewTool("calculate",
mcp.WithDescription("執(zhí)行基本的算術運算"),
mcp.WithString("operation",
mcp.Required(),
mcp.Description("要執(zhí)行的算術運算類型"),
mcp.Enum("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 "multiply":
result = x * y
case "divide":
if y == 0 {
return nil, errors.New("不允許除以零")
}
result = x / y
}
return mcp.FormatNumberResult(result), nil
})
- 添加資源(Resources)
同樣地,我們也可以注冊一些靜態(tài)資源,比如README.md文件的內容:
resource := mcp.NewResource(
"docs://readme",
"項目說明文檔",
mcp.WithResourceDescription("項目的 README 文件"),
mcp.WithMIMEType("text/markdown"),
)
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",
MIMEType: "text/markdown",
Text: string(content),
},
}, nil
})
- 啟動基于stdio傳輸類型的服務器
if err := server.ServeStdio(s); err != nil {
fmt.Printf("Server error: %v\n", err)
}
以上步驟完成后,我們就成功搭建了一個基礎的MCP服務器。
構建MCP客戶端
接著,我們將展示如何使用mcp-go提供的client模塊構建一個連接至上述MCP服務器的客戶端。
- 創(chuàng)建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()
initRequest := mcp.InitializeRequest{}
initRequest.Params.ProtocolVersion = mcp.LATEST_PROTOCOL_VERSION
initRequest.Params.ClientInfo = mcp.Implementation{
Name: "Client Demo",
Version: "1.0.0",
}
initResult, err := mcpClient.Initialize(ctx, initRequest)
if err != nil {
panic(err)
}
fmt.Printf("初始化成功,服務器信息: %s %s\n", initResult.ServerInfo.Name, initResult.ServerInfo.Version)
- 調用遠程工具
最后,我們可以通過構造CallToolRequest來調用服務器上的工具,如下所示:
toolRequest := mcp.CallToolRequest{
Request: mcp.Request{
Method: "tools/call",
},
}
toolRequest.Params.Name = "calculate"
toolRequest.Params.Arguments = map[string]any{
"operation": "multiply", // 調用乘法
"x": 2,
"y": 3,
}
result, err := mcpClient.CallTool(ctx, toolRequest)
if err != nil {
panic(err)
}
fmt.Println("調用工具結果:", result.Content[0].(mcp.TextContent).Text)
完整代碼示例
以下是完整的代碼示例,包括服務端和客戶端的實現:
服務端代碼:
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í)行基本的算術運算"),
mcp.WithString("operation",
mcp.Required(),
mcp.Description("要執(zhí)行的算術運算類型"),
mcp.Enum("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 "multiply":
result = x * y
case "divide":
if y == 0 {
return nil, errors.New("不允許除以零")
}
result = x / y
}
return mcp.FormatNumberResult(result), nil
})
// 啟動基于 stdio 的服務器
if err := server.ServeStdio(s); err != nil {
fmt.Printf("Server error: %v\n", err)
}
}
客戶端代碼:
package main
import (
"context"
"fmt"
"time"
"github.com/mark3labs/mcp-go/client"
"github.com/mark3labs/mcp-go/mcp"
)
func main() {
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()
initRequest := mcp.InitializeRequest{}
initRequest.Params.ProtocolVersion = mcp.LATEST_PROTOCOL_VERSION
initRequest.Params.ClientInfo = mcp.Implementation{
Name: "Client Demo",
Version: "1.0.0",
}
initResult, err := mcpClient.Initialize(ctx, initRequest)
if err != nil {
panic(err)
}
fmt.Printf("初始化成功,服務器信息: %s %s\n", initResult.ServerInfo.Name, initResult.ServerInfo.Version)
// 調用工具
toolRequest := mcp.CallToolRequest{
Request: mcp.Request{
Method: "tools/call",
},
}
toolRequest.Params.Name = "calculate"
toolRequest.Params.Arguments = map[string]any{
"operation": "multiply",
"x": 2,
"y": 3,
}
result, err := mcpClient.CallTool(ctx, toolRequest)
if err != nil {
panic(err)
}
fmt.Println("調用工具結果:", result.Content[0].(mcp.TextContent).Text)
}
希望這篇文章能幫助你快速入門Go語言下的MCP開發(fā)!
到此這篇關于一文弄懂用Go實現MCP服務的示例代碼的文章就介紹到這了,更多相關Go MCP服務內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Golang 實現 Redis系列(六)如何實現 pipeline 模式的 redis 客戶端
pipeline 模式的 redis 客戶端需要有兩個后臺協程負責 tcp 通信,調用方通過 channel 向后臺協程發(fā)送指令,并阻塞等待直到收到響應,本文是使用 golang 實現 redis 系列的第六篇, 將介紹如何實現一個 Pipeline 模式的 Redis 客戶端。2021-07-07
Go使用Protocol?Buffers在數據序列化的優(yōu)勢示例詳解
這篇文章主要為大家介紹了Go使用Protocol?Buffers在數據序列化的優(yōu)勢示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-11-11

