MCP Go SDK
2026年1月12日 · 375 字 · 2 分钟
mcp简介以及mcp go adk的服务端以及客户端的使用
MCP Go SDK
MCP
什么是MCP
每个人都会开发各种工具,工具除了自己调用,可以让别人调用,假如我用eino写个工具,langchain怎么调用呢,所以产生了mcp,可以理解为协议,便于各种语言和框架调用
MCP的三种通讯方式
- Stdio
- SSE
- Streamable Http
MCP Go SDK
25年7月,谷歌协助mcp组织进行了go sdk,由此MCP Go SDK孕育而生
MCP http 服务端
在这里通过http启动一个mcp服务
需要的包
"github.com/modelcontextprotocol/go-sdk/mcp"
获取时间
type TimeInput struct {
TimeZone string `json:"time_zone" jsonschema:"时区"`
}
type TimeOutput struct {
Time string `json:"time" jsonschema:"当前时间"`
}
func GetCurrentTime(ctx context.Context, req *mcp.CallToolRequest, intput *TimeInput) (*mcp.CallToolResult, *TimeOutput, error) {
if len(intput.TimeZone) == 0 {
intput.TimeZone = "Asia/Shanghai"
}
loc, err := time.LoadLocation(intput.TimeZone)
if err != nil {
return nil, nil, fmt.Errorf("failed to load location: %w", err)
}
now := time.Now().In(loc)
return nil, &TimeOutput{Time: now.Format("2006-01-02 15:04:05")}, nil
}
获取城市
const (
ip = "XX.XX.XX.XX"
GAODE_KEY = "xxxx"
)
type LocationResponse struct {
Status string `json:"status"`
Province string `json:"province"`
City string `json:"city"`
Adcode string `json:"adcode"`
}
func GetLocation(ctx context.Context, req *mcp.CallToolRequest, intput struct{}) (*mcp.CallToolResult, *LocationResponse, error) {
url := fmt.Sprintf("https://restapi.amap.com/v3/ip?key=%s&ip=%s", GAODE_KEY, ip)
data, err := HttpGet(url)//HttpGet为包装的http的get请求方法,返回值为请求体
if err != nil {
return nil, nil, fmt.Errorf("failed to get location: %w", err)
}
var location LocationResponse
err = sonic.Unmarshal(data, &location)
if err != nil {
return nil, nil, fmt.Errorf("failed to unmarshal location: %w", err)
}
if location.Status != "1" {
return nil, nil, fmt.Errorf("failed to get location: %w", err)
}
return nil, &location, nil
}
启动服务
func main() {
server := mcp.NewServer(&mcp.Implementation{
Name: "easy_mcp",
Version: "1.0.0",
}, nil)
mcp.AddTool(server, &mcp.Tool{
Name: "time_tool",
Description: "获取当前时间",
}, GetCurrentTime)
mcp.AddTool(server, &mcp.Tool{
Name: "location_tool",
Description: "获取当前位置",
}, GetLocation)
//http的server
handler := mcp.NewStreamableHTTPHandler(
func(*http.Request) *mcp.Server {
return server
}, &mcp.StreamableHTTPOptions{},
)
http.HandleFunc("/mcp", handler.ServeHTTP)
log.Fatal(http.ListenAndServe(":8080", nil))
}
MCP http 客户端
func main() {
ctx := context.Background()
client := mcp.NewClient(&mcp.Implementation{
Name: "easy_mcp",
Version: "1.0.0",
}, nil)
transport := &mcp.StreamableClientTransport{
Endpoint: "http://127.0.0.1:8080/mcp",
HTTPClient: &http.Client{
Timeout: 10 * time.Second,
},
}
session, err := client.Connect(ctx, transport, nil)
if err != nil {
log.Fatal(err)
}
defer session.Close()
resp, err := session.CallTool(ctx, &mcp.CallToolParams{
Name: "time_tool",
Arguments: map[string]any{
"time_zone": "Asia/Shanghai",
},
})
if err != nil {
log.Fatal("time_tool call failed:", err)
}
if resp.IsError {
log.Fatal("time_tool returned error, content:", resp.Content)
}
resp1, err := session.CallTool(ctx, &mcp.CallToolParams{
Name: "location_tool",
Arguments: map[string]any{},
})
if err != nil {
log.Fatal("location_tool call failed:", err)
}
if resp1.IsError {
log.Fatal("location_tool returned error, content:", resp1.Content)
}
for _, c := range resp.Content {
fmt.Println(c.(*mcp.TextContent).Text)
}
for _, c := range resp1.Content {
fmt.Println(c.(*mcp.TextContent).Text)
}
}
调用结果
{"time":"2026-01-12 15:29:07"}
{"adcode":"150000","city":"呼和浩特市","province":"内蒙古自治区","status":"1"}