MCP服务器包

一个可重用的Go包,用于构建符合MCP协议的服务器,支持多种传输方式和授权策略。

  • by vubon
  • Go
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 vubon/go-mcp-server

使用说明

MCP服务器包

一个可重用的Go包,用于构建MCP(模型上下文协议)服务器。

特性

  • ✅ 符合MCP协议 -完全支持MCP模式版本(2024-11-05、2025-03-26、2025-06-18)
  • ✅ 结构化日志记录 -JSON格式,兼容Datadog,异步,零延迟
  • ✅ 基于文件和程序化配置 -通过JSON/YAML或编程API注册声明性工具
  • ✅ 多个传输 -HTTP和Stdio支持
  • ✅ 授权策略 -灵活的身份验证处理(传递、转换、静态、基本、无)

📚 查看完整文档

快速开始

1.创建具有结构化日志记录的服务器

package main

import (
    "log"
    "net/http"
    
    "github.com/vubon/go-mcp-server"
    "github.com/vubon/go-mcp-server/transport"
)

func main() {
    // Create structured logger
    logger := mcpserver.NewLogger(&mcpserver.LoggerConfig{
        Level:  "info",
        Format: "json",
    })

    // Create server with logger
    server := mcpserver.New(&mcpserver.Config{
        Name:    "greeter",
        Version: "1.0.0",
        Logger:  logger,
    })
    
    // Register tools from JSON/YAML files (recommended)
    err := server.RegisterToolsFromFiles("tools.json", "handlers.json")
    if err != nil {
        log.Fatalf("Failed to register tools: %v", err)
    }
    
    // Create HTTP transport and start server
    httpHandler := transport.NewHTTP(server)
    http.Handle("/jsonrpc", httpHandler)
    
    if logger := server.GetLogger(); logger != nil {
        logger.Info("Server starting",
            mcpserver.F("port", "8080"),
        )
    }
    
    log.Fatal(http.ListenAndServe(":8080", nil))
}

api参考

服务器

// Create structured logger (optional, but recommended)
logger := mcpserver.NewLogger(&mcpserver.LoggerConfig{
    Level:  "info",
    Format: "json",
})

// New creates a new MCP server
server := mcpserver.New(&mcpserver.Config{
    Name:            "my-server",
    Version:         "1.0.0",
    ProtocolVersion: mcpserver.SchemaVersion2025_06_18, // optional, defaults to latest (2025-06-18)
    Logger:          logger, // optional, but recommended for production
})

MCP架构版本:

  • mcpserver.SchemaVersion2024_11_05 -初始/旧版本
  • mcpserver.SchemaVersion2025_03_26 -首次重大更新
  • mcpserver.SchemaVersion2025_06_18 -最新稳定版本(默认,使用JSON模式2020-12)

注册工具

程序化注册:

tool := mcpserver.Tool{
    Name:        "tool_name",
    Description: "Tool description",
    InputSchema: map[string]interface{}{
        // JSON Schema definition
    },
}
server.RegisterTool("tool_name", &tool, func(ctx context.Context, args map[string]interface{}) (interface{}, error) {
    // Tool implementation
    return result, nil
})

基于文件的注册:

// Register from files (auto-detects JSON/YAML)
err := server.RegisterToolsFromFiles("tools.json", "handlers.json")

// Or register from byte data
toolsData, _ := os.ReadFile("tools.json")
handlersData, _ := os.ReadFile("handlers.json")
err := server.RegisterToolsFromJSON(toolsData, handlersData)
// or
err := server.RegisterToolsFromYAML(toolsData, handlersData)

HTTP传输

httpHandler := transport.NewHTTP(server)
http.Handle("/jsonrpc", httpHandler)
http.ListenAndServe(":8080", nil)

标准运输

stdioTransport := transport.NewStdio(server)
// Run blocks until context is cancelled
stdioTransport.Run(context.Background())

基于文件的工具注册

从JSON或YAML文件注册工具,而无需编写Go代码。这允许您声明性地定义工具及其HTTP处理程序。

📚 查看完整的基于文件的注册指南

授权

MCP服务器支持多种授权策略来处理身份验证标头:

  • 通过:按原样转发客户端授权(默认)
  • 变换:修改授权头格式
  • 静态:使用固定的授权值
  • 基础:基本身份验证编码
  • 无:明确禁用授权

📚 查看完整的授权文档

示例

package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "os/signal"
    "syscall"
    
    "github.com/vubon/go-mcp-server"
    "github.com/vubon/go-mcp-server/transport"
)

func main() {
    // Create structured logger
    logger := mcpserver.NewLogger(&mcpserver.LoggerConfig{
        Level:  "info",
        Format: "json",
    })

    // Create server with logger
    server := mcpserver.New(&mcpserver.Config{
        Name:    "my-server",
        Version: "1.0.0",
        Logger:  logger,
    })
    
    // Register tools programmatically or from files
    greetTool := mcpserver.Tool{
        Name:        "greet",
        Description: "Greets a person by name",
        InputSchema: map[string]interface{}{
            "type": "object",
            "properties": map[string]interface{}{
                "name": map[string]interface{}{
                    "type":        "string",
                    "description": "Name of the person to greet",
                },
            },
            "required": []string{"name"},
        },
    }
    server.RegisterTool("greet", &greetTool, func(ctx context.Context, args map[string]interface{}) (interface{}, error) {
        name, ok := args["name"].(string)
        if !ok {
            return nil, fmt.Errorf("invalid parameter: name must be a string")
        }
        
        // Handlers can make HTTP API calls, access databases, call external services, etc.
        // The ctx parameter can be used for cancellation, timeouts, and request tracing
        
        return map[string]string{
            "greeting": "Hello, " + name + "!",
        }, nil
    })
    
    // Setup graceful shutdown
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()
    
    sigChan := make(chan os.Signal, 1)
    signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
    
    go func() {
        <-sigChan
        if logger := server.GetLogger(); logger != nil {
            logger.Info("Shutting down...")
        }
        cancel()
    }()
    
    // Create stdio transport
    stdioTransport := transport.NewStdio(server)
    if logger := server.GetLogger(); logger != nil {
        logger.Info("MCP Server (stdio) starting",
            mcpserver.F("transport", "stdio"),
        )
    }
    
    if err := stdioTransport.Run(ctx); err != nil && err != context.Canceled {
        log.Fatalf("Transport error: %v", err)
    }
    
    // Gracefully shutdown logger (flushes pending logs)
    if closeLogger, ok := logger.(interface{ Close() error }); ok {
        _ = closeLogger.Close()
    }
}

许可证

麻省理工学院