Skip to content

fix: Route MCP traffic to unified binary for PRD-061 consent flow#2171

Merged
bjcoombs merged 2 commits intodevelopfrom
fix-demo-mcp-routing
Apr 8, 2026
Merged

fix: Route MCP traffic to unified binary for PRD-061 consent flow#2171
bjcoombs merged 2 commits intodevelopfrom
fix-demo-mcp-routing

Conversation

@bjcoombs
Copy link
Copy Markdown
Collaborator

@bjcoombs bjcoombs commented Apr 8, 2026

Summary

  • Route MCP HTTP traffic (/mcp, /oauth/*, /.well-known/*) to the unified binary instead of the standalone mcp-server container in both demo and develop Caddyfile configs
  • Add MCP OAuth env vars (MCP_OAUTH_ENABLED, MCP_BASE_URL, MCP_OAUTH_CLIENT_ID, MCP_DEFAULT_TENANT_SLUG) to the unified meridian service in both compose files
  • Remove the standalone mcp-server / mcp-server-develop services from demo and develop compose files
  • Remove obsolete Dex-specific MCP env vars (MCP_DEX_ISSUER_URL, MCP_DEX_CLIENT_ID, MCP_DEX_CALLBACK_URL, MCP_JWKS_URL) from .env templates
  • Default MCP_OAUTH_ENABLED=true in env templates

Context

PRD-061 (MCP OAuth Session Unification) replaced Dex-direct auth with a BFF consent flow that requires shared in-memory stores between the BFF and MCP OAuth handler. This only works when both run inside the unified binary (cmd/meridian). The code was merged (#2155-#2160) but the deploy configs still routed MCP traffic to a separate container, causing MCP OAuth to fail: the standalone container completed OAuth token issuance but Claude Code never established an MCP session because the consent stores weren't shared.

Symptoms: MCP server shows "Auth: authenticated" but "Status: needs authentication" in Claude Code.

Deployment notes

After merging, the demo droplet needs:

  1. Copy updated Caddyfile: scp deploy/demo/Caddyfile root@68.183.40.239:/opt/meridian/Caddyfile
  2. Update .env on droplet: set MCP_OAUTH_ENABLED=true, remove MCP_DEX_* vars, remove MERIDIAN_API_KEY (no longer needed for MCP - it runs in-process)
  3. Restart: docker compose down && docker compose up -d (removes the old mcp-server container)
  4. Same for develop environment

Test plan

  • Verify demo MCP OAuth flow: Claude Code -> authorize -> consent page -> approve -> authenticated MCP session
  • Verify develop environment starts without errors
  • Verify MCP OAuth wired with shared stores log message appears in unified binary logs
  • Verify old mcp-server container is no longer running

The MCP OAuth consent flow (PRD-061) requires the BFF and MCP server to
share in-memory consent/state stores, which only works when both run
inside the unified binary. The deploy configs were still routing MCP
traffic to a separate mcp-server container that cannot share stores
with the BFF, causing MCP OAuth to fail silently after token issuance.

- Caddyfile: route /mcp, /oauth/*, /.well-known/* to unified binary
- docker-compose: add MCP env vars to meridian service, remove
  standalone mcp-server service (demo + develop)
- .env templates: remove obsolete Dex-specific MCP vars
  (MCP_DEX_ISSUER_URL, MCP_DEX_CLIENT_ID, MCP_DEX_CALLBACK_URL,
  MCP_JWKS_URL), enable MCP_OAUTH_ENABLED by default
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 8, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c045a29f-2ba9-485d-bfd0-7a65d49bd876

📥 Commits

Reviewing files that changed from the base of the PR and between a6ac3ae and ce87b31.

📒 Files selected for processing (1)
  • deploy/develop/.env.develop.template
🚧 Files skipped from review as they are similar to previous changes (1)
  • deploy/develop/.env.develop.template

📝 Walkthrough

Walkthrough

MCP OAuth 2.1 was moved from a separate container into the unified Meridian binary across demo and develop stacks. Caddy routing, environment templates, and Docker Compose were updated to remove standalone mcp-server, enable embedded OAuth, consolidate JWT signing config, and increase meridian-develop resources.

Changes

Cohort / File(s) Summary
Demo environment
deploy/demo/.env.demo.example, deploy/demo/Caddyfile, deploy/demo/docker-compose.yml
Removed standalone mcp-server; enabled MCP OAuth in-process on meridian. Replaced gRPC/API key and Dex/OIDC vars with unified JWT_SIGNING_KEY_FILE guidance. Caddy routes (/mcp, /oauth, /.well-known/oauth-authorization-server) now reverse-proxy to meridian:8090. Added MCP OAuth env vars to meridian service.
Develop environment & compose
deploy/develop/.env.develop.template, deploy/develop/docker-compose.develop.yml
Embedded MCP OAuth into meridian-develop (removed mcp-server-develop), set MCP_OAUTH_ENABLED=true default, removed MERIDIAN_API_KEY, MCP_SERVER_NAME, and Dex/OIDC/JWKS entries. Added/integrated MCP OAuth env vars into meridian-develop, updated network join and raised resource limits/reservations.
Documentation/comments
(inline env/Caddy/docker-compose comments)
Reworded MCP section to “MCP OAuth 2.1 (AI Integration)”, adjusted JWT signing-key guidance to indicate shared use by BFF and MCP OAuth, and changed key-mount arrow notation (->).

Sequence Diagram(s)

sequenceDiagram
  actor Client
  participant Caddy
  participant Meridian as "Meridian\n(unified binary)\n[BFF + MCP OAuth]"
  participant TokenStore as "In-memory\nconsent/state"

  Client->>Caddy: Request OAuth authorization (/oauth/...)
  Caddy->>Meridian: Reverse proxy to embedded OAuth endpoints
  Meridian->>TokenStore: create consent/state entry
  Meridian-->>Client: Redirect to consent UI / Authorization response (auth code)
  Client->>Meridian: Exchange auth code for token
  Meridian->>TokenStore: validate consent, issue JWT
  Meridian-->>Client: Return JWT
  Client->>Meridian: API call with Bearer JWT (via Caddy)
  Caddy->>Meridian: Proxy API request
  Meridian->>Meridian: Validate JWT (shared signing key)
  Meridian-->>Client: API response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: routing MCP traffic to the unified binary for the PRD-061 consent flow implementation, which aligns with the core objective of all changeset modifications.
Description check ✅ Passed The description comprehensively covers the changeset, including summary of modifications, context for the changes, deployment notes, and a test plan, all directly related to the MCP routing and OAuth unification changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-demo-mcp-routing

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude
Copy link
Copy Markdown

claude Bot commented Apr 8, 2026

Claude Code Review

Commit: ce87b31b | CI: running (CodeQL + security scans pending; Trivy, Dependency Review, Gitleaks passed)

Summary

Clean, well-scoped fix for a real bug -- the MCP OAuth consent flow silently failed because the standalone mcp-server container could not share in-memory consent/state stores with the BFF. Routing MCP traffic to the unified binary is the correct architectural fix per PRD-061. Changes are consistent across both demo and develop environments: Caddyfile routing, compose service consolidation, and env template cleanup all align.

Second commit (ce87b31b) addresses the orphaned MERIDIAN_API_KEY finding from the first review.

Risk Assessment

Area Level Detail
Blast radius Low MCP traffic only
Rollback Safe Revert PR and redeploy restores old mcp-server container
Scale Low MCP traffic is minimal
Cross-system Low Routing changes only
Migration N/A No database migrations

Findings

Severity Location Description Status
(none) No actionable findings remain

Previously Flagged

Severity Location Description Status
Improvement .env.develop.template Orphaned MERIDIAN_API_KEY env var Resolved in ce87b31b

Bot Review Notes

No unresolved bot threads. CodeRabbit approved on first commit; re-review of second commit in progress.

Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

See summary comment for full review. One non-blocking suggestion.

Comment thread deploy/develop/.env.develop.template Outdated
No longer consumed after mcp-server-develop container removal.
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Previous finding (orphaned MERIDIAN_API_KEY) resolved in ce87b31. No remaining concerns. See summary comment for full review.

@bjcoombs bjcoombs merged commit 98ba41a into develop Apr 8, 2026
19 checks passed
@bjcoombs bjcoombs deleted the fix-demo-mcp-routing branch April 8, 2026 14:40
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.

1 participant