一文帶你學(xué)會(huì)使用Go語(yǔ)言實(shí)現(xiàn)自己的MCP服務(wù)端
最近這段時(shí)間,AI領(lǐng)域里有一個(gè)非常熱門(mén)的概念——MCP(模型上下文協(xié)議) 。Anthropic推出的這一開(kāi)放標(biāo)準(zhǔn)旨在為大型語(yǔ)言模型和AI助手提供統(tǒng)一的接口,使其能夠輕松操作外部工具并完成更復(fù)雜的任務(wù)。
本文將帶你速覽MCP的核心概念,并以Go語(yǔ)言為例,介紹如何開(kāi)發(fā)MCP服務(wù)端和客戶端,并且用cursor和vscode調(diào)用自己開(kāi)發(fā)的MCP服務(wù)器。
為什么MCP如此重要?
在過(guò)去,如果想要讓AI處理特定的數(shù)據(jù),通常只能依賴于預(yù)訓(xùn)練數(shù)據(jù)或者手動(dòng)上傳數(shù)據(jù),這既麻煩又低效。即便對(duì)于強(qiáng)大的AI模型而言,也存在數(shù)據(jù)隔離的問(wèn)題,無(wú)法直接訪問(wèn)新的數(shù)據(jù)源,每次更新數(shù)據(jù)都需要重新訓(xùn)練或上傳?,F(xiàn)在,MCP解決了這個(gè)問(wèn)題,它使得AI不再局限于靜態(tài)知識(shí)庫(kù),而是能夠像人類一樣調(diào)用搜索引擎、訪問(wèn)本地文件、連接API服務(wù)等,極大提升了AI的動(dòng)態(tài)交互能力。
MCP總體架構(gòu)
MCP的核心是“客戶端-服務(wù)器”架構(gòu),其中MCP客戶端可以連接到多個(gè)服務(wù)器??蛻舳耸侵赶Mㄟ^(guò)MCP訪問(wèn)數(shù)據(jù)的應(yīng)用程序,如CLI工具、IDE插件或AI應(yīng)用。

