go-mcp-server-generator

go-mcp-server-generator

熱門

使用官方 github.com/modelcontextprotocol/go-sdk 生成一個完整的 Go MCP 伺服器專案,包含適當的結構、相依套件和實作。

3.7萬星標
4569分支
更新於 2026/7/14
SKILL.md
readonlyread-only
name
go-mcp-server-generator
description

使用官方 github.com/modelcontextprotocol/go-sdk 生成一個完整的 Go MCP 伺服器專案,包含適當的結構、相依套件和實作。

Go MCP 伺服器專案產生器

生成一個完整、可用於生產環境的 Go 語言 Model Context Protocol (MCP) 伺服器專案。

專案需求

您將建立一個 Go MCP 伺服器,包含:

  1. 專案結構:正確的 Go 模組佈局
  2. 相依套件:官方 MCP SDK 及必要套件
  3. 伺服器設定:配置 MCP 伺服器與傳輸方式
  4. 工具:至少 2-3 個實用工具,具有型別化的輸入/輸出
  5. 錯誤處理:正確的錯誤處理與 context 使用
  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()

    // 處理優雅關閉
    sigCh := make(chan os.Signal, 1)
    signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
    go func() {
        <-sigCh
        log.Println("正在關閉...")
        cancel()
    }()

    // 建立伺服器
    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{},
            },
        },
    )

    // 註冊工具
    tools.RegisterTools(server)

    // 執行伺服器
    transport := &mcp.StdioTransport{}
    if err := server.Run(ctx, transport); err != nil {
        log.Fatalf("伺服器錯誤: %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,
) {
    // 驗證輸入
    if input.Param1 == "" {
        return nil, Tool1Output{}, fmt.Errorf("param1 為必填")
    }

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

    // 執行操作
    result := fmt.Sprintf("已處理: %s", input.Param1)

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

func RegisterTool1(server *mcp.Server) {
    mcp.AddTool(server,
        &mcp.Tool{
            Name:        "tool1",
            Description: "tool1 的功能說明",
        },
        Tool1Handler,
    )
}

tools/registry.go 範本

package tools

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

func RegisterTools(server *mcp.Server) {
    RegisterTool1(server)
    RegisterTool2(server)
    // 在此註冊其他工具
}

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 失敗: %v", err)
    }

    if output.Status != "success" {
        t.Errorf("預期狀態為 'success',但得到 '%s'", output.Status)
    }

    if result != nil {
        t.Error("預期 result 為 nil")
    }
}

README.md 範本

# {{PROJECT_NAME}}

一個使用 Go 建置的 Model Context Protocol (MCP) 伺服器。

## 說明

{{PROJECT_DESCRIPTION}}

## 安裝

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

## 使用方式

使用 stdio 傳輸執行伺服器:

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

## 設定

透過環境變數設定:

- `SERVER_NAME`:伺服器名稱(預設:"{{PROJECT_NAME}}")
- `VERSION`:伺服器版本(預設:"v1.0.0")
- `LOG_LEVEL`:日誌層級(預設:"info")

## 可用工具

### tool1
{{TOOL1_DESCRIPTION}}

**輸入:**
- `param1`(字串,必填):第一個參數
- `param2`(整數,選填):第二個參數

**輸出:**
- `result`(字串):操作結果
- `status`(字串):操作狀態

## 開發

執行測試:

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

建置:

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

## 授權

MIT

生成說明

生成 Go MCP 伺服器時:

  1. 初始化模組:使用正確的模組路徑建立 go.mod
  2. 結構:遵循範本目錄結構
  3. 型別安全:對所有輸入/輸出使用帶有 JSON schema 標籤的結構體
  4. 錯誤處理:驗證輸入、檢查 context、包裝錯誤
  5. 文件:加入清晰的說明與範例
  6. 測試:每個工具至少包含一個測試
  7. 設定:使用環境變數進行設定
  8. 日誌:使用結構化日誌(log/slog)
  9. 優雅關閉:正確處理信號
  10. 傳輸方式:預設使用 stdio,並記錄其他選項

最佳實務

  • 保持工具專注且單一用途
  • 使用描述性的型別與函式名稱
  • 在結構體標籤中包含 JSON schema 文件
  • 始終尊重 context 取消
  • 回傳描述性錯誤
  • 保持 main.go 精簡,邏輯放在套件中
  • 為工具處理函式撰寫測試
  • 記錄所有匯出的函式