GoMCP
GoMCP
La forma rápida e idiomática de construir servidores MCP en Go.
🚀 Enlaces rápidos
Protocolo MCP: https://modelcontextprotocol.io
Related MCP server: Filesystem MCP Server
🎯 ¿Qué es GoMCP?
GoMCP es un framework para construir servidores del Protocolo de Contexto de Modelo (MCP), no solo un SDK. Piénsalo como "Gin para MCP".
MCP es el protocolo abierto que permite a las aplicaciones de IA (Claude Desktop, Cursor, Kiro, VS Code Copilot) llamar a herramientas externas, leer fuentes de datos y usar plantillas de prompts. GoMCP hace que la construcción de esos servidores sea trivial.
¿Por qué GoMCP?
mcp-go (mark3labs) | SDK oficial de Go | GoMCP | |
Nivel | SDK | SDK | Framework |
Generación de esquema | Manual | Etiqueta | |
Middleware | Hooks básicos | Ninguno | Cadena completa (Logger, Auth, RateLimit, OTel…) |
Grupos de herramientas | No | No | |
Importar rutas de Gin | No | No | ✅ Una línea |
Importar OpenAPI/Swagger | No | No | ✅ Una línea |
Importar servicios gRPC | No | No | ✅ |
Autenticación integrada | No | No | Bearer, API Key, Basic + RBAC |
Inspector UI | No | No | ✅ |
Utilidades de prueba | Básicas | No | Paquete mcptest |
🛠️ Stack tecnológico
Requisitos del entorno
Requisito | Versión |
Go | ≥ 1.25 |
Protocolo MCP | 2024-11-05 (retrocompatible con 2025-11-25) |
Dependencias principales
Tecnología | Descripción |
Biblioteca estándar de Go | Framework central — cero dependencias externas |
Gin | Solo adaptador — importar rutas de Gin existentes |
gRPC | Solo adaptador — importar servicios gRPC |
OpenTelemetry | Opcional — rastreo distribuido |
YAML v3 | Solo proveedor — recarga en caliente de definiciones de herramientas |
🌟 Características principales
🔧 Desarrollo de herramientas
Esquema automático mediante etiquetas de estructura — define parámetros con estructuras de Go y etiquetas
mcp, el JSON Schema se genera automáticamenteManejadores tipados —
func(*Context, Input) (Output, error)— sin análisis manual de parámetrosValidación de parámetros — requerido, mín/máx, enum, patrón — verificado antes de que se ejecute tu manejador
Versionado de componentes — registra múltiples versiones, los clientes llaman a
name@versionTareas asíncronas — las herramientas de larga duración devuelven un ID de tarea, con sondeo y cancelación
🔌 Adaptadores (Diferenciador principal)
Adaptador de Gin — importa rutas de Gin existentes como herramientas MCP con una línea
Adaptador de OpenAPI — genera herramientas a partir de documentos Swagger/OpenAPI 3.x
Adaptador de gRPC — importa métodos de servicio gRPC como herramientas MCP
🔐 Seguridad
BearerAuth — validación de token JWT
APIKeyAuth — validación de clave API mediante cabecera
BasicAuth — autenticación HTTP básica
RequireRole / RequirePermission — autorización RBAC en grupos de herramientas
🧩 Características del framework
Cadena de middleware — Logger, Recovery, RequestID, Timeout, RateLimit, OpenTelemetry
Grupos de herramientas — organiza herramientas con prefijos y middleware a nivel de grupo
Recursos y Prompts — soporte completo de MCP incluyendo plantillas URI y prompts parametrizados
Autocompletado — sugiere valores para argumentos de prompts/recursos
🚀 Listo para producción
Múltiples transportes — stdio (Claude Desktop, Cursor, Kiro) y HTTP transmitible con SSE
Inspector MCP — interfaz de depuración web integrada para explorar y probar herramientas
Recarga en caliente — carga definiciones de herramientas desde archivos YAML con vigilancia de archivos
Paquete mcptest — cliente en memoria para pruebas unitarias con soporte de instantáneas
🏗️ Arquitectura
┌──────────────────────────────────────────────────────────────┐
│ 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 │
└──────────────────────────────────────────────────────────────┘Estructura del proyecto
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📦 Instalación
go get github.com/zhangpanda/gomcp⚡ Inicio rápido
5 líneas para un servidor MCP funcional
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()
}La estructura SearchInput genera automáticamente este JSON Schema:
{
"type": "object",
"properties": {
"query": { "type": "string", "description": "Search keyword" },
"limit": { "type": "integer", "default": 10, "minimum": 1, "maximum": 100 }
},
"required": ["query"]
}Los parámetros inválidos son rechazados antes de que se ejecute tu manejador:
validation failed: query: required; limit: must be <= 100📖 Guía de uso
Referencia de etiquetas de estructura
Etiqueta | Tipo | Descripción | Ejemplo |
| flag | El campo debe ser proporcionado |
|
| string | Descripción legible por humanos |
|
| any | Valor predeterminado |
|
| number | Valor mínimo (inclusivo) |
|
| number | Valor máximo (inclusivo) |
|
| string | Valores permitidos separados por tubería |
|
| string | Validación de expresión regular |
|
Combinar: mcp:"required,desc=Correo electrónico del usuario,pattern=^[^@]+@[^@]+$"
Tipos soportados: string, int, float64, bool, []T, estructuras anidadas.
Herramientas
Manejador simple:
s.Tool("hello", "Say hello", func(ctx *gomcp.Context) (*gomcp.CallToolResult, error) {
return ctx.Text("Hello, " + ctx.String("name")), nil
})Manejador tipado (recomendado):
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)
})Recursos
// 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
})Prompts
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
},
)Middleware
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 authMiddleware personalizado:
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
}
}Grupos de herramientas
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.deleteAdaptadores
Gin — una línea para importar tu API existente:
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 — generar desde documentos 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"},
})Versionado de componentes
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 versionTareas asíncronas
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/cancelRecarga en caliente
s.LoadDir("./tools/", gomcp.DirOptions{Watch: true})Inspector MCP
s.Dev(":9090") // http://localhost:9090 — browse and test all toolsPruebas
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)
}Transportes
s.Stdio() // Claude Desktop, Cursor, Kiro
s.HTTP(":8080") // Remote deployment with SSE
s.Handler() // Embed in existing HTTP serverUso con clientes de IA
{
"mcpServers": {
"my-server": {
"command": "/path/to/your/binary"
}
}
}Funciona con Claude Desktop, Cursor, Kiro, Windsurf, VS Code Copilot y cualquier cliente compatible con MCP.
📋 Hoja de ruta
[x] Núcleo: Herramienta, Recurso, Prompt con soporte completo del protocolo MCP
[x] Generación automática de esquema mediante etiquetas de estructura + validación de parámetros
[x] Cadena de middleware (Logger, Recovery, RateLimit, Timeout, RequestID)
[x] Middleware de autenticación (Bearer / API Key / Basic) + autorización RBAC
[x] Grupos de herramientas con nombres de prefijo y grupos anidados
[x] Transportes stdio + HTTP transmitible con notificaciones SSE
[x] Adaptador de Gin — importar rutas de Gin existentes como herramientas MCP
[x] Adaptador de OpenAPI — generar herramientas a partir de documentos Swagger/OpenAPI
[x] Adaptador de gRPC — importar servicios gRPC como herramientas MCP
[x] Integración con OpenTelemetry
[x] Paquete mcptest con pruebas de instantáneas
[x] Versionado de componentes + obsolescencia
[x] Tareas asíncronas con sondeo y cancelación
[x] Interfaz de depuración web MCP Inspector
[x] Proveedor de recarga en caliente desde YAML
[x] Autocompletado para argumentos de prompt/recurso
[ ] Soporte de cliente MCP (llamadas de servidor a servidor)
🤝 Comentarios y soporte
Informes de errores: GitHub Issues
Solicitudes de funciones: GitHub Issues
Discusiones: GitHub Discussions
💡 Lectura recomendada: Cómo hacer preguntas de manera inteligente
⚖️ Derechos de autor y licencia
Copyright © 2026 Colaboradores de GoMCP
Licenciado bajo la Licencia Apache 2.0.
Notas importantes
Este proyecto es de código abierto y gratuito tanto para uso personal como comercial bajo la licencia Apache 2.0.
Debes conservar el aviso de derechos de autor, el texto de la licencia y cualquier aviso de atribución en todas las copias o partes sustanciales del software.
La licencia Apache 2.0 incluye una concesión expresa de derechos de patente de los colaboradores a los usuarios.
Las contribuciones a este proyecto están licenciadas bajo la misma licencia Apache 2.0.
La eliminación no autorizada de los avisos de derechos de autor puede resultar en acciones legales.
Aviso de patente
Ciertas características de este framework (generación de esquema mediante etiquetas de estructura, adaptador automático de HTTP a MCP, adaptador automático de OpenAPI a MCP) son objeto de solicitudes de patente pendientes. La licencia Apache 2.0 te otorga una licencia de patente perpetua, mundial y libre de regalías para usar estas características como parte de este software.
⭐ Historial de estrellas
Si encuentras útil GoMCP, ¡por favor considera darle una estrella! Ayuda a otros a descubrir el proyecto.
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