MCP协议服务器

一个基于Go语言实现的最小化、符合标准的Model Context Protocol (MCP)服务器,提供HTTP端点进行MCP通信,并展示了一个清晰、可扩展的架构。

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

使用说明

MCP Go服务器

Go中符合标准的最小模型上下文协议(MCP)服务器实现。此服务器为MCP通信提供基于HTTP的端点,并仅使用Go标准库演示了一个干净、可扩展的架构。

安装

  1. 克隆或下载此存储库:
git clone <repository-url>
cd mcp-server
  1. 初始化依赖关系(如果需要):
go mod tidy
  1. 构建项目:
go build .

用法

启动服务器

主MCP服务器(端口3333)

运行主服务器:

go run .

服务器将在端口上启动 3333 并记录可用端点:

文件系统MCP服务器(端口3335)

如果您的系统中配置了文件系统MCP mcp-config.json,您需要单独启动文件系统服务器:

选项1:使用脚本

./start-filesystem-server.sh

选项2:直接命令

go run ./cmd/filesystem-server/main.go

文件系统服务器将在端口上启动 3335 并提供文件系统操作。

注: 两台服务器可以同时运行。主服务器(端口3333)充当网关,配置后可以连接到文件系统服务器(端口3335)。

MCP Server starting on port :3333
Endpoints available:
  GET  /initialize
  GET  /tools/list
  POST /tools/call

API终点

1.初始化

端点: GET /initialize

说明: 初始化MCP连接并返回服务器功能。

答复:

{
  "protocolVersion": "2024-11-05",
  "capabilities": {
    "tools": true
  },
  "serverInfo": {
    "name": "mcp-go",
    "version": "0.1.0"
  }
}

例子:

curl http://localhost:3333/initialize

2.列出工具

端点: GET /tools/list

说明: 返回可用工具及其模式的列表。

答复:

{
  "tools": [
    {
      "name": "echo",
      "description": "Echo back the provided message",
      "inputSchema": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "The message to echo back"
          }
        },
        "required": ["message"]
      }
    }
  ]
}

例子:

curl http://localhost:3333/tools/list

3.调用工具

端点: POST /tools/call

说明: 使用提供的参数执行工具。

请求正文:

{
  "name": "echo",
  "arguments": {
    "message": "Hello, MCP!"
  }
}

答复:

{
  "content": [
    {
      "type": "text",
      "text": "Hello, MCP!"
    }
  ]
}

例子:

curl -X POST http://localhost:3333/tools/call \
  -H "Content-Type: application/json" \
  -d '{"name":"echo","arguments":{"message":"Hello, MCP!"}}'

错误响应:

  • 404 Not Found:无法识别工具名称
  • 400 Bad Request:JSON无效或缺少必需的参数
  • 405 Method Not Allowed:使用了错误的HTTP方法

4.谷歌PSE搜索工具

工具名称: google_pse_search

说明: 使用谷歌可编程搜索引擎搜索网络

请求正文:

{
  "name": "google_pse_search",
  "arguments": {
    "query": "Go programming language",
    "num": 5,
    "start": 1
  }
}

答复:

{
  "content": [
    {
      "type": "text",
      "text": "Found 1000000 results:\n\n1. Go Programming Language\n   URL: https://go.dev/\n   The Go programming language is an open source project...\n\n..."
    }
  ]
}

论据:

  • query (必填):搜索查询字符串
  • num (可选):结果数量(1-10,默认值:10)
  • start (可选):开始分页索引(默认值:1)

例子:

curl -X POST http://localhost:3333/tools/call \
  -H "Content-Type: application/json" \
  -d '{"name":"google_pse_search","arguments":{"query":"MCP protocol","num":5}}'

注: 需要在中配置Google PSE API密钥和搜索引擎ID mcp-config.json 或环境变量。

项目结构

