GoMCP
π Go Version
π License
π Release
π gomcp MCP server
Goλ‘ MCP μλ²λ₯Ό ꡬμΆνλ λΉ λ₯΄κ³ κ΄μ©μ μΈ λ°©λ²μ λλ€.
π λΉ λ₯Έ λ§ν¬
MCP νλ‘ν μ½: https://modelcontextprotocol.io
Related MCP server: Filesystem MCP Server
π― GoMCPλ 무μμΈκ°μ?
GoMCPλ λ¨μν SDKκ° μλ, Model Context Protocol (MCP) μλ²λ₯Ό ꡬμΆνκΈ° μν νλ μμν¬μ λλ€. **"MCPλ₯Ό μν Gin"**μ΄λΌκ³ μκ°νμλ©΄ λ©λλ€.
MCPλ AI μ ν리μΌμ΄μ (Claude Desktop, Cursor, Kiro, VS Code Copilot)μ΄ μΈλΆ λꡬλ₯Ό νΈμΆνκ³ , λ°μ΄ν° μμ€λ₯Ό μ½κ³ , ν둬ννΈ ν νλ¦Ώμ μ¬μ©ν μ μκ² ν΄μ£Όλ κ°λ°©ν νλ‘ν μ½μ λλ€. GoMCPλ₯Ό μ¬μ©νλ©΄ μ΄λ¬ν μλ²λ₯Ό λ§€μ° μ½κ² ꡬμΆν μ μμ΅λλ€.
μ GoMCPμΈκ°μ?
mcp-go (mark3labs) | 곡μ Go SDK | GoMCP | |
μμ€ | SDK | SDK | νλ μμν¬ |
μ€ν€λ§ μμ± | μλ |
|
|
λ―Έλ€μ¨μ΄ | κΈ°λ³Έ ν | μμ | μ 체 μ²΄μΈ (λ‘κ±°, μΈμ¦, μλ μ ν, OTel λ±) |
λꡬ κ·Έλ£Ή | μμ | μμ | μ§μ ( |
Gin λΌμ°νΈ κ°μ Έμ€κΈ° | μμ | μμ | β ν μ€ |
OpenAPI/Swagger κ°μ Έμ€κΈ° | μμ | μμ | β ν μ€ |
gRPC μλΉμ€ κ°μ Έμ€κΈ° | μμ | μμ | β |
λ΄μ₯ μΈμ¦ | μμ | μμ | Bearer, API Key, Basic + RBAC |
μΈμ€νν° UI | μμ | μμ | β |
ν μ€νΈ μ νΈλ¦¬ν° | κΈ°λ³Έ | μμ | mcptest ν¨ν€μ§ |
π οΈ κΈ°μ μ€ν
νκ²½ μꡬ μ¬ν
μꡬ μ¬ν | λ²μ |
Go | β₯ 1.25 |
MCP νλ‘ν μ½ | 2024-11-05 (2025-11-25μ νμ νΈν) |
ν΅μ¬ μμ‘΄μ±
κΈ°μ | μ€λͺ |
Go νμ€ λΌμ΄λΈλ¬λ¦¬ | ν΅μ¬ νλ μμν¬ β μΈλΆ μμ‘΄μ± μμ |
Gin | μ΄λν° μ μ© β κΈ°μ‘΄ Gin λΌμ°νΈ κ°μ Έμ€κΈ° |
gRPC | μ΄λν° μ μ© β gRPC μλΉμ€ κ°μ Έμ€κΈ° |
OpenTelemetry | μ ν μ¬ν β λΆμ° μΆμ |
YAML v3 | 곡κΈμ μ μ© β λꡬ μ μ ν« λ¦¬λ‘λ |
π ν΅μ¬ κΈ°λ₯
π§ λꡬ κ°λ°
ꡬ쑰체 νκ·Έ μλ μ€ν€λ§ β Go ꡬ쑰체μ
mcpνκ·Έλ‘ λ§€κ°λ³μλ₯Ό μ μνλ©΄ JSON μ€ν€λ§κ° μλμΌλ‘ μμ±λ©λλ€.νμ μ§μ νΈλ€λ¬ β
func(*Context, Input) (Output, error)β μλ λ§€κ°λ³μ νμ±μ΄ νμ μμ΅λλ€.λ§€κ°λ³μ κ²μ¦ β νμ, μ΅μ/μ΅λ, μ΄κ±°ν, ν¨ν΄ β νΈλ€λ¬ μ€ν μ μ κ²μ¦λ©λλ€.
μ»΄ν¬λνΈ λ²μ κ΄λ¦¬ β μ¬λ¬ λ²μ μ λ±λ‘νκ³ ν΄λΌμ΄μΈνΈκ°
name@versionμΌλ‘ νΈμΆν μ μμ΅λλ€.λΉλκΈ° μμ β μ€λ 걸리λ λꡬλ μμ IDλ₯Ό λ°ννλ©°, ν΄λ§ λ° μ·¨μλ₯Ό μ§μν©λλ€.
π μ΄λν° (ν΅μ¬ μ°¨λ³μ )
Gin μ΄λν° β κΈ°μ‘΄ Gin λΌμ°νΈλ₯Ό ν μ€λ‘ MCP λκ΅¬λ‘ κ°μ Έμ΅λλ€.
OpenAPI μ΄λν° β Swagger/OpenAPI 3.x λ¬Έμμμ λꡬλ₯Ό μμ±ν©λλ€.
gRPC μ΄λν° β gRPC μλΉμ€ λ©μλλ₯Ό MCP λκ΅¬λ‘ κ°μ Έμ΅λλ€.
π 보μ
BearerAuth β JWT ν ν° κ²μ¦
APIKeyAuth β ν€λλ₯Ό ν΅ν API ν€ κ²μ¦
BasicAuth β HTTP κΈ°λ³Έ μΈμ¦
RequireRole / RequirePermission β λꡬ κ·Έλ£Ήμ λν RBAC κΆν λΆμ¬
π§© νλ μμν¬ κΈ°λ₯
λ―Έλ€μ¨μ΄ μ²΄μΈ β λ‘κ±°, 볡ꡬ, μμ² ID, νμμμ, μλ μ ν, OpenTelemetry
λꡬ κ·Έλ£Ή β μ λμ¬μ κ·Έλ£Ή μμ€ λ―Έλ€μ¨μ΄λ‘ λꡬ ꡬμ±
리μμ€ λ° ν둬ννΈ β URI ν νλ¦Ώ λ° λ§€κ°λ³μνλ ν둬ννΈλ₯Ό ν¬ν¨ν μ 체 MCP μ§μ
μλ μμ± β ν둬ννΈ/리μμ€ μΈμμ λν κ° μ μ
π νλ‘λμ μ€λΉ μλ£
λ€μ€ μ μ‘ β stdio (Claude Desktop, Cursor, Kiro) λ° SSEλ₯Ό μ¬μ©νλ μ€νΈλ¦¬λ° κ°λ₯ HTTP
MCP μΈμ€νν° β λꡬ νμ λ° ν μ€νΈλ₯Ό μν λ΄μ₯ μΉ λλ²κ·Έ UI
ν« λ¦¬λ‘λ β νμΌ κ°μλ₯Ό ν΅ν΄ YAML νμΌμμ λꡬ μ μ λ‘λ
mcptest ν¨ν€μ§ β μ€λ μ· μ§μμ ν¬ν¨ν λ¨μ ν μ€νΈμ© μΈλ©λͺ¨λ¦¬ ν΄λΌμ΄μΈνΈ
ποΈ μν€ν μ²
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 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 interface and chain execution
βββ middleware_builtin.go # Logger, Recovery, RequestID, Timeout, RateLimit
βββ middleware_auth.go # BearerAuth, APIKeyAuth, BasicAuth, RBAC
βββ middleware_otel.go # OpenTelemetry tracing
βββ schema/ # struct tag β JSON Schema generator + validator
βββ transport/ # stdio + Streamable HTTP
βββ 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π¦ μ€μΉ
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 μ€ν€λ§λ₯Ό μλμΌλ‘ μμ±ν©λλ€:
{
"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π μ¬μ© κ°μ΄λ
ꡬ쑰체 νκ·Έ μ°Έμ‘°
νκ·Έ | νμ | μ€λͺ | μμ | |
| νλκ·Έ | νμ νλ |
| |
| λ¬Έμμ΄ | μ¬λμ΄ μ½μ μ μλ μ€λͺ |
| |
| μμ | κΈ°λ³Έκ° |
| |
| μ«μ | μ΅μκ° (ν¬ν¨) |
| |
| μ«μ | μ΅λκ° (ν¬ν¨) |
| |
| λ¬Έμμ΄ | νμ΄νλ‘ κ΅¬λΆλ νμ© κ° | `mcp:"enum=asc | desc"` |
| λ¬Έμμ΄ | μ κ·μ κ²μ¦ |
|
μ‘°ν©: mcp:"required,desc=μ¬μ©μ μ΄λ©μΌ,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 tool name + 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
s.Use(gomcp.BearerAuth(tokenValidator)) // JWT auth
s.Use(gomcp.APIKeyAuth("X-API-Key", keyValidator)) // API key authμ¬μ©μ μ μ λ―Έλ€μ¨μ΄:
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λ₯Ό κ°μ Έμ€λ ν μ€ μ½λ:
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, "search@1.0" β 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})MCP μΈμ€νν°
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 serverAI ν΄λΌμ΄μΈνΈμ ν¨κ» μ¬μ©
{
"mcpServers": {
"my-server": {
"command": "/path/to/your/binary"
}
}
}Claude Desktop, Cursor, Kiro, Windsurf, VS Code Copilot λ° λͺ¨λ MCP νΈν ν΄λΌμ΄μΈνΈμ μλν©λλ€.
π λ‘λλ§΅
[x] ν΅μ¬: μ 체 MCP νλ‘ν μ½ μ§μμ ν¬ν¨ν λꡬ, 리μμ€, ν둬ννΈ
[x] ꡬ쑰체 νκ·Έ μλ μ€ν€λ§ μμ± + λ§€κ°λ³μ κ²μ¦
[x] λ―Έλ€μ¨μ΄ μ²΄μΈ (λ‘κ±°, 볡ꡬ, μλ μ ν, νμμμ, μμ² ID)
[x] μΈμ¦ λ―Έλ€μ¨μ΄ (Bearer / API Key / Basic) + RBAC κΆν λΆμ¬
[x] μ λμ¬ λͺ λͺ λ° μ€μ²© κ·Έλ£Ήμ μ§μνλ λꡬ κ·Έλ£Ή
[x] stdio + SSE μλ¦Όμ ν¬ν¨ν μ€νΈλ¦¬λ° κ°λ₯ HTTP μ μ‘
[x] Gin μ΄λν° β κΈ°μ‘΄ Gin λΌμ°νΈλ₯Ό MCP λκ΅¬λ‘ κ°μ Έμ€κΈ°
[x] OpenAPI μ΄λν° β Swagger/OpenAPI λ¬Έμμμ λꡬ μμ±
[x] gRPC μ΄λν° β gRPC μλΉμ€λ₯Ό MCP λκ΅¬λ‘ κ°μ Έμ€κΈ°
[x] OpenTelemetry ν΅ν©
[x] μ€λ μ· ν μ€νΈλ₯Ό ν¬ν¨ν mcptest ν¨ν€μ§
[x] μ»΄ν¬λνΈ λ²μ κ΄λ¦¬ + μ§μ μ€λ¨(deprecation)
[x] ν΄λ§ λ° μ·¨μλ₯Ό μ§μνλ λΉλκΈ° μμ
[x] MCP μΈμ€νν° μΉ λλ²κ·Έ UI
[x] YAMLμμ λ‘λνλ ν« λ¦¬λ‘λ 곡κΈμ
[x] ν둬ννΈ/리μμ€ μΈμμ λν μλ μμ±
π€ νΌλλ°± λ° μ§μ
λ²κ·Έ 리ν¬νΈ: GitHub Issues
κΈ°λ₯ μμ²: GitHub Issues
ν λ‘ : GitHub Discussions
π‘ κΆμ₯ μ½κΈ°: μ§λ¬Ένλ λ°©λ² (Smart Way)
π 보μ
보μ μ·¨μ½μ μ λ³΄κ³ νλ €λ©΄ SECURITY.mdλ₯Ό μ°Έμ‘°νμΈμ.
βοΈ μ μκΆ λ° λΌμ΄μ μ€
Copyright Β© 2026 GoMCP Contributors
Apache License 2.0μ λ°λΌ λΌμ΄μ μ€κ° λΆμ¬λ©λλ€.
μ€μ μ°Έκ³ μ¬ν
μ΄ νλ‘μ νΈλ Apache 2.0 λΌμ΄μ μ€μ λ°λΌ κ°μΈ λ° μμ μ μ©λλ‘ μ€ν μμ€μ΄λ©° 무λ£μ λλ€.
μννΈμ¨μ΄μ λͺ¨λ μ¬λ³Έ λλ μλΉ λΆλΆμ μ μκΆ κ³ μ§, λΌμ΄μ μ€ ν μ€νΈ λ° λͺ¨λ κ·μ κ³ μ§λ₯Ό μ μ§ν΄μΌ ν©λλ€.
Apache 2.0 λΌμ΄μ μ€μλ κΈ°μ¬μλ‘λΆν° μ¬μ©μμκ² λΆμ¬λλ λͺ μμ μΈ νΉνκΆ λΆμ¬κ° ν¬ν¨λμ΄ μμ΅λλ€.
μ΄ νλ‘μ νΈμ λν κΈ°μ¬λ λμΌν Apache 2.0 λΌμ΄μ μ€μ λ°λΌ λΌμ΄μ μ€κ° λΆμ¬λ©λλ€.
μ μκΆ κ³ μ§λ₯Ό 무λ¨μΌλ‘ μ κ±°ν κ²½μ° λ²μ μ‘°μΉκ° μ·¨ν΄μ§ μ μμ΅λλ€.
νΉν κ³ μ§
μ΄ νλ μμν¬μ νΉμ κΈ°λ₯(ꡬ쑰체 νκ·Έ μ€ν€λ§ μμ±, HTTP-to-MCP μλ μ΄λν°, OpenAPI-to-MCP μλ μ΄λν°)μ νμ¬ νΉν μΆμ μ€μ λλ€. Apache 2.0 λΌμ΄μ μ€λ κ·νμκ² μ΄ μννΈμ¨μ΄μ μΌλΆλ‘μ μ΄λ¬ν κΈ°λ₯μ μ¬μ©ν μ μλ μꡬμ μ΄κ³ μ μΈκ³μ μ΄λ©° λ‘μ΄ν°κ° μλ νΉν λΌμ΄μ μ€λ₯Ό λΆμ¬ν©λλ€.
β Star History
GoMCPκ° μ μ©νλ€λ©΄ λ³νλ₯Ό λλ¬μ£ΌμΈμ! λ€λ₯Έ μ¬λλ€μ΄ νλ‘μ νΈλ₯Ό λ°κ²¬νλ λ° λμμ΄ λ©λλ€.
Maintenance
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/zhangpanda/gomcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
