MCP Debug Endpoints

Expose Go runtime internals to AI tools via the Model Context Protocol (MCP).

Overview

The app package provides an optional MCP debug server that exposes Go runtime information to AI tools. It uses the Model Context Protocol to let LLM-based tools inspect goroutine counts, heap usage, GC statistics, build info, and application configuration.

Security Warning: Debug MCP endpoints expose sensitive runtime information. NEVER enable them in production without proper security measures.

Basic Configuration

Enable Runtime Tools

Enable the debug MCP server with runtime introspection:

a, err := app.New(
    app.WithDebugEndpoints(
        app.WithMCPDebug(
            app.WithMCPDebugRuntime(),
        ),
    ),
)

Enable All Features

When called without sub-options, WithMCPDebug() enables all features (runtime, config, build):

a, err := app.New(
    app.WithDebugEndpoints(
        app.WithMCPDebug(),
    ),
)

This is equivalent to:

app.WithMCPDebug(
    app.WithMCPDebugRuntime(),
    app.WithMCPDebugConfig(),
    app.WithMCPDebugBuild(),
)

Built-in Tools and Resources

When enabled, the debug MCP server registers these tools and resources:

Tools

ToolEnabled byDescription
runtime_statsWithMCPDebugRuntime()Goroutine count, memory usage, GC stats, uptime. Includes AI-useful anomaly signals.
goroutine_profileWithMCPDebugRuntime()Full goroutine stack dump with state summary. Useful for leak detection.
gc_analysisWithMCPDebugRuntime()Detailed GC statistics including pause times and CPU fraction.

Resources

Resource URIEnabled byDescription
rivaas://runtime/overviewWithMCPDebugRuntime()Live snapshot of runtime statistics
rivaas://configWithMCPDebugConfig()Sanitized application configuration (no secrets)
rivaas://buildWithMCPDebugBuild()Go build info: module path, Go version, dependencies

AI-Friendly Signals

Each tool and resource includes a signals field with human-readable observations. These help AI tools understand the current state without needing to interpret raw numbers:

  • "goroutine count (4200) exceeds typical threshold — investigate if expected"
  • "heap usage (1.2 GB) is very high — check for memory leaks"
  • "last GC pause (15.3 ms) is high — may cause latency spikes"

Connecting an AI Client

Point your AI tool at the MCP debug endpoint:

http://localhost:8080/_internal/debug/mcp

For Cursor, add to your MCP configuration:

{
  "mcpServers": {
    "rivaas-debug": {
      "url": "http://localhost:8080/_internal/debug/mcp"
    }
  }
}

The debug MCP server uses Streamable HTTP transport. It accepts GET, POST, and DELETE requests on a single endpoint.

Security Considerations

Development

Safe to enable all features unconditionally. Bare WithMCPDebug() enables everything:

a, err := app.New(
    app.WithEnvironment("development"),
    app.WithDebugEndpoints(
        app.WithPprof(),
        app.WithMCPDebug(),
    ),
)

Staging

Enable behind VPN or IP allowlist. Use WithMCPDebugIf for conditional enablement:

a, err := app.New(
    app.WithDebugEndpoints(
        app.WithMCPDebugIf(os.Getenv("MCP_DEBUG") == "true",
            app.WithMCPDebugRuntime(),
        ),
    ),
)

a.Use(IPAllowlistMiddleware([]string{"10.0.0.0/8"}))

Production

Enable only with proper authentication:

a, err := app.New(
    app.WithDebugEndpoints(
        app.WithDebugPrefix("/_internal/debug"),
        app.WithMCPDebug(
            app.WithMCPDebugRuntime(),
        ),
    ),
)

debugAuth := a.Group("/_internal", AdminAuthMiddleware())

Complete Example

package main

import (
    "context"
    "log"
    "os"
    "os/signal"
    "syscall"

    "rivaas.dev/app"
)

func main() {
    ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
    defer cancel()

    a, err := app.New(
        app.WithServiceName("my-api"),
        app.WithServiceVersion("v1.0.0"),

        app.WithDebugEndpoints(
            app.WithPprof(),
            app.WithMCPDebug(),
        ),
    )
    if err != nil {
        log.Fatal(err)
    }

    // Debug MCP: http://localhost:8080/_internal/debug/mcp
    // pprof:     http://localhost:8080/_internal/debug/pprof/

    if err = a.Start(ctx); err != nil {
        log.Fatal(err)
    }
}

Next Steps