Skip to content

Add MCP setup guidance and OAuth flow#30

Merged
andrewzolotukhin merged 3 commits into
mainfrom
feat/mcp-oauth-setup-instructions
Jun 6, 2026
Merged

Add MCP setup guidance and OAuth flow#30
andrewzolotukhin merged 3 commits into
mainfrom
feat/mcp-oauth-setup-instructions

Conversation

@andrewzolotukhin

@andrewzolotukhin andrewzolotukhin commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Original request

Add user-facing instructions for the existing MCP server: how to use it, what URL to configure, how to install/connect it in popular clients, and include MCP OAuth support for compatible clients.

Summary

This adds in-app MCP setup instructions and an OAuth approval flow for MCP clients.

What changed

  • Added MCP setup guidance to Settings > Preferences in the API keys card, including the live MCP URL, Claude/Codex/Cursor instructions, copyable Codex TOML, copyable Cursor JSON, API-key bearer fallback, and active MCP OAuth connection revocation.
  • Added MCP OAuth support for public clients with dynamic client registration, authorization-code + PKCE approval, refresh-token rotation, OAuth discovery metadata, protected-resource metadata, and token exchange endpoints.
  • Added an MCP consent page at /mcp/oauth/authorize and preserved callback redirects through password, Google, and Passport login flows.
  • Updated the MCP endpoint to accept either existing xpenser API keys or MCP OAuth bearer tokens, and to return a WWW-Authenticate challenge with protected-resource metadata for unauthenticated clients.
  • Added database tables for OAuth clients, grants, authorization codes, and refresh tokens.
  • Added user APIs for listing/revoking MCP OAuth connections and contract schemas/endpoints for the OAuth consent flow.
  • Updated web proxy/rewrite handling so /.well-known/* and /external-api/oauth/* resolve to the API endpoints.
  • Updated MCP tool logging to distinguish API-key and MCP OAuth credentials.
  • Added focused unit tests for MCP OAuth, endpoint discovery/challenge behavior, MCP auth principal detection, and the settings UI instructions; updated the authenticated e2e flow assertion for the MCP settings copy.

Reasoning

The settings UI now gives users the exact copy/paste configuration they need without requiring documentation outside the app. OAuth was added alongside API-key fallback so clients such as Claude and Codex can connect through a user approval flow, while existing scripts and clients that only support custom headers can still use xpenser API keys. The implementation follows the existing contract-first API structure, Next.js server-action patterns, and existing MCP endpoint/tool boundaries.

Validation

  • npm run lint
  • npm run typecheck
  • npm test (60 files, 341 tests)
  • GitHub Lint and test
  • GitHub Deploy PR environment
  • GitHub Playwright e2e
  • Preview QA: signed in to https://xpenser-pr-030.cleverbrush.com, opened Settings > Preferences, verified the MCP server section, preview MCP URL, Claude/Codex/Cursor instructions, Codex TOML, Cursor JSON, API-key bearer fallback, and empty MCP OAuth connections state.
  • Preview protocol QA: verified /.well-known/oauth-authorization-server, /.well-known/oauth-protected-resource/external-api/mcp, unauthenticated /external-api/mcp WWW-Authenticate challenge, dynamic client registration, and /mcp/oauth/authorize consent screen for a registered client.
  • SigNoz: attempted traces/logs/metrics verification for xpenser-web-pr-30 / xpenser-api-pr-30 and broader pr-30 / pr-030 service-name searches. SigNoz returned no PR Add MCP setup guidance and OAuth flow #30 service telemetry and direct lookup of fresh preview trace IDs 09481c086dbe462bcec5b954399eb135 and 9ed15c7eff4cf52396e253eeff19b72d returned no spans after an ingestion wait. This appears to be a PR-environment telemetry gap outside the application change; not marked as passed.

Screenshots / Preview

  • Preview URL: https://xpenser-pr-030.cleverbrush.com
  • MCP settings page screenshot captured locally at /tmp/xpenser-pr-030-mcp-settings.png.
  • Agent-browser text snapshot confirmed the rendered MCP URL and setup snippets, including:
    • https://xpenser-pr-030.cleverbrush.com/external-api/mcp
    • [mcp_servers.xpenser]
    • Cursor "type": "streamable-http"
    • "Authorization": "Bearer ${XPENSER_API_KEY}"

Checklist

  • I kept the change focused.
  • I updated docs or tests where needed.
  • I checked for secrets, local env files, and generated build output.
  • API changes keep contracts, endpoint metadata, and handlers aligned.

@andrewzolotukhin andrewzolotukhin temporarily deployed to pr-30 June 6, 2026 06:34 — with GitHub Actions Inactive
@andrewzolotukhin andrewzolotukhin temporarily deployed to pr-30 June 6, 2026 06:43 — with GitHub Actions Inactive
@andrewzolotukhin andrewzolotukhin temporarily deployed to pr-30 June 6, 2026 06:59 — with GitHub Actions Inactive
@andrewzolotukhin

Copy link
Copy Markdown
Contributor Author

Addressed the schema review comment in bb82fa9: the MCP OAuth string-array validation now uses Cleverbrush array(string()) instead of the manual isStringArray guard. Local npm run lint, npm run typecheck, and npm test pass, and GitHub Lint and test, deploy, and Playwright e2e are green on the updated commit.

@andrewzolotukhin andrewzolotukhin merged commit 6d6bd1a into main Jun 6, 2026
4 checks passed
@andrewzolotukhin andrewzolotukhin deleted the feat/mcp-oauth-setup-instructions branch June 6, 2026 07:09
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