Skip to content

Go SDK

Model Context Protocol (MCP) 的 Go SDK 提供了构建 MCP 服务器和客户端的完整工具集。

安装

bash
go get github.com/modelcontextprotocol/go-sdk

快速开始

创建 MCP 服务器

go
package main

import (
    "context"
    "log"
    
    "github.com/modelcontextprotocol/go-sdk/mcp"
    "github.com/modelcontextprotocol/go-sdk/server"
)

func main() {
    // 创建服务器
    srv := server.New(server.Options{
        Name:    "my-go-server",
        Version: "1.0.0",
    })
    
    // 注册工具
    srv.RegisterTool("echo", &EchoTool{})
    
    // 启动服务器
    if err := srv.Serve(context.Background()); err != nil {
        log.Fatal(err)
    }
}

type EchoTool struct{}

func (t *EchoTool) Call(ctx context.Context, args map[string]interface{}) (interface{}, error) {
    message, ok := args["message"].(string)
    if !ok {
        return nil, fmt.Errorf("message parameter is required")
    }
    
    return map[string]string{
        "echo": message,
    }, nil
}

func (t *EchoTool) Schema() mcp.ToolSchema {
    return mcp.ToolSchema{
        Name:        "echo",
        Description: "回显输入的消息",
        InputSchema: mcp.Schema{
            Type: "object",
            Properties: map[string]mcp.Schema{
                "message": {
                    Type:        "string",
                    Description: "要回显的消息",
                },
            },
            Required: []string{"message"},
        },
    }
}

创建 MCP 客户端

go
package main

import (
    "context"
    "log"
    
    "github.com/modelcontextprotocol/go-sdk/client"
    "github.com/modelcontextprotocol/go-sdk/transport"
)

func main() {
    // 创建传输层
    transport := transport.NewStdio()
    
    // 创建客户端
    client := client.New(client.Options{
        Transport: transport,
    })
    
    // 连接到服务器
    if err := client.Connect(context.Background()); err != nil {
        log.Fatal(err)
    }
    defer client.Close()
    
    // 列出可用工具
    tools, err := client.ListTools(context.Background())
    if err != nil {
        log.Fatal(err)
    }
    
    log.Printf("可用工具: %+v", tools)
    
    // 调用工具
    result, err := client.CallTool(context.Background(), "echo", map[string]interface{}{
        "message": "Hello from Go!",
    })
    if err != nil {
        log.Fatal(err)
    }
    
    log.Printf("工具调用结果: %+v", result)
}

核心功能

服务器功能

  • 工具注册: 注册自定义工具供客户端调用
  • 资源管理: 提供文件、数据库等资源访问
  • 提示模板: 定义可重用的提示模板
  • 传输协议: 支持 stdio、WebSocket 等传输方式

客户端功能

  • 服务器连接: 连接到本地或远程 MCP 服务器
  • 工具调用: 调用服务器提供的工具
  • 资源访问: 读取服务器资源
  • 会话管理: 管理与服务器的会话状态

传输协议

Stdio 传输

go
transport := transport.NewStdio()

WebSocket 传输

go
transport := transport.NewWebSocket("ws://localhost:8080/mcp")

HTTP SSE 传输

go
transport := transport.NewSSE("http://localhost:8080/mcp")

最佳实践

错误处理

go
func (t *MyTool) Call(ctx context.Context, args map[string]interface{}) (interface{}, error) {
    // 验证参数
    if err := t.validateArgs(args); err != nil {
        return nil, fmt.Errorf("参数验证失败: %w", err)
    }
    
    // 执行业务逻辑
    result, err := t.execute(ctx, args)
    if err != nil {
        return nil, fmt.Errorf("执行失败: %w", err)
    }
    
    return result, nil
}

上下文管理

go
func (s *MyServer) handleRequest(ctx context.Context, req *mcp.Request) {
    // 设置超时
    ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
    defer cancel()
    
    // 处理请求
    // ...
}

并发安全

go
type SafeServer struct {
    mu    sync.RWMutex
    tools map[string]Tool
}

func (s *SafeServer) RegisterTool(name string, tool Tool) {
    s.mu.Lock()
    defer s.mu.Unlock()
    s.tools[name] = tool
}

配置选项

服务器配置

go
srv := server.New(server.Options{
    Name:        "my-server",
    Version:     "1.0.0",
    Description: "我的 MCP 服务器",
    MaxConnections: 100,
    ReadTimeout:    30 * time.Second,
    WriteTimeout:   30 * time.Second,
})

客户端配置

go
client := client.New(client.Options{
    Transport:      transport,
    ConnectTimeout: 10 * time.Second,
    RequestTimeout: 30 * time.Second,
    RetryAttempts:  3,
})

测试

单元测试

go
func TestEchoTool(t *testing.T) {
    tool := &EchoTool{}
    
    result, err := tool.Call(context.Background(), map[string]interface{}{
        "message": "test",
    })
    
    assert.NoError(t, err)
    assert.Equal(t, map[string]string{"echo": "test"}, result)
}

集成测试

go
func TestServerClient(t *testing.T) {
    // 启动测试服务器
    srv := server.New(server.Options{Name: "test-server"})
    srv.RegisterTool("echo", &EchoTool{})
    
    go srv.Serve(context.Background())
    defer srv.Close()
    
    // 创建客户端并测试
    client := client.New(client.Options{
        Transport: transport.NewStdio(),
    })
    
    err := client.Connect(context.Background())
    assert.NoError(t, err)
    defer client.Close()
    
    result, err := client.CallTool(context.Background(), "echo", map[string]interface{}{
        "message": "test",
    })
    assert.NoError(t, err)
    assert.NotNil(t, result)
}

部署

Docker 部署

dockerfile
FROM golang:1.21-alpine AS builder

WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN go build -o mcp-server ./cmd/server

FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/

COPY --from=builder /app/mcp-server .

CMD ["./mcp-server"]

系统服务

ini
[Unit]
Description=MCP Go Server
After=network.target

[Service]
Type=simple
User=mcp
ExecStart=/usr/local/bin/mcp-server
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

相关资源

社区支持

🚀 探索模型上下文协议的无限可能 | 连接 AI 与世界的桥梁 | 让智能更智能