mcpField
G
go-mcp-server-generator

go-mcp-server-generator

github.com/github开发40.5k9.2k 次安装1 天前更新
代码仓库

关于 go-mcp-server-generator

用于生成 Model Context Protocol(MCP)服务 Go 项目的技能。它规定模块化项目结构,并涵盖类型化工具、错误处理、文档、测试、配置、日志记录和优雅关闭。

主要功能

  1. 01创建 Go 模块与服务端结构
  2. 02使用官方 Go MCP SDK
  3. 03定义类型化工具并校验输入
  4. 04包含测试与 README 指引
  5. 05支持配置与优雅关闭

适用场景

  1. 01搭建新的 Go MCP 服务
  2. 02为服务项目添加类型化工具
  3. 03创建包含测试和文档的服务起始项目

MCP 相关

使用官方 Go SDK 生成 Go MCP 服务项目,默认采用 stdio 传输,并注明其他传输方式。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/github/awesome-copilot --skill go-mcp-server-generator

安装后在 Claude Code 中输入/go-mcp-server-generator确认已加载。

详细介绍

Go MCP 服务项目生成器

生成一个完整、可用于生产环境的 Go 语言 Model Context Protocol (MCP) 服务项目。

项目要求

你需要创建一个 Go MCP 服务,包含:

  1. 项目结构:规范的 Go 模块布局
  2. 依赖项:官方 MCP SDK 及必要的软件包
  3. 服务设置:配置好传输方式的 MCP 服务
  4. 工具:至少 2-3 个具有类型化输入/输出的工具
  5. 错误处理:正确的错误处理和上下文使用
  6. 文档:包含设置和使用说明的 README
  7. 测试:基本的测试结构

模板结构

myserver/
├── go.mod
├── go.sum
├── main.go
├── tools/
│   ├── tool1.go
│   └── tool2.go
├── resources/
│   └── resource1.go
├── config/
│   └── config.go
├── README.md
└── main_test.go

go.mod 模板

module github.com/yourusername/{{PROJECT_NAME}}

go 1.23

require (
    github.com/modelcontextprotocol/go-sdk v1.0.0
)

main.go 模板

package main

import (
    "context"
    "log"
    "os"
    "os/signal"
    "syscall"

    "github.com/modelcontextprotocol/go-sdk/mcp"
    "github.com/yourusername/{{PROJECT_NAME}}/config"
    "github.com/yourusername/{{PROJECT_NAME}}/tools"
)

func main() {
    cfg := config.Load()
    
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    // Handle graceful shutdown
    sigCh := make(chan os.Signal, 1)
    signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
    go func() {
        <-sigCh
        log.Println("Shutting down...")
        cancel()
    }()

    // Create server
    server := mcp.NewServer(
        &mcp.Implementation{
            Name:    cfg.ServerName,
            Version: cfg.Version,
        },
        &mcp.Options{
            Capabilities: &mcp.ServerCapabilities{
                Tools:     &mcp.ToolsCapability{},
                Resources: &mcp.ResourcesCapability{},
                Prompts:   &mcp.PromptsCapability{},
            },
        },
    )

    // Register tools
    tools.RegisterTools(server)

    // Run server
    transport := &mcp.StdioTransport{}
    if err := server.Run(ctx, transport); err != nil {
        log.Fatalf("Server error: %v", err)
    }
}

tools/tool1.go 模板

package tools

import (
    "context"
    "fmt"

    "github.com/modelcontextprotocol/go-sdk/mcp"
)

type Tool1Input struct {
    Param1 string `json:"param1" jsonschema:"required,description=First parameter"`
    Param2 int    `json:"param2,omitempty" jsonschema:"description=Optional second parameter"`
}

type Tool1Output struct {
    Result string `json:"result" jsonschema:"description=The result of the operation"`
    Status string `json:"status" jsonschema:"description=Operation status"`
}