mcp-server/
├── go.mod                    # Go module definition
├── main.go                   # Application entry point
├── README.md                 # This file
├── mcp-config.json.example  # Example configuration file
├── client/                   # MCP client implementation
│   └── client.go           # Client interface and HTTP client
├── config/                   # Configuration management
│   └── config.go           # Config loading and parsing
├── gateway/                  # Gateway for multiple MCP servers
│   └── gateway.go         # Gateway manager
├── server/                   # HTTP server
│   ├── server.go          # HTTP server and endpoint handlers
│   ├── server_test.go     # Unit tests for endpoints
│   └── integration_test.go # Integration tests
├── tools/                    # Tool implementations
│   ├── echo.go            # Echo tool implementation
│   ├── echo_test.go       # Echo tool tests
│   ├── google_pse.go      # Google PSE search tool
│   ├── google_pse_test.go # Google PSE tests
│   └── proxy/             # Proxy tools for remote MCPs
│       ├── cloudflare.go  # Cloudflare proxy example
│       ├── filesystem.go  # File System MCP proxy
│       └── google_pse.go  # Google PSE proxy wrapper
└── transport/               # Transport layer abstraction
    ├── interface.go       # Transport interface
    └── http.go           # HTTP transport implementation

测试

该项目包括全面的测试覆盖范围:

运行所有测试

go test ./...

使用详细输出运行测试

go test ./... -v

运行覆盖率测试

go test ./... -cover

测试覆盖率

  • 工具:100%覆盖率
  • 服务器:59.6%的覆盖率

测试文件

  • server/server_test.go:所有HTTP端点的单元测试
  • server/integration_test.go:端到端工作流测试
  • tools/echo_test.go:工具特定测试

连接到其他MCP服务器

此服务器包括 网关 该系统允许您连接到其他MCP服务器(如Cloudflare、GitHub等)并使用其中的工具。

建筑

网关系统由以下部分组成:

  • client/:用于连接到远程服务器的MCP客户端实现
  • gateway/:用于处理多个MCP连接的网关管理器
  • transport/:传输层抽象(HTTP、SSE、stdio)
  • config/:MCP服务器的配置管理

配置

选项1:配置文件

创建一个 mcp-config.json 项目根目录中的文件:

{
  "port": ":3333",
  "google_pse": {
    "api_key": "YOUR_GOOGLE_PSE_API_KEY",
    "search_engine_id": "YOUR_GOOGLE_PSE_SEARCH_ENGINE_ID"
  },
  "servers": [
    {
      "name": "cloudflare",
      "url": "https://api.cloudflare.com/mcp",
      "transport": "http",
      "enabled": true,
      "prefix": "cloudflare:",
      "auth": {
        "Authorization": "Bearer YOUR_API_TOKEN",
        "X-Auth-Email": "your-email@example.com"
      }
    }
  ]
}

配置选项:

  • port:服务器端口(默认值: ":3333").可以 ":3333" 或 "3333" (将以前缀 : 自动)
  • google_pse:谷歌可编程搜索引擎配置
    • api_key:您的Google PSE API密钥
    • search_engine_id:您的谷歌自定义搜索引擎ID(CX)
  • servers:远程MCP服务器配置数组

选项2:环境变量

设置配置的环境变量:

# Server port (optional, defaults to :3333)
export MCP_PORT="3333"

# Google PSE configuration (optional)
export GOOGLE_PSE_API_KEY="your-api-key"
export GOOGLE_PSE_SEARCH_ENGINE_ID="your-search-engine-id"

# Remote MCP servers (optional)
export MCP_SERVERS='[{"name":"cloudflare","url":"https://api.cloudflare.com/mcp","transport":"http","enabled":true,"prefix":"cloudflare:"}]'

注: 配置文件优先于环境变量。如果两者都提供,则将使用配置文件值。

使用远程工具

配置后,远程工具将自动可用:

  1. 列出所有工具 (本地+远程):
curl http://localhost:3333/tools/list
  1. 调用远程工具 (使用前缀):
curl -X POST http://localhost:3333/tools/call \
  -H "Content-Type: application/json" \
  -d '{"name":"cloudflare:list_zones","arguments":{}}'

网关功能

  • ✅ 自动工具发现:远程工具自动包含在 /tools/list
  • ✅ 工具前缀:使用前缀(例如。, cloudflare:)避免命名冲突
  • ✅ 多个服务器:同时连接到多个MCP服务器
  • ✅ 错误处理:妥善处理连接故障
  • ✅ 运输抽象:支持HTTP、SSE和stdio传输

