MCP服务器框架

一个用Go编写的简单、可重用的模型上下文协议(MCP)服务器框架,支持多种传输机制,包括HTTP流、SSE和STDIO,可作为库或独立可执行文件使用。

  • by Protobomb
  • Go
  • 本地部署
  • 更新于
在 GitHub 查看 Protobomb/mcp-server-framework

使用说明

MCP服务器框架

一个用Go编写的简单、可重用的模型上下文协议(MCP)服务器框架。该框架支持多种传输机制,包括HTTP流(符合MCP)、SSE(服务器发送事件)和STDIO传输,既可以用作库,也可以用作独立的可执行文件。

特性

  • 🚀 多个传输:支持HTTP流(符合MCP)、SSE(服务器发送事件)和STDIO
  • 📦 图书馆和独立:用作Go库或作为独立服务器运行
  • 🧪 测试良好:全面的测试覆盖率
  • 🔄 JSON-RPC 2.0:完全支持JSON-RPC 2.0协议
  • 🌐 CORS已启用:为web客户端内置CORS支持
  • 🐳 容器化:Docker支持自动构建
  • ⚡ 易于使用:用于注册处理程序的简单API
  • 🔧 MCP客户端:用于测试和开发的全功能客户端实现

快速开始

作为独立服务器

# HTTP Streams transport (default)
go run cmd/mcp-server/main.go -addr=8080

# SSE transport
go run cmd/mcp-server/main.go -transport=sse -addr=8080

# STDIO transport
go run cmd/mcp-server/main.go -transport=stdio

作为图书馆

package main

import (
    "context"
    "encoding/json"
    "log"

    "github.com/protobomb/mcp-server-framework/pkg/transport"
    "github.com/protobomb/mcp-server-framework/pkg/mcp"
)

func main() {
    // Create transport (HTTP Streams, SSE, or STDIO)
    transport := transport.NewHTTPStreamsTransport(mcp.NewServerWithoutTransport(), transport.HTTPStreamsTransportOptions{})
    // transport := transport.NewSSETransport(":8080")
    // transport := transport.NewSTDIOTransport()

    // Create server
    server := mcp.NewServer(transport)

    // Register a custom handler
    server.RegisterHandler("greet", func(ctx context.Context, params json.RawMessage) (interface{}, error) {
        var greetParams struct {
            Name string `json:"name"`
        }
        
        if len(params) > 0 {
            json.Unmarshal(params, &greetParams)
        }
        
        return map[string]string{
            "message": "Hello, " + greetParams.Name + "!",
        }, nil
    })

    // Start server
    ctx := context.Background()
    if err := server.Start(ctx); err != nil {
        log.Fatal(err)
    }

    // Keep running...
    select {}
}

作为客户

package main

import (
    "context"
    "log"

    "github.com/openhands/mcp-server-framework/internal/transport"
    "github.com/openhands/mcp-server-framework/pkg/client"
    "github.com/openhands/mcp-server-framework/pkg/mcp"
)

func main() {
    // Create transport (STDIO or HTTP)
    transport := transport.NewSTDIOTransport("./mcp-server")
    // transport := transport.NewHTTPTransport("http://localhost:8080")

    // Create client
    client := client.NewClient(transport)
    defer client.Close()

    ctx := context.Background()

    // Initialize connection
    clientInfo := mcp.ServerInfo{
        Name:    "my-client",
        Version: "1.0.0",
    }
    
    result, err := client.Initialize(ctx, clientInfo)
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Server: %s v%s", result.ServerInfo.Name, result.ServerInfo.Version)

    // List available tools
    tools, err := client.ListTools(ctx)
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Available tools: %d", len(tools.Tools))

    // Call a tool
    params := map[string]interface{}{
        "message": "Hello from client!",
    }
    
    response, err := client.CallTool(ctx, "echo", params)
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Tool response: %v", response)
}

快速命令

# Build everything
make build-both

# Test the client
make run-client

# Try the interactive demo
make demo

# Run all tests
make test

安装

Go模块

go get github.com/openhands/mcp-server-framework

码头工人

docker pull ghcr.io/openhands/mcp-server-framework:latest

# Run with HTTP Streams transport (default)
docker run -p 8080:8080 ghcr.io/openhands/mcp-server-framework:latest

