1
0
mirror of https://github.com/go-micro/go-micro.git synced 2026-04-30 19:15:24 +02:00
Files
Copilot ac47a4650a MCP gateway: add per-tool scopes, tracing, rate limiting, and audit logging (#2850)
* Initial plan

* Add MCP per-tool scopes, tracing, rate limiting, and audit logging

- Add Scopes field to Tool struct for per-tool scope requirements
- Add Auth (auth.Auth) integration to Options for token inspection
- Add trace ID generation (UUID) propagated via metadata to downstream RPCs
- Add per-tool rate limiting with configurable requests/sec and burst
- Add AuditFunc callback for immutable tool-call audit records
- Extract tool scopes from registry endpoint metadata ("scopes" key)
- Update both HTTP and stdio transports with auth/trace/rate/audit
- Add comprehensive tests for all new functionality

Co-authored-by: asim <17530+asim@users.noreply.github.com>

* Revert unrelated example go.mod changes

Co-authored-by: asim <17530+asim@users.noreply.github.com>

* Remove auto-generated example go.sum files

Co-authored-by: asim <17530+asim@users.noreply.github.com>

* Add WithEndpointScopes helper, gateway-level ToolScopes, and documentation

- Add server.WithEndpointScopes() for declaring per-endpoint auth scopes at
  handler registration time
- Add mcp.Options.ToolScopes for gateway-level scope overrides without
  changing individual services
- Update documented example to show WithEndpointScopes usage
- Update examples/mcp/README.md with scopes, tracing, and rate-limiting docs
- Update gateway/mcp/DOCUMENTATION.md with scopes section and FAQ
- Add tests for both new features

Co-authored-by: asim <17530+asim@users.noreply.github.com>

* Fix ToolScopes doc comment: clarify override (not merge) semantics

Co-authored-by: asim <17530+asim@users.noreply.github.com>

* Revert unrelated example go.mod/go.sum changes

Co-authored-by: asim <17530+asim@users.noreply.github.com>

* Rename ToolScopes to Scopes in MCP Options

The field name "Scopes" is more universal and consistent with how
auth scopes are used throughout go-micro. Updated all code references,
tests, and documentation.

Co-authored-by: asim <17530+asim@users.noreply.github.com>

* MCP gateway: add per-tool scopes, tracing, rate limiting, and audit logging

Co-authored-by: asim <17530+asim@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: asim <17530+asim@users.noreply.github.com>
2026-02-11 21:01:31 +00:00
..
2026-02-11 14:12:21 +00:00

MCP Examples

Examples demonstrating Model Context Protocol (MCP) integration with go-micro.

Examples

hello - Minimal Example Start Here

The simplest possible MCP-enabled service. Perfect for learning the basics.

What it shows:

  • Automatic documentation extraction from Go comments
  • MCP gateway setup with 3 lines
  • Ready for Claude Code

Run it:

cd hello
go run main.go

Complete example showing all MCP features with a user service.

What it shows:

  • Multiple endpoints (GetUser, CreateUser)
  • Rich documentation with examples
  • Per-endpoint auth scopes via server.WithEndpointScopes()
  • Pre-populated test data
  • Production-ready patterns

Run it:

cd documented
go run main.go

Quick Start

1. Write Your Service

Add Go doc comments to your handler methods:

// SayHello greets a person by name. Returns a friendly greeting message.
//
// @example {"name": "Alice"}
func (g *Greeter) SayHello(ctx context.Context, req *HelloRequest, rsp *HelloResponse) error {
    rsp.Message = "Hello " + req.Name + "!"
    return nil
}

type HelloRequest struct {
    Name string `json:"name" description:"Person's name to greet"`
}

2. Register Handler (Auto-Extracts Docs!)

handler := service.Server().NewHandler(new(Greeter))
service.Server().Handle(handler)

3. Start MCP Gateway

go mcp.ListenAndServe(":3000", mcp.Options{
    Registry: service.Options().Registry,
})

Testing

HTTP API

# List tools
curl http://localhost:3000/mcp/tools | jq

# Call a tool
curl -X POST http://localhost:3000/mcp/call \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "greeter.Greeter.SayHello",
    "input": {"name": "Alice"}
  }' | jq

Claude Code (Stdio)

Start MCP server:

micro mcp serve

Add to ~/.claude/claude_desktop_config.json:

{
  "mcpServers": {
    "my-services": {
      "command": "micro",
      "args": ["mcp", "serve"]
    }
  }
}

Restart Claude Code and ask Claude to use your services!

Features

Automatic Documentation Extraction

Just write Go comments - documentation is extracted automatically:

  • Go doc comments → Tool descriptions
  • @example tags → Example inputs for AI
  • Struct tags → Parameter descriptions

Multiple Transports

  • Stdio - For Claude Code (recommended)
  • HTTP/SSE - For web-based agents

MCP Command Line

micro mcp serve              # Start with stdio
micro mcp serve --address :3000  # Start with HTTP
micro mcp list               # List tools
micro mcp test <tool-name>   # Test a tool

Zero Configuration

  • No manual tool registration
  • No API wrappers
  • No code generation
  • Just write normal Go code!

Per-Tool Auth Scopes

Declare required scopes when registering a handler:

handler := service.Server().NewHandler(
    new(BlogService),
    server.WithEndpointScopes("Blog.Create", "blog:write"),
    server.WithEndpointScopes("Blog.Delete", "blog:admin"),
)

Or define scopes at the gateway layer without changing services:

mcp.Serve(mcp.Options{
    Registry: reg,
    Auth:     authProvider,
    Scopes: map[string][]string{
        "blog.Blog.Create": {"blog:write"},
        "blog.Blog.Delete": {"blog:admin"},
    },
})

Tracing, Rate Limiting & Audit Logging

Every tool call generates a trace ID that propagates through the RPC chain. Configure rate limiting and audit logging at the gateway:

mcp.Serve(mcp.Options{
    Registry: reg,
    Auth:     authProvider,
    RateLimit: &mcp.RateLimitConfig{
        RequestsPerSecond: 10,
        Burst:             20,
    },
    AuditFunc: func(r mcp.AuditRecord) {
        log.Printf("[audit] trace=%s tool=%s account=%s allowed=%v",
            r.TraceID, r.Tool, r.AccountID, r.Allowed)
    },
})

Documentation

Learn More