mcp-kit

module
v0.5.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 5, 2026 License: MIT

README

mcp-kit

A reusable Go library for building production-grade Model Context Protocol (MCP) servers with OAuth 2.1 authentication, key rotation, audit-ready middleware, and a battle-tested test methodology.

Status: Pre-1.0 (v0.x). API may change. Pin a specific minor version.

What it does

mcp-kit extracts the cross-cutting concerns common to every MCP server:

  • OAuth 2.1 server with PKCE, dynamic client registration, refresh-token rotation, and 90-day signing-key rotation with grace window
  • Bearer middleware that accepts both OAuth-issued JWTs and Personal Access Tokens
  • JSON-RPC envelope rewriter so SDK protocol errors come out as canonical JSON-RPC envelopes (not plain-text 400s)
  • Origin allowlist with explicit loopback allowance for browser MCP clients
  • OIDC / OAuth discovery endpoints (/.well-known/openid-configuration, /.well-known/oauth-authorization-server, /.well-known/oauth-protected-resource, /.well-known/jwks.json)
  • CLI auth helper (mcpkit/cliauth) with browser-based PKCE flow and issuer-scoped 0600 file-backed token cache
  • Ent schema mixins for OAuth tables (oauth_client, oauth_signing_key, oauth_authorization_code, oauth_access_token, oauth_refresh_token, personal_access_token)
  • E2E test methodology templates with phased dispatch runbook, evidence captures, and lessons-learned IDs

It does not ship:

  • Domain tools, resources, or prompts — those live in the consumer
  • A user table or password store — consumers authenticate browser consent and map subjects themselves
  • A permission/RBAC model — consumers enforce tool/resource authorization in their domain layer
  • An audit log table — consumers map kit and domain events into their own audit system

Quickstart

import (
    "net/http"

    "github.com/haakco/mcp-kit/mcpkit"
    "github.com/haakco/mcp-kit/oauth"
    "github.com/haakco/mcp-kit/oauth/consent"
    "github.com/haakco/mcp-kit/oidc"
)

func main() {
    // 1. Construct the OAuth provider using your app's storage + key manager.
    oauthProv, err := oauth.New(oauth.Config{
        Issuer:        "https://my-mcp.example.com",
        Store:         myapp.NewOAuthStore(db),
        KeyManager:    myapp.NewOAuthKeyManager(db),
        AllowedScopes: []string{"mcp.read", "mcp.write", "offline_access"},
        DefaultScopes: []string{"mcp.read", "offline_access"},
    })
    if err != nil { /* handle */ }

    // 2. Wrap your official Go SDK MCP HTTP handler.
    // The handler still owns domain authorization and audit: validate scopes,
    // check RBAC, and emit audit events inside each tool/resource.
    mcpServer, err := mcpkit.New(mcpkit.Config{
        Handler: myapp.NewAuditedMCPHandler(myapp.MCPDeps{
            Authz: myapp.NewAuthz(db),
            Audit: myapp.NewAuditEmitter(db),
        }),
        Bearer: mcpkit.BearerConfig{
            TokenValidator: myapp.NewPATValidator(db),
            Introspector:   oauthProv.OAuth2Provider(),
            SessionFactory: oauth.NewEmptySession,
        },
        AllowedOrigins: []string{"https://app.example.com"},
        AllowLoopback:  isDev,
    })
    if err != nil { /* handle */ }

    // 3. Mount on your HTTP framework.
    mux := http.NewServeMux()
    mux.Handle("/mcp", mcpServer.Handler())
    authorize, err := consent.NewHandler(consent.Config{
        Provider:       oauthProv,
        Authenticator:  myapp.NewAuthenticator(db),
        Renderer:       myapp.NewConsentRenderer(),
        PublicURL:      "https://my-mcp.example.com",
        ApprovalSecret: myapp.OAuthApprovalSecret(), // exactly 32 bytes
        AuditEmitter:   myapp.NewAuditEmitter(db),
    })
    if err != nil { /* handle */ }
    mux.Handle("/oauth/authorize", authorize)
    mux.Handle("/oauth/token", oauthProv.TokenHandler())
    mux.Handle("/oauth/register", oauthProv.RegisterHandler())

    discovery := oidc.NewDiscoveryConfig("https://my-mcp.example.com", []string{"mcp.read", "mcp.write", "offline_access"})
    discovery.RegisterRoutes(mux, oidc.RouteConfig{
        ResourceURL: "https://my-mcp.example.com/mcp",
        JWKS:        oidc.JWKSHandler(myapp.NewOAuthKeyManager(db)),
    })

    http.ListenAndServe(":8080", mux)
}