代理工具

您还可以为特定的MCP服务器创建代理包装器。示例:

  • tools/proxy/cloudflare.go -Cloudflare MCP代理
  • tools/proxy/filesystem.go -文件系统MCP代理
  • tools/proxy/google_pse.go -Google PSE代理包装器

Cloudflare MCP服务器

Cloudflare为不同的用例提供了多个MCP服务器。看 docs/CLOUDFLARE_MCP.md 了解详细信息。

快速设置:

增添 mcp-config.json:

{
  "servers": [
    {
      "name": "cloudflare-observability",
      "url": "https://observability.mcp.cloudflare.com/mcp",
      "transport": "http",
      "enabled": true,
      "prefix": "cloudflare:",
      "auth": {
        "Authorization": "Bearer YOUR_CLOUDFLARE_API_TOKEN"
      }
    }
  ]
}

可用的Cloudflare服务器:

  • 文档: https://docs.mcp.cloudflare.com/mcp (无身份验证)
  • 可观察性: https://observability.mcp.cloudflare.com/mcp (需要身份验证)
  • 工人绑定: https://bindings.mcp.cloudflare.com/mcp (需要身份验证)
  • 雷达: https://radar.mcp.cloudflare.com/mcp (无身份验证)
  • 浏览器渲染: https://browser.mcp.cloudflare.com/mcp (需要身份验证)
  • 和 更多...

请参阅 Cloudflare MCP文档 查看完整列表和设置说明。

文件系统MCP示例

文件系统MCP代理为文件操作提供了方便的方法:

import "mcp-go/tools/proxy"

// Create proxy
fsProxy := proxy.NewFileSystemProxy(gateway)

// Read a file
response, err := fsProxy.ReadFile(ctx, "/path/to/file.txt")

// Write a file
response, err := fsProxy.WriteFile(ctx, "/path/to/file.txt", "content")

// List directory
response, err := fsProxy.ListDirectory(ctx, "/path/to/dir")

// Create directory
response, err := fsProxy.CreateDirectory(ctx, "/path/to/newdir")

// Delete file
response, err := fsProxy.DeleteFile(ctx, "/path/to/file.txt")

可用的文件系统工具:

  • filesystem:read_file -读取文件内容
  • filesystem:write_file -将内容写入文件
  • filesystem:list_directory -列出目录中的文件
  • filesystem:create_directory -创建新目录
  • filesystem:delete_file -删除文件

API调用示例:

# Read a file
curl -X POST http://localhost:3333/tools/call \
  -H "Content-Type: application/json" \
  -d '{"name":"filesystem:read_file","arguments":{"path":"/path/to/file.txt"}}'

# Write a file
curl -X POST http://localhost:3333/tools/call \
  -H "Content-Type: application/json" \
  -d '{"name":"filesystem:write_file","arguments":{"path":"/path/to/file.txt","content":"Hello World"}}'

# List directory
curl -X POST http://localhost:3333/tools/call \
  -H "Content-Type: application/json" \
  -d '{"name":"filesystem:list_directory","arguments":{"path":"/path/to/dir"}}'

添加新工具

要添加新的本地工具,请执行以下操作:

  1. 在中创建新文件 tools/ 目录(例如。, tools/my_tool.go):
package tools

import "fmt"

type MyTool struct {
    Name        string                 `json:"name"`
    Description string                 `json:"description"`
    InputSchema map[string]interface{} `json:"inputSchema"`
}

func GetMyTool() MyTool {
    return MyTool{
        Name:        "my_tool",
        Description: "Description of my tool",
        InputSchema: map[string]interface{}{
            "type": "object",
            "properties": map[string]interface{}{
                "param": map[string]interface{}{
                    "type": "string",
                },
            },
            "required": []string{"param"},
        },
    }
}

func CallMyTool(arguments map[string]interface{}) (string, error) {
    // Implementation here
    return "result", nil
}
  1. 在中注册该工具 server/server.go:

    • 增添 handleToolsList() 包含在工具列表中
    • 在中添加处理程序 handleToolsCall() 执行该工具
  2. 在中添加测试 tools/my_tool_test.go

