mcp-gate: A Go Sidecar That Makes Claude.ai Custom Connectors Work with RFC 9728 and JWT Validation
mcp-gate is a Go sidecar that enables Claude.ai custom connectors by serving RFC 9728 metadata, validating JWTs via JWKS, and reverse-proxying requests.
Why Claude.ai Custom Connectors Often Fail with Off‑the‑Shelf MCP Servers
Connecting Claude.ai to a custom MCP (Model Connector Protocol) server can be surprisingly brittle. The connector flow expects the MCP endpoint to publish OAuth 2.1 protected resource metadata at /.well-known/oauth-protected-resource (RFC 9728), point to an authorization server, and accept signed Bearer JWTs validated against a JWKS endpoint. Most MCP server projects — whether written in Go, Python, or TypeScript, or deployed from an existing package — focus on the protocol semantics and not on the surrounding auth plumbing. When a connector fetches /.well-known/oauth-protected-resource and finds nothing, Claude.ai will silently stop attempting authentication; there’s no helpful error returned. That mismatch between protocol implementation and authentication expectations is the problem mcp-gate was created to solve.
What mcp-gate Is and What It Protects
mcp-gate is a compact, stateless Go binary designed to sit in front of any MCP server as an authentication sidecar. Its job is narrow and specific: expose RFC 9728-compliant protected-resource metadata, perform per-request Bearer JWT validation against a configurable JWKS, and forward valid requests to the upstream MCP server. It makes no assumptions about the internals of the MCP server — it neither transforms requests nor alters protocol-level behavior — it simply ensures Claude.ai (or any client following the same expectations) can discover auth metadata and deliver authenticated calls that your MCP backend will accept.
Because mcp-gate implements only the auth-facing pieces, it works with a variety of authorization backends. Any OIDC‑compatible authorization server that publishes a JWKS endpoint — Keycloak, Auth0, Okta, Authentik, and similar systems — can issue tokens that mcp-gate will validate and pass through.
How mcp-gate Works: Request Flow and Validation Steps
At a high level the runtime flow is straightforward:
- When a connector (e.g., Claude.ai) attempts to initialize, it fetches /.well-known/oauth-protected-resource from the resource URI you publish. mcp-gate serves that document and points clients to the configured authorization server.
- During normal operation, the client negotiates an OAuth token with the authorization server and then issues requests with a Bearer JWT.
- mcp-gate intercepts every incoming request, extracts the Bearer token, and validates it. Validation includes signature verification against keys fetched from the JWKS URI, expiry checks, issuer and audience matching, and optional scope verification.
- If validation succeeds, mcp-gate reverse-proxies the request to the configured upstream MCP server. If validation fails, it returns a 401 response.
Under the hood the binary caches JWKS material in memory and refreshes it according to a time-to-live policy to avoid fetching the remote keyset on every request while still supporting key rotation. The validator uses RS256 signature verification and enforces standard token claims along with any operator-defined constraints (for example, a required audience value).
Architecture and Deployment Patterns for mcp-gate
mcp-gate is intentionally minimal in architecture: a single stateless process sits in the request path and performs auth-related duties. That design maps well to a few common deployment patterns:
- Sidecar container in Kubernetes: Run mcp-gate next to the MCP pod; set the resource URI to the service address for the sidecar and point the sidecar at the local MCP container for upstream proxying.
- Reverse proxy in front of a single-host MCP: Bind mcp-gate to a public IP or domain and have it forward validated requests to the MCP server on a private port.
- Edge container in a Docker Compose stack: Use environment variables to configure the auth endpoints and upstream URL so the same image runs in local dev and production with no config files.
Configuration is environment-variable driven to simplify containerized deployments: listen address, upstream URL, resource URL, authorization server base, JWKS URI, expected issuer, and expected audience are all provided as environment settings. That keeps the binary simple to run in Docker, Kubernetes, or bare-metal environments without a configuration file format to manage.
Operational Details: Logging, Observability, and Scaling
Operationally, mcp-gate favors transparency and observability. Every request is emitted as structured JSON with fields such as method, path, status, duration_ms, client_ip, and user_agent. Those logs are designed for ingestion by observability stacks like Loki, Alloy, or any structured log aggregator and make it easier to troubleshoot denied requests or performance bottlenecks.
Because the process is stateless and caches only ephemeral JWKS entries, horizontal scaling is straightforward. You can run multiple mcp-gate instances behind a load balancer or leverage Kubernetes replica sets to handle higher throughput. In large deployments you may tune JWKS cache TTLs and refresh jitter to avoid thundering-herd fetches when keys rotate.
Security Model and Validation Controls
mcp-gate enforces a conservative security posture by default:
- Signature verification: Tokens are validated using RS256 against keys obtained from the configured JWKS URI.
- Token lifetime: Standard exp (expiry) and nbf (not before) claims are checked to prevent replay of expired tokens.
- Issuer and audience: Expected issuer and audience values are required to match configuration, preventing token reuse across unrelated clients.
- Scope and claims: Operators can define necessary scopes or custom claim checks to ensure tokens grant the expected permissions before the request is forwarded.
Key rotation and JWKS availability are key operational considerations. mcp-gate caches key material with TTL-based refresh and will reject tokens signed by keys not present in the cached JWKS. For high-availability setups, ensure your authorization server’s JWKS endpoint is reachable from all mcp-gate instances and that its TTLs and rotation practices are coordinated with your service-level objectives.
Why a Separate Binary Is Often the Right Choice
Embedding full OAuth/JWKS support directly into every MCP server implementation mixes cross-cutting concerns into application code. There are several reasons to prefer a dedicated sidecar:
- Separation of concerns: Authentication, token validation, and metadata publication are orthogonal to MCP protocol behavior. Keeping them outside the MCP codebase reduces complexity.
- Language-agnostic integration: A standalone sidecar works whether your MCP server is written in Go, Python, Rust, or Node.js.
- Operational uniformity: Centralizing auth logic in a single component reduces the maintenance burden and ensures consistent behavior across deployments.
- Scalability and reliability: A stateless proxy with cached keysets is easier to scale and less prone to failures tied to application state.
mcp-gate embraces this model: a single-purpose binary with no session state, configured entirely via environment variables, built for container ecosystems.
Practical Integration Scenarios and Ecosystem Compatibility
mcp-gate is deliberately compatible with mainstream identity providers and developer tools. In practice that means:
- With Keycloak or Authentik you can configure a client for the MCP connector and point mcp-gate at the authorization server’s endpoints.
- With managed services like Auth0 or Okta, create an application/client that issues JWTs and use the provided JWKS URI and issuer values.
- For teams using CI/CD pipelines or infrastructure-as-code, mcp-gate’s environment-variable configuration maps cleanly into deployment manifests, Helm charts, and Docker Compose files.
- In enterprise environments with SSO and existing identity stores, administrators can reuse the same authorization server configuration to secure both internal and external connectors.
On the broader toolchain front, mcp-gate is complementary to observability stacks, CI/CD tooling, and infrastructure automation. It doesn’t replace API gateways or service meshes, but it can be used in front of MCP endpoints that sit behind those layers. For example, teams that already use automation platforms, CRMs, or product analytics systems that consume model connectors can integrate mcp-gate without altering their identity provider configuration.
When to Use mcp-gate and Who Benefits Most
mcp-gate is most useful when you need a quick, auditable, and standards-compliant way to make an MCP server reachable by clients that expect RFC 9728 metadata and JWKS-backed token validation. Typical beneficiaries include:
- Small teams that want to avoid building authentication into every MCP service implementation.
- Organizations running self-hosted Claude.ai custom connectors that need a compliant protected-resource endpoint and robust JWT validation.
- DevOps teams that prefer sidecar deployments to keep runtime responsibilities separated.
- Security teams that require consistent token validation and logging for auditability.
If your deployment already includes an API gateway capable of publishing RFC 9728 metadata and validating JWTs to your exact policy, the gateway may suffice. mcp-gate fills the gap when such infrastructure is missing or when you want a lightweight, easy-to-deploy alternative specific to MCP endpoints.
Developer Experience: Quickstarts and Common Commands
mcp-gate intentionally keeps the developer experience simple. Typical setup steps include:
- Configure environment variables for listen address, upstream MCP URL, the public-facing resource URI, authorization server base URL, JWKS URI, expected issuer, and audience.
- Launch the binary in the same environment as your MCP server — locally via go run in development, as a Docker container, or as a Kubernetes sidecar in production.
- Verify that /.well-known/oauth-protected-resource responds with metadata that points to your authorization server and that the JWKS URI is reachable from the mcp-gate process.
- Test an end-to-end flow by having a client obtain a token from the authorization server and make a proxied request through mcp-gate to the MCP backend.
Because configuration is environment-driven, the same container image can be used across local, staging, and production environments simply by changing environment variables or Kubernetes manifest values.
Broader Implications for the Model Connector Ecosystem and Security Posture
The need for a tool like mcp-gate highlights a larger gap in how developer tooling and model connector ecosystems handle authentication: protocol implementations frequently underinvest in identity integration. That gap has consequences:
- Fragmentation: Individual projects re-implement token validation inconsistently, which increases the risk of subtle security bugs and operational divergence.
- Developer friction: Teams lose engineering time when each connector requires custom auth plumbing rather than reusing a well-defined sidecar or gateway.
- Standards adoption: RFC 9728 and related OIDC practices are robust and address common needs, but adoption is uneven; tools like mcp-gate lower the barrier to compliance.
For businesses, consolidating authentication concerns into a small, auditable component reduces surface area for error and makes audits simpler. For developers, it shifts the focus back to building domain logic in MCP servers instead of reengineering identity stacks.
Maturity, Current Status, and Community Fit
The design goals for mcp-gate emphasize small scope, reliability, and predictable behavior. In practice that means the core feature set — RFC 9728 metadata serving, JWKS-backed JWT validation, and reverse proxying — is stable and appropriate for production use. The binary’s stateless nature and environment-variable configuration model make it suitable for teams that prefer minimal operational overhead.
Because mcp-gate intentionally avoids opinionated request transformations or protocol adaptations, it slots easily into existing deployment topologies. Teams that want to extend behavior (for example, request-level instrumentation or additional claim enforcement) can run mcp-gate alongside other infrastructure components such as service meshes or API gateways.
Next Steps and How Teams Can Adopt mcp-gate
Adoption steps are straightforward: evaluate the compatibility of your authorization server (it should publish a JWKS endpoint and support OIDC/OAuth2 flows), configure mcp-gate’s environment values, and run it in front of a staging MCP server. Test token issuance and verification flows, exercise key rotation, and confirm log ingestion into your observability pipeline. For Kubernetes users, packaging the sidecar as part of a pod or as a separate deployment with a ClusterIP service are both viable approaches.
mcp-gate is also a useful short-term mitigation if you plan to consolidate authentication into a centralized gateway later. Because it provides the required discovery document and token enforcement, it allows teams to validate connector integrations quickly without investing in larger gateway projects.
Looking ahead, expect to see patterns converge around small, secure sidecars and shared identity configurations for connectors. As model connectors become more widespread across AI tools, CRM integrations, and automation platforms, a standardized approach to publishing protected-resource metadata and validating JWTs will reduce integration friction and improve security across the ecosystem.
As model connector deployments scale, there’s an opportunity for tools like mcp-gate to evolve in ways that address multi-tenant policies, richer claim mapping, and tighter integration with identity orchestration systems. Those directions would preserve the core benefit — a focused auth sidecar — while providing additional controls for enterprises that need them.




