GO 構(gòu)建MCP服務(wù)端
package main
import (
"context"
"errors"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
"log"
)
func main() {
s := server.NewMCPServer("CalculatorServer", "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("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 "multiply":
result = x * y
case "divide":
if y == 0 {
return nil, errors.New("不允許除以零")
}
result = x / y
}
return mcp.FormatNumberResult(result), nil
})
//sseServer := server.NewSSEServer(s, server.WithBaseURL("http://localhost:8082"))
//log.Printf("SSE server listening on :8082")
//if err := sseServer.Start(":8082"); err != nil {
// log.Fatalf("Server error: %v", err)
//}
// 啟動(dòng)基于 stdio 的服務(wù)器
if err := server.ServeStdio(s); err != nil {
log.Printf("Server error: %v\n", err)
}
}
執(zhí)行go build -o mcp-server main.go命令,生成服務(wù)器端可執(zhí)行文件
GO 構(gòu)建MCP服務(wù)端
package main
import (
"context"
"fmt"
"os"
"strconv"
"time"
"github.com/mark3labs/mcp-go/client"
"github.com/mark3labs/mcp-go/mcp"
)
func main() {
if len(os.Args) < 2 {
fmt.Println("請(qǐng)?zhí)峁┲辽僖粋€(gè)參數(shù)。")
return
}
// 輸出程序名稱
// 遍歷并輸出所有參數(shù)
a, _ := strconv.ParseFloat(os.Args[1], 64)
b, _ := strconv.ParseFloat(os.Args[2], 64)
// 這里的路徑是上面編譯的mcp-server可執(zhí)行文件
mcpClient, err := client.NewStdioMCPClient("/Users/yourusername/Workspace/go/src/mcp-server/mcp-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("初始化成功,服務(wù)器信息: %s %s\n", initResult.ServerInfo.Name, initResult.ServerInfo.Version)
// 調(diào)用工具
toolRequest := mcp.CallToolRequest{
Request: mcp.Request{
Method: "tools/call",
},
}
toolRequest.Params.Name = "calculate"
toolRequest.Params.Arguments = map[string]any{
"operation": "multiply",
"x": a,
"y": b,
}
result, err := mcpClient.CallTool(ctx, toolRequest)
if err != nil {
panic(err)
}
fmt.Printf("%f * %f = %s\n", a, b, result.Content[0].(mcp.TextContent).Text)
}
運(yùn)行客戶端
go run main.go 4 6
初始化成功,服務(wù)器信息: CalculatorServer 1.0.0
4.000000 * 6.000000 = 24.00
vs code調(diào)用 GO MCP服務(wù)端
vscode 主要是通過(guò)cline插件運(yùn)行MCP服務(wù)
安裝cline插件

配置cline插件的MCP服務(wù)

增加如下配置
{
"mcpServers": {
"mcp-calculator-server": {
"command": "/Users/yourusername/Workspace/go/src/mcp-server/mcp-server"
}
}
}
配置成功后即可看到如下信息

cursor 調(diào)用 GO MCP服務(wù)端
配置MCP服務(wù)器調(diào)用

添加如下配置
{
"mcpServers": {
"mcp-calculator-server": {
"command": "/Users/yourusername/Workspace/go/src/mcp-server/mcp-server"
}
}
}
配置成功后,看到如下信息

然后去聊天對(duì)話框中問(wèn)大模型,可以看到它調(diào)用了自定義的MCP服務(wù)

總結(jié)
本文以 Go 語(yǔ)言為例,教你開(kāi)發(fā) MCP 服務(wù)端與客戶端,并用 Cursor 和 VSCode 調(diào)用。
到此這篇關(guān)于一文帶你學(xué)會(huì)使用Go語(yǔ)言實(shí)現(xiàn)自己的MCP服務(wù)端的文章就介紹到這了,更多相關(guān)Go實(shí)現(xiàn)MCP服務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用golang寫(xiě)一個(gè)redis-cli的方法示例
這篇文章主要介紹了使用golang寫(xiě)一個(gè)redis-cli的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10
golang中的string與其他格式數(shù)據(jù)的轉(zhuǎn)換方法詳解
這篇文章主要介紹了golang中的string與其他格式數(shù)據(jù)的轉(zhuǎn)換方法,文章通過(guò)代碼示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-10-10
Go?語(yǔ)言入門(mén)之Go?計(jì)時(shí)器介紹
這篇文章主要介紹了Go?語(yǔ)言入門(mén)之Go?計(jì)時(shí)器,文章基于GO語(yǔ)言的相關(guān)資料展開(kāi)對(duì)其中計(jì)時(shí)器的詳細(xì)內(nèi)容。具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-05-05
Go內(nèi)存分配之結(jié)構(gòu)體優(yōu)化技巧
這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言內(nèi)存分配之結(jié)構(gòu)體優(yōu)化技巧的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-11-11
Go語(yǔ)言死鎖與goroutine泄露問(wèn)題的解決
最近在工作中使用golang編程,今天的文章給大家分享一下Go語(yǔ)言死鎖與goroutine泄露問(wèn)題,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07
Go語(yǔ)言Seeker接口與文件斷點(diǎn)續(xù)傳實(shí)戰(zhàn)教程
Go語(yǔ)言的io包中Seeker接口為大文件處理或需要隨機(jī)訪問(wèn)的場(chǎng)景提供了強(qiáng)大的支持,本文通過(guò)具體案例詳細(xì)介紹了Seeker接口的應(yīng)用,包括隨機(jī)訪問(wèn)大文件、斷點(diǎn)續(xù)傳等場(chǎng)景,以及如何使用Seeker接口進(jìn)行有效的文件讀寫(xiě)操作2024-10-10
golang多次讀取http request body的問(wèn)題分析
這篇文章主要給大家分析了golang多次讀取http request body的問(wèn)題,文中通過(guò)代碼示例和圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-01-01