# Run with SSE transport
docker run -p 8080:8080 ghcr.io/openhands/mcp-server-framework:latest -transport=sse

# Run with STDIO transport
docker run -i ghcr.io/openhands/mcp-server-framework:latest -transport=stdio

运输选项

该框架支持多种传输机制,以适应不同的用例:

1.HTTP流传输(默认)

  • 符合MCP流式HTTP(2024-11-05)标准
  • 现代HTTP+SSE混合方法
  • 具有安全会话ID的内置会话管理
  • 批量请求支持,提高效率
  • 出色的代理和防火墙兼容性
  • 完全符合MCP规范
  • 端点: /mcp (发布/获取), /health (获取)
  • 📖 详细文件
# Start HTTP Streams server
./mcp-server -addr=8080

# Test with curl
curl http://localhost:8080/health

2.SSE(服务器发送事件)传输

  • 用于实时通信的自定义SSE实现
  • 通过SSE+HTTP POST进行双向通信
  • 内置会话管理
  • web浏览器的CORS支持
  • 端点: /sse (GET), /message (POST), /health (获取)
  • 📖 详细文件
# Start SSE server
./mcp-server -transport=sse -addr=8080

# Test SSE connection
curl -N -H "Accept: text/event-stream" http://localhost:8080/sse

3.STDIO传输

  • 标准输入/输出通信
  • 非常适合命令行工具和脚本
  • 轻便高效
  • 无网络依赖关系
# Start STDIO server
./mcp-server -transport=stdio

# Communicate via stdin/stdout
echo '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{}}' | ./mcp-server -transport=stdio

运输比较

特性 HTTP流 SSE传输 STDIO
MCP合规性 ✅ 已满(2024-11-05) ⚠️ 自定义 ✅ 标准
会话管理 ✅ 内置 ✅ 内置 ❌ 无
批量请求 ✅ 支持 ❌ 不支持 ✅ 支持
Web浏览器支持 ✅ 优秀 ✅ 好 ❌ 无
代理兼容性 ✅ 优秀 ⚠️ 有限 ❌ 无
需要网络 ✅ 是 ✅ 是 ❌ 没有
用例 Web应用程序、API 实时应用程序 CLI工具

api参考

服务器

创建服务器

server := mcp.NewServer(transport)

注册处理程序

// Request handler (expects response)
server.RegisterHandler("methodName", func(ctx context.Context, params json.RawMessage) (interface{}, error) {
    // Handle request and return result
    return result, nil
})

// Notification handler (no response expected)
server.RegisterNotificationHandler("notificationName", func(ctx context.Context, params json.RawMessage) error {
    // Handle notification
    return nil
})

服务器生命周期

// Start the server
err := server.Start(ctx)

// Send notifications to clients
err := server.SendNotification("eventName", eventData)

// Stop the server
err := server.Stop()

// Close the server
err := server.Close()

客户端

创建客户端

// With STDIO transport
transport := transport.NewSTDIOTransport("./mcp-server")
client := client.NewClient(transport)

// With HTTP transport
transport := transport.NewHTTPTransport("http://localhost:8080")
client := client.NewClient(transport)

客户端方法

// Initialize connection
clientInfo := mcp.ServerInfo{
    Name:    "my-client",
    Version: "1.0.0",
}
result, err := client.Initialize(ctx, clientInfo)

// List available tools
tools, err := client.ListTools(ctx)

// Call a tool
params := map[string]interface{}{
    "param1": "value1",
    "param2": 42,
}
response, err := client.CallTool(ctx, "toolName", params)

// Send notifications
err := client.Notify(ctx, "notificationName", params)

客户端生命周期

// Close the client
err := client.Close()

运输

STDIO传输

transport := transport.NewSTDIOTransport()
// or with custom IO
transport := transport.NewSTDIOTransportWithIO(reader, writer)

SSE 运输

transport := transport.NewSSETransport(":8080")

SSE 端点:

  • GET /sse -SSE事件流(带可选的sessionId参数)
  • POST /message -向服务器发送消息(需要?sessionId参数)
  • GET /health -健康检查

内置处理器

该框架包括这些内置的MCP处理程序:

  • initialize -MCP初始化握手
  • initialized -MCP初始化完成通知
  • tools/list -列出可用工具
  • tools/call -调用特定工具