Authentication is not authorization. mcp-kit validates bearer tokens, Origin, metadata, and JSON-RPC envelope behavior. Consumers must still enforce tool/resource permissions and audit every sensitive domain operation in their handlers.

Documentation

Status

Phase Status
Design ✅ — see DESIGN.md
v0.1.0 spike — package skeletons + envelope middleware ✅ Complete
v0.2.0 — OAuth core extracted from skills-mcp ✅ Complete
v0.3.0 — skills-mcp migrated to kit ✅ Complete
v0.4.0 — Vorrent migrated to kit ✅ Complete
v1.0.0 — Meridian on kit + cycle methodology shipped Planned

License

MIT — see LICENSE.

Directories

Path Synopsis
_examples
minimal-server command
Package audit defines the audit emitter interface that mcp-kit consumers implement to receive tool-call, OAuth, and key-rotation events.
Package audit defines the audit emitter interface that mcp-kit consumers implement to receive tool-call, OAuth, and key-rotation events.
Package authz defines the authorization interface that mcp-kit consumers implement to expose their existing RBAC / permission model to the kit.
Package authz defines the authorization interface that mcp-kit consumers implement to expose their existing RBAC / permission model to the kit.
Package mcpkit is the top-level convenience entry point for building MCP servers with mcp-kit.
Package mcpkit is the top-level convenience entry point for building MCP servers with mcp-kit.
Package mcpmw provides MCP-specific HTTP middleware: JSON-RPC envelope rewriting, Origin allowlist, and (in later versions) audit emitter wrapping.
Package mcpmw provides MCP-specific HTTP middleware: JSON-RPC envelope rewriting, Origin allowlist, and (in later versions) audit emitter wrapping.
consent
Package consent provides one shared OAuth 2.1 authorization-endpoint handler that performs browser-based login, optional 2FA challenge, explicit user consent, and produces a fosite authorization response with the canonical MCP audience bound server-side per RFC 8707.
Package consent provides one shared OAuth 2.1 authorization-endpoint handler that performs browser-based login, optional 2FA challenge, explicit user consent, and produces a fosite authorization response with the canonical MCP audience bound server-side per RFC 8707.
consent/consenttest
Package consenttest provides test fixtures for consent.Handler consumers.
Package consenttest provides test fixtures for consent.Handler consumers.
consent/hmacstore
Package hmacstore implements consent.ApprovalTokenStore using a stateless HMAC-signed payload plus an in-memory replay map.
Package hmacstore implements consent.ApprovalTokenStore using a stateless HMAC-signed payload plus an in-memory replay map.
consent/sessionstore
Package sessionstore implements consent.ApprovalTokenStore using a consumer-supplied session backend.
Package sessionstore implements consent.ApprovalTokenStore using a consumer-supplied session backend.
keys
Package keys manages OAuth JWT signing keys.
Package keys manages OAuth JWT signing keys.
storage
Package storage adapts consumer persistence to Fosite's OAuth storage interfaces.
Package storage adapts consumer persistence to Fosite's OAuth storage interfaces.
Package oidc serves OAuth/OIDC discovery documents for MCP servers.
Package oidc serves OAuth/OIDC discovery documents for MCP servers.
Package userstore defines the user-lookup interface that mcp-kit consumers implement to expose their existing user table to the OAuth flow.
Package userstore defines the user-lookup interface that mcp-kit consumers implement to expose their existing user table to the OAuth flow.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL