GoMCP

GoMCP

About The fast, idiomatic way to build MCP servers in Go. Gin-like DX with struct-tag auto schema, middleware, adapters for Gin/OpenAPI/gRPC.

Category
Visit Server

README

GoMCP

Go Version License Release gomcp MCP server

The fast, idiomatic way to build MCP servers in Go.

δΈ­ζ–‡ζ–‡ζ‘£


πŸš€ Quick Links

  • GitHub: https://github.com/zhangpanda/gomcp
  • Gitee: https://gitee.com/rilegouasas/gomcp
  • MCP Protocol: https://modelcontextprotocol.io

🎯 What is GoMCP?

GoMCP is a framework for building Model Context Protocol (MCP) servers β€” not just an SDK. Think of it as "Gin for MCP".

MCP is the open protocol that lets AI applications (Claude Desktop, Cursor, Kiro, VS Code Copilot) call external tools, read data sources, and use prompt templates. GoMCP makes building those servers trivial.

Why GoMCP?

mcp-go (mark3labs) Official Go SDK GoMCP
Level SDK SDK Framework
Schema generation Manual jsonschema tag mcp tag + auto validation
Middleware Basic hooks None Full chain (Logger, Auth, RateLimit, OTel…)
Tool groups No No Yes (user.get, admin.delete)
Import Gin routes No No βœ… One line
Import OpenAPI/Swagger No No βœ… One line
Import gRPC services No No βœ…
Built-in auth No No Bearer, API Key, Basic + RBAC
Inspector UI No No βœ…
Test utilities Basic No mcptest package

πŸ› οΈ Tech Stack

Environment Requirements

Requirement Version
Go β‰₯ 1.25
MCP Protocol 2024-11-05 (backward compatible with 2025-11-25)

Core Dependencies

Technology Description
Go standard library Core framework β€” zero external dependencies
Gin Adapter only β€” import existing Gin routes
gRPC Adapter only β€” import gRPC services
OpenTelemetry Optional β€” distributed tracing
YAML v3 Provider only β€” hot-reload tool definitions

🌟 Core Features

πŸ”§ Tool Development

  • Struct-tag auto schema β€” define parameters with Go structs and mcp tags, JSON Schema generated automatically
  • Typed handlers β€” func(*Context, Input) (Output, error) β€” no manual parameter parsing
  • Parameter validation β€” required, min/max, enum, pattern β€” checked before your handler runs
  • Component versioning β€” register multiple versions, clients call name@version
  • Async tasks β€” long-running tools return task ID, with polling and cancellation

πŸ”Œ Adapters (Core Differentiator)

  • Gin adapter β€” import existing Gin routes as MCP tools with one line
  • OpenAPI adapter β€” generate tools from Swagger/OpenAPI 3.x docs
  • gRPC adapter β€” import gRPC service methods as MCP tools

πŸ” Security

  • BearerAuth β€” JWT token validation
  • APIKeyAuth β€” API key validation via header
  • BasicAuth β€” HTTP Basic authentication
  • RequireRole / RequirePermission β€” RBAC authorization on tool groups

🧩 Framework Features

  • Middleware chain β€” Logger, Recovery, RequestID, Timeout, RateLimit, OpenTelemetry
  • Tool groups β€” organize tools with prefixes and group-level middleware
  • Resource & Prompt β€” full MCP support including URI templates and parameterized prompts
  • Auto-completions β€” suggest values for prompt/resource arguments

πŸš€ Production Ready

  • Multiple transports β€” stdio (Claude Desktop, Cursor, Kiro) and Streamable HTTP with SSE
  • MCP Inspector β€” built-in web debug UI for browsing and testing tools
  • Hot-reload β€” load tool definitions from YAML files with file watching
  • mcptest package β€” in-memory client for unit testing with snapshot support

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        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                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Project Structure

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

πŸ“¦ Installation

go get github.com/zhangpanda/gomcp

⚑ Quick Start

5 lines to a working MCP server

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()
}

The SearchInput struct automatically generates this JSON Schema:

{
  "type": "object",
  "properties": {
    "query": { "type": "string", "description": "Search keyword" },
    "limit": { "type": "integer", "default": 10, "minimum": 1, "maximum": 100 }
  },
  "required": ["query"]
}

Invalid parameters are rejected before your handler runs:

validation failed: query: required; limit: must be <= 100

πŸ“– Usage Guide

Struct Tag Reference

Tag Type Description Example
required flag Field must be provided mcp:"required"
desc string Human-readable description mcp:"desc=Search keyword"
default any Default value mcp:"default=10"
min number Minimum value (inclusive) mcp:"min=0"
max number Maximum value (inclusive) mcp:"max=100"
enum string Pipe-separated allowed values mcp:"enum=asc|desc"
pattern string Regex validation mcp:"pattern=^[a-z]+$"

Combine: mcp:"required,desc=User email,pattern=^[^@]+@[^@]+$"

Supported types: string, int, float64, bool, []T, nested structs.

Tools

Simple handler:

s.Tool("hello", "Say hello", func(ctx *gomcp.Context) (*gomcp.CallToolResult, error) {
    return ctx.Text("Hello, " + ctx.String("name")), nil
})

Typed handler (recommended):

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)
})

Resources

// 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 auth

Custom middleware:

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
    }
}

Tool Groups

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

Adapters

Gin β€” one line to import your existing 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 β€” generate from Swagger docs:

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"},
})

Component Versioning

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

Async Tasks

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

Hot-Reload

s.LoadDir("./tools/", gomcp.DirOptions{Watch: true})

MCP Inspector

s.Dev(":9090") // http://localhost:9090 β€” browse and test all tools

Testing

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)
}

Transports

s.Stdio()          // Claude Desktop, Cursor, Kiro
s.HTTP(":8080")    // Remote deployment with SSE
s.Handler()        // Embed in existing HTTP server

Use with AI Clients

{
  "mcpServers": {
    "my-server": {
      "command": "/path/to/your/binary"
    }
  }
}

Works with Claude Desktop, Cursor, Kiro, Windsurf, VS Code Copilot, and any MCP-compatible client.


πŸ“‹ Roadmap

  • [x] Core: Tool, Resource, Prompt with full MCP protocol support
  • [x] Struct-tag auto schema generation + parameter validation
  • [x] Middleware chain (Logger, Recovery, RateLimit, Timeout, RequestID)
  • [x] Auth middleware (Bearer / API Key / Basic) + RBAC authorization
  • [x] Tool groups with prefix naming and nested groups
  • [x] stdio + Streamable HTTP transports with SSE notifications
  • [x] Gin adapter β€” import existing Gin routes as MCP tools
  • [x] OpenAPI adapter β€” generate tools from Swagger/OpenAPI docs
  • [x] gRPC adapter β€” import gRPC services as MCP tools
  • [x] OpenTelemetry integration
  • [x] mcptest package with snapshot testing
  • [x] Component versioning + deprecation
  • [x] Async tasks with polling and cancellation
  • [x] MCP Inspector web debug UI
  • [x] Hot-reload provider from YAML
  • [x] Auto-completions for prompt/resource arguments

🀝 Feedback & Support

πŸ’‘ Recommended reading: How To Ask Questions The Smart Way


βš–οΈ Copyright & License

Copyright Β© 2026 GoMCP Contributors

Licensed under the Apache License 2.0.

Important Notes

  1. This project is open source and free for both personal and commercial use under the Apache 2.0 license.
  2. You must retain the copyright notice, license text, and any attribution notices in all copies or substantial portions of the software.
  3. The Apache 2.0 license includes an express grant of patent rights from contributors to users.
  4. Contributions to this project are licensed under the same Apache 2.0 license.
  5. Unauthorized removal of copyright notices may result in legal action.

Patent Notice

Certain features of this framework (struct-tag schema generation, HTTP-to-MCP automatic adapter, OpenAPI-to-MCP automatic adapter) are the subject of pending patent applications. The Apache 2.0 license grants you a perpetual, worldwide, royalty-free patent license to use these features as part of this software.


⭐ Star History

If you find GoMCP useful, please consider giving it a star! It helps others discover the project.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured