GoMCP — Gin-like Framework for MCP Servers in Go について
GoMCPは、型付きツールやミドルウェア、既存APIとの連携を必要とするGo開発者向けのMCPサーバーフレームワークです。構造体タグからスキーマを生成し、Gin、OpenAPI、gRPC用アダプターを備えています。
主な機能
- 01構造体タグからのスキーマ生成
- 02型付きツール引数の検証
- 03ミドルウェア、認証、RBAC
- 04Gin、OpenAPI、gRPC APIの取り込み
- 05リソース、プロンプト、非同期タスク
- 06stdioとStreamable HTTPのトランスポート
活用シーン
- 01Goでの型付きMCPツールの構築
- 02既存のGinまたはgRPC APIの公開
- 03認証とロールチェックの適用
- 04インメモリクライアントによるMCPサーバーのテスト
MCP 対応
GoMCPはMCPサーバーを実装するためのフレームワークです。ツール、リソース、プロンプトを登録でき、stdioとStreamable HTTPのトランスポートに対応します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
GoMCP
Go で MCP サーバーを構築する、速くて慣用的な方法です。
🚀 クイックリンク
- GitHub: https://github.com/zhangpanda/gomcp
- Gitee: https://gitee.com/rilegouasas/gomcp
- MCP Protocol: https://modelcontextprotocol.io
🎯 GoMCP とは?
GoMCP は、Model Context Protocol (MCP) サーバーを構築するための フレームワーク です。単なる SDK ではありません。「MCP のための Gin」 と考えてください。
MCP は、AI アプリケーション(Claude Desktop、Cursor、Kiro、VS Code Copilot)が外部ツールを呼び出し、データソースを読み込み、プロンプトテンプレートを使用できるようにするオープンプロトコルです。GoMCP を使えば、こうしたサーバーを簡単に構築できます。
GoMCP を選ぶ理由
| mcp-go (mark3labs) | Official Go SDK | GoMCP | |
|---|---|---|---|
| レベル | SDK | SDK | フレームワーク |
| スキーマ生成 | 手動 | jsonschema タグ | mcp タグ + 自動検証 |
| ミドルウェア | 基本的なフック | なし | 完全なチェーン(Logger、Auth、RateLimit、OTel…) |
| ツールグループ | なし | なし | あり(user.get、admin.delete) |
| Gin ルートのインポート | なし | なし | ✅ 1 行で可能 |
| OpenAPI/Swagger のインポート | なし | なし | ✅ 1 行で可能 |
| gRPC サービスのインポート | なし | なし | ✅ |
| 組み込み認証 | なし | なし | Bearer / API Key / Basic + RBAC(Bearer = ユーザー側のトークン/JWT 検証機能) |
| インスペクター UI | なし | なし | ✅ |
| テストユーティリティ | 基本的なもの | なし | mcptest パッケージ |
🛠️ 技術スタック
環境要件
| 要件 | バージョン |
|---|---|
| Go | ≥ 1.25 |
| MCP Protocol | 2024-11-05(2025-11-25 と後方互換性あり) |
Go 1.25 要件について。 GoMCP の
go.modではgo 1.25.0を宣言しており、セキュリティとランタイムの最新修正が適用されたツールチェーンで常にプロジェクトをビルドできるようにしています。ローカルで Go 1.21 以降をデフォルトのGOTOOLCHAIN=autoで実行している場合、Go が一致するツールチェーンを自動的にダウンロードして使用するため、手動でアップグレードする必要はありません。GOTOOLCHAIN=localを固定している場合は、Go 1.25 以降をインストールするか、固定を解除してください。
コア依存関係
| 技術 | 説明 |
|---|---|
| Go 標準ライブラリ | フレームワークのルーティング、JSON-RPC、トランスポート。DB/ORM の依存関係を強制しません |
| Gin | アダプターのみ。既存の Gin ルートをインポート |
| gRPC | アダプターのみ。gRPC サービスをインポート |
| OpenTelemetry | オプション。分散トレーシング |
| YAML v3 | プロバイダーのみ。ツール定義のホットリロード |
🌟 主な機能
🔧 ツール開発
- 構造体タグによる自動スキーマ生成 — Go の構造体と
mcpタグでパラメーターを定義すると、JSON Schema が自動生成されます - 型付きハンドラー —
func(*Context, Input) (Output, error)— 手動でパラメーターを解析する必要はありません - パラメーター検証 — required、min/max、enum、pattern をハンドラーの実行前にチェックします
- コンポーネントのバージョン管理 — 複数のバージョンを登録でき、クライアントは
name@versionを呼び出します - 非同期タスク — 長時間実行するツールはタスク ID を返し、ポーリングとキャンセルに対応します
🔌 アダプター(主な差別化要素)
- Gin アダプター — 既存の Gin ルートを 1 行で MCP ツールとしてインポート
- OpenAPI アダプター — Swagger/OpenAPI 3.x のドキュメントからツールを生成
- gRPC アダプター — gRPC サービスメソッドを MCP ツールとしてインポート
🔐 セキュリティ
- BearerAuth — ユーザー側の検証機能を使った Bearer トークンのチェック(JWT の解析はユーザー側で行う必要があり、このライブラリは JWT をデコードしません)
- APIKeyAuth — ヘッダーを使った API キーの検証
- BasicAuth — HTTP Basic 認証
- RequireRole / RequirePermission — ツールグループに対する RBAC 認可
🧩 フレームワークの機能
- ミドルウェアチェーン — Logger、Recovery、RequestID、Timeout、RateLimit、OpenTelemetry
- ツールグループ — プレフィックスとグループ単位のミドルウェアでツールを整理
- リソースとプロンプト — URI テンプレートやパラメーター化されたプロンプトを含む、MCP の完全なサポート
- 自動補完 — プロンプトやリソースの引数に指定する値を提案
🚀 本番環境対応
- 複数のトランスポート — stdio(Claude Desktop、Cursor、Kiro)と SSE 対応の Streamable HTTP
- MCP Inspector — ツールの閲覧とテストができる、組み込みのウェブデバッグ UI
- ホットリロード — YAML ファイルからツール定義を読み込み、ファイルの変更を監視
- mcptest パッケージ — スナップショットに対応した、単体テスト用のインメモリークライアント
- ライフサイクル —
Close()、セッションのアイドル時の削除、非同期並行処理については、サーバーのライフサイクル、セッションと非同期タスクを参照してください。
🏗️ アーキテクチャ
┌──────────────────────────────────────────────────────────────┐
│ User Code │
│ s.Tool() / s.ToolFunc() / s.Resource() / s.Prompt() │
├──────────────────────────────────────────────────────────────┤
│ Framework Core │
│ Router → Middleware Chain → Validation → Handler → Result │
├────────────┬─────────────┬───────────────┬───────────────────┤
│ Schema │ Validator │ Adapters │ Observability │
│ Generator │ Engine │ Gin/OpenAPI/ │ OTel / Logger │
│ (mcp tags) │ (auto) │ gRPC │ / Inspector │
├────────────┴─────────────┴───────────────┴───────────────────┤
│ Protocol Layer │
│ JSON-RPC 2.0 / MCP / Capability Negotiation │
├──────────────────────────────────────────────────────────────┤
│ Transport Layer │
│ stdio / Streamable HTTP + SSE │
└──────────────────────────────────────────────────────────────┘
プロジェクト構成
gomcp/
├── server.go # Server core, tool/resource/prompt registration
├── context.go # Request context with typed accessors
├── group.go # Tool groups with prefix naming
├── middleware.go # Middleware chain helpers (SkipAuthForMCPMethods, handshake skips)
├── middleware_builtin.go # Logger, Recovery, RequestID, Timeout, RateLimit
├── middleware_auth.go # Bearer/API key/Basic auth, RBAC, SSE auth helpers
├── middleware_otel.go # OpenTelemetry tracing
├── schema/ # struct tag → JSON Schema generator + validator
├── transport/ # stdio + Streamable HTTP + optional CORS helper
├── adapter/ # Gin, OpenAPI, gRPC adapters
├── mcptest/ # Testing utilities
├── task.go # Async task support
├── completion.go # Auto-completions
├── inspector.go # Web debug UI
├── provider.go # Hot-reload from YAML
└── examples/ # Working examples
├── basic/ # Minimal stdio server
├── filesystem/ # Real-world file ops
├── gin-adapter/ # Import Gin routes
├── openapi-adapter/ # Import Swagger/OpenAPI
└── grpc-adapter/ # Import gRPC services
📖 クックブック
よくあるタスクを順を追って説明するガイドです(各 5 分):
- 検索ツールを構築する — ゼロから Claude Desktop まで
- 既存の API をインポートする — Gin/OpenAPI/gRPC を 1 行で
- 認証と RBAC を追加する — Bearer トークンとロールベースのアクセス制御
📦 インストール
go get github.com/zhangpanda/gomcp
⚡ クイックスタート
5 行で MCP サーバーを動かす
package main
import (
"fmt"
"github.com/zhangpanda/gomcp"
)
type SearchInput struct {
Query string `json:"query" mcp:"required,desc=Search keyword"`
Limit int `json:"limit" mcp:"default=10,min=1,max=100"`
}
type SearchResult struct {
Items []string `json:"items"`
Total int `json:"total"`
}
func main() {
s := gomcp.New("my-server", "1.0.0")
s.ToolFunc("search", "Search documents by keyword", func(ctx *gomcp.Context, in SearchInput) (SearchResult, error) {
items := []string{fmt.Sprintf("Result for %q", in.Query)}
return SearchResult{Items: items, Total: len(items)}, nil
})
s.Stdio()
}
SearchInput 構造体は、この JSON Schema を自動的に生成します:
{
"type": "object",
"properties": {
"query": { "type": "string", "description": "Search keyword" },
"limit": { "type": "integer", "default": 10, "minimum": 1, "maximum": 100 }
},
"required": ["query"]
}
無効なパラメーターは、ハンドラーの実行前に拒否されます:
validation failed: query: required; limit: must be <= 100
📖 使用ガイド
構造体タグのリファレンス
| タグ | 型 | 説明 | 例 |
|---|---|---|---|
required | フラグ | フィールドの指定が必須です | mcp:"required" |
desc | 文字列 | 人が読める説明 | mcp:"desc=Search keyword" |
default | 任意 | デフォルト値 | mcp:"default=10" |
min | 数値 | 最小値(値を含む) | mcp:"min=0" |
max | 数値 | 最大値(値を含む) | mcp:"max=100" |
enum | 文字列 | パイプ区切りの許可値 | mcp:"enum=asc|desc" |
pattern | 文字列 | 正規表現による検証 | mcp:"pattern=^[a-z]+$" |
組み合わせる場合:mcp:"required,desc=User email,pattern=^[^@]+@[^@]+$"
サポートする型:string、int、float64、bool、[]T、ネストされた構造体。
ツール
シンプルなハンドラー:
s.Tool("hello", "Say hello", func(ctx *gomcp.Context) (*gomcp.CallToolResult, error) {
return ctx.Text("Hello, " + ctx.String("name")), nil
})
型付きハンドラー(推奨):
type Input struct {
Name string `json:"name" mcp:"required,desc=User name"`
Email string `json:"email" mcp:"required,pattern=^[^@]+@[^@]+$"`
}
s.ToolFunc("create_user", "Create user", func(ctx *gomcp.Context, in Input) (User, error) {
return db.CreateUser(in.Name, in.Email)
})
リソース
// Static
s.Resource("config://app", "App config", func(ctx *gomcp.Context) (any, error) {
return map[string]any{"version": "1.0"}, nil
})
// Dynamic URI template
s.ResourceTemplate("db://{table}/{id}", "DB record", func(ctx *gomcp.Context) (any, error) {
return db.Find(ctx.String("table"), ctx.String("id")), nil
})
プロンプト
s.Prompt("code_review", "Code review",
[]gomcp.PromptArgument{gomcp.PromptArg("language", "Language", true)},
func(ctx *gomcp.Context) ([]gomcp.PromptMessage, error) {
return []gomcp.PromptMessage{
gomcp.UserMsg(fmt.Sprintf("Review this %s code for bugs.", ctx.String("language"))),
}, nil
},
)
ミドルウェア
s.Use(gomcp.Logger()) // Log MCP method + duration
s.Use(gomcp.Recovery()) // Recover from panics
s.Use(gomcp.RequestID()) // Unique request ID
s.Use(gomcp.Timeout(10 * time.Second)) // Deadline enforcement
s.Use(gomcp.RateLimit(100)) // 100 calls/minute
s.Use(gomcp.OpenTelemetry()) // Distributed tracing
// Pick one: BearerAuth (token required on initialize too) or BearerAuthSkipHandshake (initialize/ping anonymous).
s.Use(gomcp.BearerAuthSkipHandshake(tokenValidator))
s.Use(gomcp.APIKeyAuthSkipHandshake("X-API-Key", keyValidator))
認証エラーの形式。 BearerAuth/APIKeyAuth/BasicAuth/ RequireRole/RequirePermission ミドルウェアが呼び出しを拒否すると、 フレームワークは通常の JSON-RPC
resultを返し、isError = trueとなり、理由はcontent[0].textに含まれます。これは JSON-RPC のerrorオブジェクトでも、HTTP 401/403 でもありません。 認証失敗を検出するには、クライアントはツール呼び出し結果のisErrorを確認する必要があります。
カスタムミドルウェア:
func AuditLog() gomcp.Middleware {
return func(ctx *gomcp.Context, next func() error) error {
start := time.Now()
err := next()
log.Printf("tool=%s duration=%s err=%v", ctx.String("_tool_name"), time.Since(start), err)
return err
}
}
ツールグループ
user := s.Group("user", authMiddleware)
user.Tool("get", "Get user", getUser) // → user.get
user.Tool("update", "Update user", updateUser) // → user.update
admin := user.Group("admin", gomcp.RequireRole("admin"))
admin.Tool("delete", "Delete user", deleteUser) // → user.admin.delete
アダプター
Gin — 既存の API を 1 行でインポート:
adapter.ImportGin(s, ginRouter, adapter.ImportOptions{
IncludePaths: []string{"/api/v1/"},
})
// GET /api/v1/users/:id → Tool get_api_v1_users_by_id (id = required param)
OpenAPI — Swagger ドキュメントから生成:
adapter.ImportOpenAPI(s, "./swagger.yaml", adapter.OpenAPIOptions{
TagFilter: []string{"pets"},
ServerURL: "https://api.example.com",
})
gRPC:
adapter.ImportGRPC(s, grpcConn, adapter.GRPCOptions{
Services: []string{"user.UserService"},
})
コンポーネントのバージョン管理
s.ToolFunc("search", "v1", searchV1, gomcp.Version("1.0"))
s.ToolFunc("search", "v2 with embeddings", searchV2, gomcp.Version("2.0"))
// "search" → latest, "[email protected]" → exact version
非同期タスク
s.AsyncTool("report", "Generate report", func(ctx *gomcp.Context) (*gomcp.CallToolResult, error) {
// long-running work
return ctx.Text("done"), nil
})
// Client gets taskId immediately, polls tasks/get, can tasks/cancel
ホットリロード
s.LoadDir("./tools/", gomcp.DirOptions{Watch: true})
YAML ツールファイルの形式:
name: search
description: Full-text document search
version: "1.0" # OPTIONAL — non-empty renames the tool to "[email protected]"
method: GET
handler: https://example.com/search
params:
- {name: query, type: string, required: true, description: Query text}
ご注意 —
versionはツール名を変更します。 空でないversionフィールドを指定すると、Provider はgomcp.Version()と同じ規則に従い、ツールをname@version(例:[email protected])として登録します。これはクライアントがtools/callに渡す必要のある名前であり、tools/listに表示される名前です。バージョンなしのsearchという ツールにする場合は、versionフィールドを完全に削除してください。
サーバーのライフサイクル、セッション、非同期タスク
Server.Close()—LoadDir(..., Watch: true)または長時間稼働する HTTP を使用するサーバーを、プロセスまたはテストの終了時に停止する場合は、Close()を一度呼び出してください。YAML の監視ループ、セッションの削除を行うバックグラウンドゴルーチン、および非同期タスクマネージャーの削除ループを停止します。この呼び出しは冪等です。- セッション — セッション状態はメモリ内のみに保存されます。識別子は、クライアントの
Mcp-Session-Idヘッダーから取得されます(Streamable HTTP を参照)。30 分間アイドル状態のセッション(その ID によるアクセスがない状態)は削除されます。同じ ID で次のリクエストを送ると、新しい空のセッションが作成されます。クライアントが通信を続けるか、自分で状態を更新しない限り、長いアイドル期間をまたいでSessionのストレージが維持されることを前提にしないでください。 SetMaxConcurrentTasks(n)— 最初のAsyncTool/AsyncToolFuncを使う前に設定してください。内部タスクマネージャーの作成後に呼び出しても、後続の呼び出しは何もしません(実行中の処理との競合を避けるため)。- シャットダウンと非同期処理 —
Close()は、実行中の非同期ツールハンドラーの完了を待ちません。終了前に確実に完了させる必要がある場合は、独自にタイムアウト/待機を追加してください。
MCP Inspector
s.Dev(":9090") // http://localhost:9090 — browse and test all tools
テスト
func TestSearch(t *testing.T) {
c := mcptest.NewClient(t, setupServer())
c.Initialize()
result := c.CallTool("search", map[string]any{"query": "golang"})
result.AssertNoError(t)
result.AssertContains(t, "golang")
mcptest.MatchSnapshot(t, "search_result", result)
}
トランスポート
s.Stdio() // Claude Desktop, Cursor, Kiro
s.HTTP(":8080") // Remote deployment with SSE
s.Handler() // Embed in existing HTTP server
// Browser clients: wrap the handler with transport.WrapCORS(h, []string{"https://your.app"}) when needed
AI クライアントでの使用
{
"mcpServers": {
"my-server": {
"command": "/path/to/your/binary"
}
}
}
Claude Desktop、Cursor、Kiro、Windsurf、VS Code Copilot、および MCP 互換のあらゆるクライアントで動作します。
📋 ロードマップ
- コア:MCP プロトコルを完全にサポートしたツール、リソース、プロンプト
- 構造体タグによるスキーマの自動生成とパラメーターの検証
- ミドルウェアチェーン(Logger、Recovery、RateLimit、Timeout、RequestID)
- 認証ミドルウェア(Bearer/API Key/Basic)と RBAC 認可
- プレフィックスによる命名とネストに対応したツールグループ
- stdio と Streamable HTTP のトランスポート、および SSE 通知
- Gin アダプター — 既存の Gin ルートを MCP ツールとしてインポート
- OpenAPI アダプター — Swagger/OpenAPI ドキュメントからツールを生成
- gRPC アダプター — gRPC サービスを MCP ツールとしてインポート
- OpenTelemetry との統合
- スナップショットテストに対応した mcptest パッケージ
- コンポーネントのバージョニングと非推奨化
- ポーリングとキャンセルに対応した非同期タスク
- MCP Inspector のウェブデバッグ UI
- YAML によるプロバイダーのホットリロード
- プロンプト/リソースの引数の自動補完
🤝 フィードバックとサポート
- バグ報告:GitHub Issues
- 機能リクエスト:GitHub Issues
- ディスカッション:GitHub Discussions
💡 おすすめ記事:賢い質問の仕方
🔒 セキュリティ
HTTP トランスポートと認証
Useミドルウェアは、JSON-RPC のすべてのメソッドで実行されます(応答のない通知notifications/initializedを除く):initialize、tools/list、tools/call、resources/read、prompts/get、tasks/*、completion/completeなどです。POST /mcpを公開する場合は、BearerAuth/APIKeyAuth/BasicAuthを使用してください。APIKeyAuthでは、ヘッダーが送信されない場合、api_key(およびマージされたその他のパラメーター)は、tools/callの引数、prompts/getの引数、またはresources/readのパラメーターの JSON から取得されます。本番環境ではヘッダーの使用を推奨します。BearerAuthSkipHandshake/APIKeyAuthSkipHandshake/BasicAuthSkipHandshake(またはSkipAuthForMCPMethods)を使うと、他のメソッドを保護したまま、initializeとpingを認証情報なしで実行できます。これは、トークンを送信する前にネゴシエーションを行う一般的な MCP HTTP クライアント向けです。- リクエストコンテキストはツール、リソース、プロンプトのハンドラーに伝播します(デッドライン、
Authorization、および Streamable HTTP から注入されたヘッダー)。 - SSE(
GET /mcp)では MCP ミドルウェアは実行されません。WithSSEAuthとSSEBearerAuth、SSEAPIKeyAuth、SSEBasicAuth、または独自のゲートを使用してください。WithSSEAuthがない場合、GETを開けるすべてのクライアントがブロードキャスト通知を受け取ります。 - ブラウザーの
fetch:github.com/zhangpanda/gomcp/transportのtransport.WrapCORS(h, allowedOrigins)で/mcpハンドラーをラップしてください。認証情報を使用する場合は*を指定せず、信頼できるオリジンのみを列挙してください。
本番環境で Streamable HTTP をデプロイする場合は、TLS、POST の認証ミドルウェア、および通知を公開しない場合の WithSSEAuth を組み合わせてください。
セキュリティの脆弱性を報告するには、SECURITY.md をご覧ください。
⚖️ 著作権とライセンス
Copyright © 2026 GoMCP Contributors
Apache License 2.0 に基づいてライセンスされています。
重要な注意事項
- このプロジェクトは、Apache 2.0 ライセンスに基づき、個人利用および商用利用のどちらでもオープンソースで無料です。
- ソフトウェアのすべての複製および実質的な部分には、著作権表示、ライセンス文、ならびに帰属表示をすべて保持する必要があります。
- Apache 2.0 ライセンスでは、貢献者からユーザーに対する明示的な特許権の許諾が含まれています。
- このプロジェクトへの貢献は、同じ Apache 2.0 ライセンスに基づいてライセンスされます。
- 著作権表示を無断で削除すると、法的措置の対象となる場合があります。
特許に関する通知
このフレームワークの一部の機能(構造体タグによるスキーマ生成、HTTP から MCP への自動アダプター、OpenAPI から MCP への自動アダプター)は、特許出願中です。Apache 2.0 ライセンスにより、本ソフトウェアの一部としてこれらの機能を使用するための、永続的、全世界的、ロイヤリティフリーの特許ライセンスが許諾されます。
⭐ スターの履歴
GoMCP が役に立ったら、ぜひスターを付けてください。より多くの人にこのプロジェクトを知ってもらう助けになります。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。