Skip to content

AS-308: Add Apollo MCP Server with auth to reference architecture#32

Open
andywgarcia wants to merge 9 commits intomainfrom
agent/AS-308-mcp-with-auth
Open

AS-308: Add Apollo MCP Server with auth to reference architecture#32
andywgarcia wants to merge 9 commits intomainfrom
agent/AS-308-mcp-with-auth

Conversation

@andywgarcia
Copy link
Contributor

@andywgarcia andywgarcia commented Mar 9, 2026

Summary

Adds an Apollo MCP Server to the reference architecture, connecting it to the locally-running Apollo Router with OAuth 2.1 authentication via the users subgraph.

Jira ticket: AS-308

What's included

  • Apollo MCP Server Helm chart (deploy/apollo-mcp-server/) — complete Kubernetes deployment with ConfigMaps for server config and GraphQL operations
  • MCP server configuration — streamable HTTP transport with OAuth 2.1 auth pointing to the users subgraph as the authorization server
  • Pre-defined GraphQL operationsMyCart and MyProfileDetails queries scoped to authenticated users
  • Users subgraph auth enhancements:
    • OAuth authorization server metadata endpoint (/.well-known/oauth-authorization-server)
    • JWT kid, issuer, and audience claims for MCP server token validation
    • JWKS alg, use, and kid fields for proper key identification
  • Deploy script (scripts/minikube/12-deploy-mcp-server.sh) — automates MCP server deployment into the Minikube cluster
  • Documentation — setup guide for MCP server deployment and AI agent connection (Claude Desktop, Claude Code, MCP Inspector)

Auth flow

  1. MCP client discovers auth server via /.well-known/oauth-authorization-server on the users subgraph
  2. User authenticates via the login mutation to obtain a JWT
  3. JWT is passed as a Bearer token to the MCP server
  4. MCP server validates token (signature, audience apollo-mcp, expiry) and forwards it to the Router
  5. Router enforces @authenticated and @requiresScopes directives as usual

Acceptance criteria addressed

  • Apollo MCP server starts as part of the local stack and connects to the Router
  • MCP server requires and forwards authentication credentials to the Router
  • Authenticated MCP clients can execute GraphQL operations through the MCP server
  • Unauthenticated requests are rejected with appropriate errors
  • Documentation describes the local MCP + auth setup with sufficient detail

Context

This builds on prior exploration by Daniel Dorsey and Shane Myrick (see Jira comments). The implementation takes a clean approach from main while incorporating key patterns from the prior feature/mcp-auth WIP branch, with fixes for naming consistency and scope alignment.

Demo

Mar-18-2026 13-11-37


Generated by Agentic Developer

…architecture

Adds an Apollo MCP Server deployment to the reference architecture that connects
to the locally-running Apollo Router and enforces OAuth 2.1 authentication using
the users subgraph as the authorization server.

Changes:
- New Helm chart (deploy/apollo-mcp-server/) with deployment, service, and
  ConfigMaps for MCP server config and GraphQL operations
- MCP server config with streamable_http transport and OAuth auth pointing to
  the users subgraph JWKS/metadata endpoints
- Two pre-defined operations (MyCart, MyProfileDetails) for authenticated queries
- Users subgraph: added OAuth authorization server metadata endpoint
  (/.well-known/oauth-authorization-server) for MCP auth discovery
- Users subgraph: enhanced JWT signing with kid, issuer, and audience claims
- JWKS endpoint: added alg, use, and kid fields for proper key identification
- New deployment script (scripts/minikube/12-deploy-mcp-server.sh)
- Documentation: added MCP setup instructions and AI agent connection guide

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@andywgarcia
Copy link
Contributor Author

Ya this wasn't even close to working. Setting it to draft

@andywgarcia andywgarcia marked this pull request as draft March 12, 2026 19:45
@andywgarcia andywgarcia marked this pull request as ready for review March 18, 2026 20:35
@andywgarcia
Copy link
Contributor Author

Ya this wasn't even close to working. Setting it to draft

Fixed. It is functional now

@ganesh-arumugam
Copy link

Did the initial review with Andy. It would be good to have Client ID Metadata document as a preferred mode of communication with our MCP Server. Its part of the new spec and implemented in our Apollo MCP server as well.

docs/setup.md Outdated
|<-- tool results ----------------------| |
```

1. **Discovery** — `mcp-remote` fetches `/.well-known/oauth-authorization-server` from the MCP server, which returns the users subgraph as the authorization server

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would useful to record what settings have been updated with the Idp provider of choice. Like what was the redirect URL, logout URL and how scopes are entered as well.

Image Image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed — expanded the production guide (docs/mcp-production.md) Step 2 with provider-specific walkthroughs for Auth0, Okta, and Keycloak covering:

  • Redirect / callback URLs (Allowed Callback URLs, Sign-in redirect URIs, Valid redirect URIs)
  • Logout URLs (Allowed Logout URLs, Sign-out redirect URIs, Valid post logout redirect URIs)
  • Web origins (for CORS / silent token refresh)
  • How to define scopes — Auth0: Permissions tab under APIs; Okta: Scopes tab under Authorization Servers; Keycloak: Client scopes
  • Where to set audience — provider-specific table (Auth0 API Identifier, Okta Authorization Server, Keycloak audience mapper)
  • Where to find the IdP URL / issuer — provider-specific table with exact dashboard locations

Primary examples now use production-style HTTPS URLs (https://mcp-client.yourdomain.com/callback), with localhost references only in clearly labeled "Local testing" callout blocks.

Also updated the cross-reference in docs/setup.md to deep-link directly to the IdP configuration section.

Standardize the authorization server with the MCP spec's recommended
client registration approach (draft-ietf-oauth-client-id-metadata-document-00).
The AS now detects URL-formatted client_ids, fetches and validates metadata
documents, displays client info on the consent page, and advertises
client_id_metadata_document_supported in its metadata. Dynamic registration
(RFC 7591) is preserved as a fallback. Also enables allow_anonymous_mcp_discovery
so clients can browse tools before authenticating.

Made-with: Cursor
- Updated authorization code structure to include code challenge and method for PKCE compliance.
- Added HTML escaping function to prevent XSS vulnerabilities in user inputs and error messages.
- Improved login page rendering to utilize the new escaping function for client information and parameters.
- Enhanced error handling for invalid client IDs and redirect URIs during the OAuth process.
- Adjusted JWT issuance to dynamically set the issuer based on request headers.

These changes strengthen the security and compliance of the OAuth implementation.
…, Okta, and Keycloak

- Expanded the section on redirect URIs, logout URLs, and scopes for each IdP.
- Added specific configuration steps for Auth0, Okta, and Keycloak, including audience settings and local testing notes.
- Enhanced clarity on defining custom scopes and their importance in the authorization process.
- Updated the setup documentation to reference the new detailed guide for production deployment.
@andywgarcia
Copy link
Contributor Author

Did the initial review with Andy. It would be good to have Client ID Metadata document as a preferred mode of communication with our MCP Server. Its part of the new spec and implemented in our Apollo MCP server as well.

This should be fixed now with a fallback of the dynamic option

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants