返回市场
Go-MCP服务器

Go-MCP服务器

作者:ktr0731145 星标更新:2025-05-06

项目介绍

⚡ go-mcp

<div align="center"> <h3>一个类型安全且直观的Go SDK,用于MCP服务器开发</h3> </div> <p align="center"> <a href="#-what-is-go-mcp">🤔 什么是go-mcp?</a> • <a href="#-features">✨ 特性</a> • <a href="#-quick-start">🏁 快速开始</a> • <a href="#-examples">🔍 示例</a> • <a href="#-supported-features">✅ 支持的功能</a> • <a href="#-contributing">🤝 贡献</a> </p>

🤔 什么是go-mcp?

go-mcp 是一个用于轻松自信地构建MCP(模型上下文协议)服务器的Go SDK。它提供了一个类型安全且直观的接口,使得服务器开发变得简单。


✨ 特性

  • 🔒 类型安全 – 代码生成确保您的工具和提示参数是静态类型的,因此错误会在编译时被捕获而不是在运行时。
  • 🧩 简单直观的API – 提供一种自然且符合Go习惯用法的接口,让您能够快速构建服务器而无需陡峭的学习曲线。
  • 🔌 开发者友好 – 设计时考虑了API的人体工程学,使其易于接近。

🏁 快速开始

使用go-mcp创建一个MCP服务器非常简单!

目录结构

下面是一个温度转换MCP服务器的目录结构示例:

.
├── cmd
│   ├── mcpgen
│   │   └── main.go
│   └── temperature
│       └── main.go
├── mcp.gen.go
└── temperature.go

1. 定义MCP服务器

首先,在cmd/mcpgen/main.go中创建代码生成器。运行此文件会自动生成所需的代码。

package main

import (
    "log"
    "os"
    "path/filepath"

    "github.com/ktr0731/go-mcp/codegen"
)

func main() {
    // 创建输出目录
    outDir := "."
    if err := os.MkdirAll(outDir, 0o755); err != nil {
        log.Fatalf("创建输出目录失败: %v", err)
    }

    // 创建输出文件
    f, err := os.Create(filepath.Join(outDir, "mcp.gen.go"))
    if err != nil {
        log.Fatalf("创建文件失败: %v", err)
    }
    defer f.Close()

    // 服务器定义
    def := &codegen.ServerDefinition{
        Capabilities: codegen.ServerCapabilities{
            Tools:   &codegen.ToolCapability{},
            Logging: &codegen.LoggingCapability{},
        },
        Implementation: codegen.Implementation{
            Name:    "温度转换MCP服务器",
            Version: "1.0.0",
        },
        // 工具定义(使用Go结构体声明)
        Tools: []codegen.Tool{
            {
                Name:        "convert_temperature",
                Description: "在摄氏度和华氏度之间转换温度",
                InputSchema: struct {
                    Temperature float64 `json:"temperature" jsonschema:"description=要转换的温度值"`
                    FromUnit    string  `json:"from_unit"  jsonschema:"description=源温度单位,enum=celsius,enum=fahrenheit"`
                    ToUnit      string  `json:"to_unit"    jsonschema:"description=目标温度单位,enum=celsius,enum=fahrenheit"`
                }{},
            },
        },
    }

    // 生成代码
    if err := codegen.Generate(f, def, "temperature"); err != nil {
        log.Fatalf("生成代码失败: %v", err)
    }
}

生成代码:

go run ./cmd/mcpgen

2. 实现MCP服务器

接下来,在cmd/temperature/main.go中实现服务器逻辑:

package main

import (
    "context"
    "fmt"
    "log"
    "math"

    mcp "github.com/ktr0731/go-mcp"
    "golang.org/x/exp/jsonrpc2"
)

type toolHandler struct{}

func (h *toolHandler) HandleToolConvertTemperature(ctx context.Context, req *ToolConvertTemperatureRequest) (*mcp.CallToolResult, error) {
    temperature := req.Temperature
    fromUnit := req.FromUnit
    toUnit := req.ToUnit

    var result float64
    switch {
    case fromUnit == ConvertTemperatureFromUnitTypeCelsius && toUnit == ConvertTemperatureToUnitTypeFahrenheit:
        // °C → °F: (C × 9/5) + 32
        result = (temperature*9/5 + 32)
    case fromUnit == ConvertTemperatureFromUnitTypeFahrenheit && toUnit == ConvertTemperatureToUnitTypeCelsius:
        // °F → °C: (F − 32) × 5/9
        result = (temperature - 32) * 5 / 9
    case fromUnit == toUnit:
        result = temperature
    default:
        return nil, fmt.Errorf("不支持的转换: %s 到 %s", fromUnit, toUnit)
    }

    // 四舍五入到两位小数
    result = math.Round(result*100) / 100

    resultText := fmt.Sprintf("%.2f %s = %.2f %s", temperature, fromUnit, result, toUnit)

    return &mcp.CallToolResult{
        Content: []mcp.CallToolContent{
            mcp.TextContent{Text: resultText},
        },
    }, nil
}

func main() {
    handler := NewHandler(&toolHandler{})

    ctx, listener, binder := mcp.NewStdioTransport(context.Background(), handler, nil)
    srv, err := jsonrpc2.Serve(ctx, listener, binder)
    if err != nil {
        log.Fatalf("服务失败: %v", err)
    }

    srv.Wait()
}

运行服务器:

go run ./cmd/temperature

🔍 示例

查看完整的示例,请参阅示例目录API文档


✅ 支持的功能

  • Ping
  • 工具
  • 提示
  • 提示、工具、资源、资源模板
  • 资源订阅
  • 资源更新通知
  • 日志记录
  • 完成
  • 取消

🚧 正在开发

  • 批处理(JSON-RPC 2.0)
  • 可流式传输的HTTP传输
  • 进度通知

🚫 未计划

  • 动态提示和工具更改

    Go并不适合动态添加工具。动态添加工具需要在运行时构造工具定义、JSON Schema和处理器。虽然生成的代码保持类型安全,但动态添加的组件不会,这迫使大量使用any和类型断言,并损害接口的一致性。我们把这些用例委托给更适合动态变化的语言的SDK,如TypeScript。

    目前大多数已实现的MCP服务器仅使用静态定义,动态变化似乎还不是主要用例。


🤝 贡献

欢迎贡献!请随意提交拉取请求。


📄 许可证

本项目采用MIT许可证 – 详情见LICENSE文件。