Skip to content

feat(api): declare oauth2 security scheme for MCP per-user auth#2961

Merged
tofikwest merged 1 commit into
mainfrom
feat/openapi-oauth2-mcp
May 29, 2026
Merged

feat(api): declare oauth2 security scheme for MCP per-user auth#2961
tofikwest merged 1 commit into
mainfrom
feat/openapi-oauth2-mcp

Conversation

@tofikwest
Copy link
Copy Markdown
Contributor

@tofikwest tofikwest commented May 29, 2026

Why

This unblocks keyless, per-user auth for the hosted MCP (Speakeasy Gram).

I traced Gram's source: it picks the credential it sends to our backend from the spec's security scheme. With only the X-API-Key scheme, Gram would call our API with one shared key for every MCP user — bypassing the per-user/per-org RBAC the API already enforces. Gram also only shows the customer-facing OAuth wizard when the spec advertises an oauth2 scheme (oauth2SecurityCount > 0); until then it offers only "Gram OAuth" (internal Gram-org members).

What

  • Adds an oauth2 (authorization code) security scheme pointed at the better-auth MCP authorization server (/api/auth/mcp/authorize + /token).
  • Offers it alongside the API key on every authenticated operation (OR semantics — either credential satisfies a request, so existing API-key integrations and the SDK are unaffected).
  • Centralized in applyPublicOpenApiMetadata so all three spec-generation paths (main.ts, gen-openapi.spec.ts, openapi-docs.spec.ts) stay consistent.
  • Regenerated the committed openapi.jsonverified byte-identical to a real GEN_OPENAPI=1 run (935 insertions, 0 deletions; 306/306 API-key ops now also offer oauth2).

How it fits the rollout

Once merged, the existing gram-sync CI pushes the updated spec → oauth2SecurityCount flips above 0 → the External/Proxy OAuth wizard unlocks in Gram. Next steps (Gram-side): set the MCP server Public, run the OAuth wizard pointed at better-auth, set the staging GRAM_OAUTH_* env vars.

Tests

  • New openapi-docs.spec.ts cases: asserts the oauth2 scheme exists with the right endpoints, every API-key op also offers oauth2, and oauth2 is never on a non-API-key (public) op.
  • Full openapi-docs.spec.ts green (5/5).

Heads-up

Speakeasy SDK generation consumes this spec; it'll see the new oauth2 scheme (additive). The authorization-code flow is for interactive/MCP clients — existing API-key SDK usage is unchanged.

🤖 Generated with Claude Code


Summary by cubic

Enables per-user OAuth for hosted MCP (Speakeasy Gram) by declaring an oauth2 authorization-code security scheme in the public OpenAPI spec, alongside the existing API key. This unlocks Gram’s OAuth wizard and keeps current API-key integrations working.

  • New Features
    • Added oauth2 authorization code scheme pointing to /api/auth/mcp/authorize and /api/auth/mcp/token.
    • Offered oauth2 on all API-key–gated operations (OR semantics: API key or OAuth token).
    • Centralized in applyPublicOpenApiMetadata to keep all spec-generation paths consistent.
    • Regenerated packages/docs/openapi.json.

Written for commit e906b6d. Summary will update on new commits.

Review in cubic

Hosted MCP (Speakeasy Gram) only surfaces a customer-facing 'Sign in with Comp AI' flow and forwards each user's bearer token to the API when the OpenAPI spec declares an oauth2 scheme. With only the X-API-Key scheme, Gram would call the API with one shared key for every user, bypassing the per-user/per-org RBAC the API already enforces.

Adds an oauth2 (authorization code) scheme pointed at the better-auth MCP authorization server and offers it alongside the API key on every authenticated operation (OR semantics — either credential satisfies a request, so existing API-key integrations are unaffected). Centralized in applyPublicOpenApiMetadata so all three spec-generation paths stay consistent; committed openapi.json regenerated (verified byte-identical to a GEN_OPENAPI=1 run). Once synced to Gram, oauth2SecurityCount>0 unlocks the External/Proxy OAuth wizard.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel vercel Bot temporarily deployed to Preview – portal May 29, 2026 01:44 Inactive
@vercel
Copy link
Copy Markdown

vercel Bot commented May 29, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
comp-framework-editor Ready Ready Preview, Comment May 29, 2026 1:45am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
app Skipped Skipped May 29, 2026 1:45am
portal Skipped Skipped May 29, 2026 1:45am

Request Review

@vercel vercel Bot temporarily deployed to Preview – app May 29, 2026 01:44 Inactive
@mintlify
Copy link
Copy Markdown
Contributor

mintlify Bot commented May 29, 2026

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
CompAI 🟢 Ready View Preview May 29, 2026, 1:45 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 3 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@tofikwest tofikwest merged commit 2bd0de6 into main May 29, 2026
13 checks passed
@tofikwest tofikwest deleted the feat/openapi-oauth2-mcp branch May 29, 2026 01:48
@claudfuen
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 3.66.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants