Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

feat(integrations): add Pylon + Mintlify OAuth MCP providers

merged#2499CedarCopilot

CedarCopilot wants to merge 0 commits into staging from feat/mcp-oauth-pylon-mintlify

Live on prod, no production signal yetTimeline and evidence
  1. Opened
    Aug 15, 2026, 2:57 PM
  2. Merged
    Aug 15, 2026, 5:03 PM
  3. Live on staging
    Aug 15, 2026, 5:03 PM
  4. Live on prod
    Aug 15, 2026, 5:03 PM
  5. Observed 2 days
    Aug 15, 2026, 5:03 PM
  6. Pipelines steady after this deploy
    Aug 15, 2026, 5:03 PM
  7. Pipelines steady after this deploy
    Aug 15, 2026, 5:03 PM
  8. Unobserved

    Live on prod, no production signal yet

    Aug 18, 2026, 4:10 PM

Behaviors Libra is checking

The native chat harness refreshes OAuth MCP credentials before building a per-turn MCP server configuration, preventing expired Pylon, Mintlify, or Notion tokens from failing the turn.Inconclusivelow confidence

OTEL fallback found no prod spans matching buildUserMcpServers since deploy.

prod, checked Aug 18, 2026, 3:57 PM
All registered MCP provider connections, including Pylon and Mintlify, are discoverable by chat rules, external-system context, account connection settings, direct MCP calls, and the native chat harness.Inconclusivelow confidence

OTEL fallback found no prod spans matching buildUserMcpServers; callMcpTool; buildConnectionRulesBlock; loadMcpIntegrations since deploy.

prod, checked Aug 18, 2026, 3:57 PM
Users can connect Mintlify through OAuth and let Cedar agents search connected product documentation through Mintlify MCP tools.Inconclusivelow confidence

OTEL fallback found no prod spans matching integrations.initiateOAuth (integration=mintlify); GET /oauth/mintlify/callback; Mintlify MCP server since deploy.

prod, checked Aug 18, 2026, 4:10 PM
Settings, onboarding, and the playground now show branded Connect, Reconnect, and Disconnect controls for Notion, Pylon, and Mintlify OAuth MCP providers.Inconclusivelow confidence

OTEL fallback found no prod spans matching Settings Connections MCP tab; onboarding context-source step; playground Integrations MCP tab since deploy.

prod, checked Aug 18, 2026, 4:10 PM
Account-configuration reads recognize Pylon and Mintlify as MCP connections and return their server URLs and MCP metadata alongside existing MCP providers.Inconclusivehigh confidence

Since 2026-08-16T00:03:13Z, staging produced 0 OTEL spans matching read-connection-settings/readConnectionSettingsTool and 0 Pylon or Mintlify connection-provider spans. CloudWatch found only one concrete tool-surface log (2026-08-18 17:23:52Z: cedar-configuration skill loaded.

staging, checked Aug 18, 2026, 4:11 PM
The native chat-agent harness refreshes near-expired OAuth MCP credentials before constructing its per-turn server connection, preventing expired Pylon, Mintlify, and Notion tokens from causing avoidable authorization failures.Inconclusivelow confidence

OTEL fallback found no prod spans matching buildUserMcpServers since deploy.

staging, checked Aug 18, 2026, 4:12 PM

Libra has verdicts on 0 of 5 tracked behaviors on prod; 5 are still being checked. Libra checks hourly for 3 days after each deploy.

What & why

Registers two new OAuth-authenticated external MCP servers so Cedar's agent can call their tools:

  • Pylon , https://mcp.usepylon.com/
  • Mintlify , https://mcp.mintlify.com

Both authenticate exactly like the existing Notion MCP driver: Dynamic Client Registration (DCR) + PKCE, public client, no pre-registered secret. Verified from each vendor's /.well-known/oauth-authorization-server.

Approach

  • Extract a driver factory. createDcrPkceMcpDriver(config) captures the full DCR → PKCE(S256) → code-exchange → refresh-grant pattern. notion.ts refactors onto it (142→13 lines); pylon.ts / mintlify.ts are ~10-line configs with endpoints + scopes.
  • Unify the provider-id allowlist. The ['mcp','notion'] literal was hardcoded in 6 places that decide which connections the agent can use , a missed site silently makes a connection dead. All now reference MCP_PROVIDER_IDS, so future providers are one line in constants.ts.
  • Generalize the frontend card. The bespoke 146-line Notion card becomes a config-driven OAuthMcpIntegrationCard + cluster, rendered in settings / playground / onboarding.
  • Env vars PYLON_REDIRECT_URI / MINTLIFY_REDIRECT_URI; proper display names; fixed the hardcoded NOTION_REDIRECT_URI error string.

Design doc: docs/design/mcp-oauth-pylon-mintlify.md.

One behavior change to a live path

The factory registers grant_types: [authorization_code, refresh_token] for all providers; Notion previously registered only authorization_code. Only new Notion connects re-register. Verified live: a DCR POST to https://mcp.notion.com/register with the new body returns 201 and echoes both grant types. It's also strictly more correct , Notion already uses the refresh grant it didn't previously register for.

Testing

  • vitest oauth-drivers.test.ts , 11/11 (DCR body, S256 authorize URL + scope, code exchange, refresh grant, invalid_grant permanent-vs-transient, registry resolution).
  • Live registration: DCR POST to all three real vendor register endpoints → 201 + client_id with correct scopes. Proves endpoints/body/scopes short of a human clicking "Allow".
  • @zero/server + @zero/mail types clean on touched files; pnpm deps:check clean.

Deploy step (required before it works): set on the server env ,

PYLON_REDIRECT_URI=https://<api-host>/oauth/pylon/callback
MINTLIFY_REDIRECT_URI=https://<api-host>/oauth/mintlify/callback

Under DCR the redirect URI is submitted at registration time, so there is no vendor-side app registration. Pylon requires a Member/Admin seat to authorize.

Risk notes (from Libra pre-commit check)

  1. Connections-route overlap with a known prod "Unexpected end of JSON input" failure. This PR's only change to that path is widening the listMcpConnections WHERE providerId IN (...) filter , it adds no new response parsing/serialization. Worth a glance before deploy but not a new parse surface.
  2. No route-level integration test for the connect/callback flow, token persistence, reconnect, or actual MCP invocation for Pylon/Mintlify , driver-level coverage only. The full round-trip is unverifiable without a real browser login (see deploy step); tier-3 manual validation is the gate.

Open question

Mintlify scope is docs:read offline_access (read-only docs). Widen in mintlify.ts if the agent should also deploy/edit docs or read analytics.

🤖 Generated with Claude Code

Greptile Summary

The PR adds DCR-and-PKCE OAuth support for Pylon and Mintlify, extracts the shared OAuth driver used by Notion, and exposes all three providers throughout connection management and agent MCP loading.

  • Adds provider drivers, redirect-URI environment settings, registration tests, and a shared provider allowlist.
  • Replaces the Notion-specific frontend card with a configuration-driven OAuth MCP card cluster.
  • Expands agent and connec
Show production surfaces and changed-file mapping

Production surfaces

Libra has not measured any production surfaces for this change yet.

Changed files → surfaces

  • apps/mail/app/(full-width)/onboarding/page.tsxno production surface mapped
  • apps/mail/app/(routes)/playground/components/IntegrationsTabContent.tsxno production surface mapped
  • apps/mail/app/(routes)/settings/connections/page.tsxno production surface mapped
  • apps/mail/modules/integrations/oauth-mcp-integration-card.tsxno production surface mapped
  • apps/server/src/env.tsno production surface mapped
  • apps/server/src/mastra/skills/account-config/tools/readConnectionSettingsTool.tsno production surface mapped
  • apps/server/src/mastra/skills/integrations/external-systems.tsno production surface mapped
  • apps/server/src/mastra/tools/integrations/callMcpTool.tsno production surface mapped
  • apps/server/src/mastra/workflows/chat/chat-org-rules.tsno production surface mapped
  • apps/server/src/mastra/workflows/chat/harness/__tests__/user-mcp-servers.test.tsno production surface mapped
  • apps/server/src/mastra/workflows/chat/harness/user-mcp-servers.tsno production surface mapped
  • apps/server/src/services/integrations/constants.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/__tests__/oauth-drivers.test.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/index.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/provider-ids.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/providers/dcr-pkce-driver.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/providers/mintlify.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/providers/notion.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/providers/pylon.tsno production surface mapped
  • apps/server/src/trpc/routes/integrations.tsno production surface mapped
  • docs/design/mcp-oauth-pylon-mintlify.mdno production surface mapped