MCP协议合规性

此实现遵循MCP规范:

  • ✅ 协议版本: 2024-11-05
  • ✅ 工具响应使用MCP内容格式: {"content": [{"type": "text", "text": "..."}]}
  • ✅ 输入模式遵循JSON模式规范
  • ✅ 正确的HTTP状态码和错误处理

发展

代码的风格

  • 遵循Go标准格式(go fmt)
  • 仅使用标准库
  • 干净、可读、文档齐全的代码

建筑

# Build binary
go build -o mcp-server .

# Run directly
go run .

许可证

本项目按原样提供,用于教育和示范目的。

贡献

欢迎投稿!请确保:

  • 代码遵循Go最佳实践
  • 所有测试均通过
  • 新功能包括测试
  • 如果需要,README会更新

谷歌PSE配置

要使用谷歌可编程搜索引擎(PSE)进行网络搜索:

  1. 获取您的API证书:

  2. 添加到配置文件(mcp-config.json):

{
  "google_pse": {
    "api_key": "YOUR_API_KEY",
    "search_engine_id": "YOUR_SEARCH_ENGINE_ID"
  }
}
  1. 或者使用环境变量:
export GOOGLE_PSE_API_KEY="your-api-key"
export GOOGLE_PSE_SEARCH_ENGINE_ID="your-search-engine-id"
  1. 使用搜索工具:
curl -X POST http://localhost:3333/tools/call \
  -H "Content-Type: application/json" \
  -d '{"name":"google_pse_search","arguments":{"query":"Go programming language","num":5}}'

工作流示例

  1. 创建配置文件:
cp mcp-config.json.example mcp-config.json
# Edit mcp-config.json and add your API keys
  1. 启动服务器:
go run .
  1. 初始化连接:
curl http://localhost:3333/initialize
  1. 列出可用工具:
curl http://localhost:3333/tools/list
  1. 调用回声工具:
curl -X POST http://localhost:3333/tools/call \
  -H "Content-Type: application/json" \
  -d '{"name":"echo","arguments":{"message":"Hello from MCP!"}}'
  1. 调用文件系统工具(如果已配置):
# Read a file
curl -X POST http://localhost:3333/tools/call \
  -H "Content-Type: application/json" \
  -d '{"name":"filesystem:read_file","arguments":{"path":"/path/to/file.txt"}}'

# List directory
curl -X POST http://localhost:3333/tools/call \
  -H "Content-Type: application/json" \
  -d '{"name":"filesystem:list_directory","arguments":{"path":"/tmp"}}'

故障排除

端口已在使用中

如果端口3333已在使用中,请配置其他端口:

选项1: 产生 mcp-config.json:

{
  "port": ":8080"
}

选项2: 设置环境变量:

export MCP_SERVER_PORT=":8080"

选项3: 修改 server/server.go (不推荐):

port := ":8080"  // Change to your desired port

谷歌PSE不工作

  1. 验证API密钥和搜索引擎ID设置是否正确:

    • 在 mcp-config.json:设置 google_pse.enabled: true 并提供凭据
    • 或设置 GOOGLE_PSE_API_KEY 和 GOOGLE_PSE_SEARCH_ENGINE_ID 环境变量
  2. 检查API密钥权限和配额限制

  3. 验证您的Google自定义搜索引擎的搜索引擎ID(CX)是否正确

  4. 确保 google_pse.enabled 设置为 true 在配置文件中

连接被拒绝

主服务器: 在发出请求之前,请确保主服务器正在运行:

go run .

文件系统服务器: 如果你看到一个错误,比如 dial tcp [::1]:3335: connect: connection refused,您需要启动文件系统服务器:

# Option 1: Using the script
./start-filesystem-server.sh

# Option 2: Direct command
go run ./cmd/filesystem-server/main.go

如果您在浏览器中启用了文件系统服务器,则该服务器必须在端口3335上运行 mcp-config.json。您可以通过设置禁用它 "enabled": false 在文件系统服务器配置中。

JSON解析错误

确保请求正文是有效的JSON,并且设置了Content-Type标头:

-H "Content-Type: application/json"

参考文献