内置工具

该框架包括以下示例工具:

  • echo -回显提供的消息
    • 参数: message (string)-要回显的消息
    • 返回:带有“Echo:{message}”的文本内容

测试

该框架包括单元测试和集成测试的全面测试。

快速测试

# Run all tests (unit + integration)
make test-all

# Run only unit tests
make test

# Run only integration tests
make test-integration

# Run tests with coverage
make test-coverage

# Run all checks (format, lint, test)
make check

测试覆盖率

该框架具有 42个综合测试用例 涵盖:

  • SSE 运输:14个测试,涵盖会话管理、消息处理、CORS、错误处理
  • STDIO传输:9个测试,涵盖传输生命周期和消息处理
  • MCP服务器:13项测试,涵盖处理程序、工具、功能和协议合规性
  • MCP客户端:14个测试,涵盖客户端操作、超时和错误处理

集成测试

自动集成测试:

  1. 使用SSE传输启动MCP服务器
  2. 测试完整的MCP协议流(初始化→ 已初始化→ 工具/列表→ 工具/调用)
  3. 验证请求/响应匹配和通知处理
  4. 清理服务器进程

手动测试

# Manual unit testing
go test ./pkg/...
go test -v -race ./pkg/...
go test -cover ./pkg/...

# Test with mcp-cli (requires Node.js)
./mcp-server -transport=sse -addr=8080 &
npx @modelcontextprotocol/cli connect sse http://localhost:8080/sse

# Test client with STDIO server
make test-client-stdio

# Test client with HTTP server  
make test-client-http

测试脚本

  • scripts/test_sse_integration.py -基于Python的SSE集成测试
  • scripts/test-examples.sh -基于Bash的端点测试脚本

建筑

# Build everything (server + client)
make build-both

# Build just the server
make build

# Build just the client
make build-client

# Run the client with help
make run-client

# Try the interactive demo
make demo

# Manual building
go build -o mcp-server cmd/mcp-server/main.go
go build -o mcp-client cmd/mcp-client/main.go

# Build for different platforms
GOOS=linux GOARCH=amd64 go build -o mcp-server-linux cmd/mcp-server/main.go
GOOS=windows GOARCH=amd64 go build -o mcp-server.exe cmd/mcp-server/main.go
GOOS=darwin GOARCH=amd64 go build -o mcp-server-darwin cmd/mcp-server/main.go

码头工人

# Build Docker image
docker build -t mcp-server-framework .

# Run with SSE transport (default)
docker run -p 8080:8080 mcp-server-framework

# Run with STDIO transport
docker run -i mcp-server-framework -transport=stdio

# Run with custom SSE address
docker run -p 9090:9090 mcp-server-framework -addr=9090

例子

使用测试客户端

# Test with STDIO server
./mcp-client -transport=stdio -command='./mcp-server'

# Test with HTTP server (start server first)
./mcp-server -transport=sse -addr=8080 &
./mcp-client -transport=http -addr=http://localhost:8080

# Interactive demo
make demo

原始STDIO客户端示例

echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | ./mcp-server

SSE客户端示例

// Generate or get session ID
const sessionId = 'your-session-id'; // or generate one

// Connect to SSE endpoint
const eventSource = new EventSource(`http://localhost:8080/sse?sessionId=${sessionId}`);

eventSource.onmessage = function(event) {
    const data = JSON.parse(event.data);
    console.log('Received:', data);
};

// Send a message
fetch(`http://localhost:8080/message?sessionId=${sessionId}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
        jsonrpc: '2.0',
        id: 1,
        method: 'echo',
        params: { message: 'Hello, World!' }
    })
});

文档

所有传输机制和功能都有全面的文档:

贡献

  1. 分叉存储库
  2. 创建要素分支
  3. 为您的更改添加测试
  4. 确保所有测试通过
  5. 提交拉取请求

许可证

MIT许可证-请参阅 许可证 文件以获取详细信息。

协议支持

该框架实现了模型上下文协议(MCP)规范:

  • JSON-RPC 2.0消息传递
  • 初始化握手
  • 请求/响应模式
  • 通知支持
  • 错误处理

有关MCP的更多信息,请访问 官方规范.