func Tool1Handler(ctx context.Context, req *mcp.CallToolRequest, input Tool1Input) (
    *mcp.CallToolResult,
    Tool1Output,
    error,
) {
    // Validate input
    if input.Param1 == "" {
        return nil, Tool1Output{}, fmt.Errorf("param1 is required")
    }

    // Check context
    if ctx.Err() != nil {
        return nil, Tool1Output{}, ctx.Err()
    }

    // Perform operation
    result := fmt.Sprintf("Processed: %s", input.Param1)

    return nil, Tool1Output{
        Result: result,
        Status: "success",
    }, nil
}

func RegisterTool1(server *mcp.Server) {
    mcp.AddTool(server,
        &mcp.Tool{
            Name:        "tool1",
            Description: "Description of what tool1 does",
        },
        Tool1Handler,
    )
}

tools/registry.go 模板

package tools

import "github.com/modelcontextprotocol/go-sdk/mcp"

func RegisterTools(server *mcp.Server) {
    RegisterTool1(server)
    RegisterTool2(server)
    // Register additional tools here
}

config/config.go 模板

package config

import "os"

type Config struct {
    ServerName string
    Version    string
    LogLevel   string
}

func Load() *Config {
    return &Config{
        ServerName: getEnv("SERVER_NAME", "{{PROJECT_NAME}}"),
        Version:    getEnv("VERSION", "v1.0.0"),
        LogLevel:   getEnv("LOG_LEVEL", "info"),
    }
}

func getEnv(key, defaultValue string) string {
    if value := os.Getenv(key); value != "" {
        return value
    }
    return defaultValue
}

main_test.go 模板

package main

import (
    "context"
    "testing"

    "github.com/yourusername/{{PROJECT_NAME}}/tools"
)

func TestTool1Handler(t *testing.T) {
    ctx := context.Background()
    input := tools.Tool1Input{
        Param1: "test",
        Param2: 42,
    }

    result, output, err := tools.Tool1Handler(ctx, nil, input)
    if err != nil {
        t.Fatalf("Tool1Handler failed: %v", err)
    }

    if output.Status != "success" {
        t.Errorf("Expected status 'success', got '%s'", output.Status)
    }

    if result != nil {
        t.Error("Expected result to be nil")
    }
}

README.md 模板

# {{PROJECT_NAME}}

A Model Context Protocol (MCP) server built with Go.

## Description

{{PROJECT_DESCRIPTION}}

## Installation

\`\`\`bash
go mod download
go build -o {{PROJECT_NAME}}
\`\`\`

## Usage

Run the server with stdio transport:

\`\`\`bash
./{{PROJECT_NAME}}
\`\`\`

## Configuration

Configure via environment variables:

- `SERVER_NAME`: Server name (default: "{{PROJECT_NAME}}")
- `VERSION`: Server version (default: "v1.0.0")
- `LOG_LEVEL`: Logging level (default: "info")

## Available Tools

### tool1
{{TOOL1_DESCRIPTION}}

**Input:**
- `param1` (string, required): First parameter
- `param2` (int, optional): Second parameter

**Output:**
- `result` (string): Operation result
- `status` (string): Status of the operation

## Development

Run tests:

\`\`\`bash
go test ./...
\`\`\`

Build:

\`\`\`bash
go build -o {{PROJECT_NAME}}
\`\`\`

## License

MIT

生成说明

生成 Go MCP 服务时:

  1. 初始化模块:创建带有正确模块路径的 go.mod
  2. 结构:遵循模板目录结构
  3. 类型安全:为所有输入/输出使用带有 JSON schema 标签的结构体
  4. 错误处理:验证输入、检查上下文、包装错误
  5. 文档:添加清晰的描述和示例
  6. 测试:为每个工具至少包含一个测试
  7. 配置:使用环境变量进行配置
  8. 日志:使用结构化日志(log/slog)
  9. 优雅关闭:正确处理信号
  10. 传输:默认使用 stdio,并记录其他可选方案

最佳实践

  • 保持工具专注且单一用途
  • 为类型和函数使用描述性名称
  • 在结构体标签中包含 JSON schema 文档
  • 始终遵循上下文取消
  • 返回描述性错误
  • 保持 main.go 简洁,逻辑放在各个包中
  • 为工具处理程序编写测试
  • 为所有导出函数编写文档

评论

支持 Markdown