Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

feat(mcp): discovery-based OAuth, credential vault, and recorder onboarding without a terminal

merged#2623CedarCopilot

CedarCopilot wants to merge 12 commits into staging from feat/mcp-oauth-foundation

Live on prod, no production signal yetTimeline and evidence
  1. Opened
    Aug 29, 2026, 6:08 PM
  2. Aug 30, 2026, 2:00 PM
  3. Merged
    Aug 30, 2026, 3:21 PM
  4. Live on staging
    Aug 30, 2026, 3:21 PM
  5. Live on prod
    Aug 30, 2026, 3:21 PM
  6. Observed 3 hours
    Aug 30, 2026, 3:21 PM
  7. Pipelines steady after this deploy
    Aug 30, 2026, 3:21 PM
  8. Pipelines steady after this deploy
    Aug 30, 2026, 3:21 PM
  9. Unobserved

    Live on prod, no production signal yet

    Aug 30, 2026, 6:22 PM

Behaviors Libra is checking

Authentication and access behavior from mcp/oauth-discovery.ts, mcp/oauth-driver.ts, mcp/oauth-state.ts keeps working in prod.Inconclusivelow confidence

Strict CloudWatch fallback saw 131 success-shaped log lines matching auth, login, session, token, but no tied operation was present, so Libra is not calling this working.

prod, checked Aug 30, 2026, 4:08 PM
Chat workflow behavior from agents/chat-agent.ts, chat/chat-org-rules.ts, harness/user-mcp-servers.ts keeps working in prod.Inconclusivelow confidence

OTEL fallback saw 4,691 prod spans for the repo/env since deploy, but 144 were errors and the intent has no concrete surface to attribute them to.

prod, checked Aug 30, 2026, 5:08 PM
CRM integration behavior from tools/readConnectionSettingsTool.ts keeps working in prod.Inconclusivelow confidence

Strict CloudWatch fallback saw 247 success-shaped log lines matching crm, hubspot, salesforce, deal, deals, but no tied operation was present, so Libra is not calling this working.

prod, checked Aug 30, 2026, 5:21 PM
Email workflow behavior from onboarding/page.tsx, components/IntegrationsTabContent.tsx, connections/page.tsx keeps working in prod.Inconclusivelow confidence

Strict CloudWatch fallback saw 3,196 success-shaped log lines matching email, emails, gmail, mail, inbox, but no tied operation was present, so Libra is not calling this working.

prod, checked Aug 30, 2026, 5:21 PM
Meeting import behavior from providers/fireflies.ts keeps working in prod.Inconclusivelow confidence

Strict CloudWatch fallback found 12 recent prod failure log lines for [SCHEDULED] Failed to enrich unenriched calendar event (Failed query: insert into \), but the same failure had 9 log lines in the comparable pre-deploy baseline. Libra is not blaming this PR intent without a.

prod, checked Aug 30, 2026, 6:22 PM
Authentication and access behavior from mcp/oauth-discovery.ts, mcp/oauth-driver.ts, mcp/oauth-state.ts keeps working in staging.Inconclusivelow confidence

Strict CloudWatch fallback found 54 prod failure log lines for [processIncomingSlackChannelData] Error processing channel (No valid connection tokens found for user <id>), but this domain-wide failure family is not tied to this intent.

staging, checked Sep 2, 2026, 5:42 AM

Failures attributed to this change

No prod customers are affected while this is only in staging. If promoted, prod impact is unknown because Libra still needs a concrete exception, route, and failed user action before assigning severity. 0 hits · no retained affected-user count · no retained trace sample.Introducedmedium confidence

internal_only

staging, first seen Aug 30, 2026, 3:31 PM
No prod customers are affected while this is only in staging. If promoted, prod impact is unknown because Libra still needs a concrete exception, route, and failed user action before assigning severity. 0 hits · no retained affected-user count · no retained trace sample.Introducedmedium confidence

internal_only

staging, first seen Aug 30, 2026, 7:36 PM
No prod customers are affected while this is only in staging. If promoted, prod impact is unknown because Libra still needs a concrete exception, route, and failed user action before assigning severity. 0 hits · no retained affected-user count · no retained trace sample.Introducedmedium confidence

internal_only

staging, first seen Aug 30, 2026, 10:51 PM
No prod customers are affected while this is only in staging. If promoted, prod impact is unknown because Libra still needs a concrete exception, route, and failed user action before assigning severity. 0 hits · no retained affected-user count · no retained trace sample.Introducedmedium confidence

internal_only

staging, first seen Aug 31, 2026, 1:06 AM
No prod customers are affected while this is only in staging. If promoted, prod impact is unknown because Libra still needs a concrete exception, route, and failed user action before assigning severity. 1 hit · no retained affected-user count · no retained trace sample.Introducedmedium confidence

internal_only

staging, first seen Aug 31, 2026, 6:36 AM
No prod customers are affected while this is only in staging. If promoted, prod impact is unknown because Libra still needs a concrete exception, route, and failed user action before assigning severity. 1 hit · no retained affected-user count · no retained trace sample.Introducedmedium confidence

internal_only

staging, first seen Aug 31, 2026, 6:51 AM
No prod customers are affected while this is only in staging. If promoted, prod impact is unknown because Libra still needs a concrete exception, route, and failed user action before assigning severity. 0 hits · no retained affected-user count · no retained trace sample.Introducedmedium confidence

internal_only

staging, first seen Aug 31, 2026, 10:11 AM
No prod customers are affected while this is only in staging. If promoted, prod impact is unknown because Libra still needs a concrete exception, route, and failed user action before assigning severity. 12 hits · no retained affected-user count · no retained trace sample.Introducedmedium confidence

internal_only

staging, first seen Aug 31, 2026, 2:21 PM
No prod customers are affected while this is only in staging. If promoted, prod impact is unknown because Libra still needs a concrete exception, route, and failed user action before assigning severity. 18 hits · no retained affected-user count · no retained trace sample.Introducedmedium confidence

internal_only

staging, first seen Aug 31, 2026, 2:21 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.

Connecting an MCP server now needs a name and a URL instead of a code change, and a server a user pastes works with no provider entry at all. Adds a credential vault for systems that have no MCP, and moves three meeting recorders off hand-extracted CLI tokens.

Why discovery instead of per-provider config

The OAuth endpoints cannot be derived from an MCP URL. Caretta's MCP is on gateway.caretta.app while its authorization server is a Supabase project on supabase.co; Gong's MCP is on mcp.gong.io while registration is on app.gong.io. Every server checked puts at least one endpoint on a host you would not predict, so they have to be discovered: RFC 9728 protected-resource metadata, then RFC 8414 authorization-server metadata, then RFC 7591 dynamic client registration.

Verified against twelve live servers, including three deviations the chain has to absorb:

  • Xero's WWW-Authenticate carries no resource_metadata, so the well-known path must be constructed.
  • Krisp serves protected-resource metadata at the bare well-known path, not the path-suffixed one.
  • Caretta's authorization server answers only on RFC 8414's path-insertion form.

providers/dcr-pkce-driver.ts is deleted. Notion, Pylon and Mintlify move onto discovery, keeping pinned narrow scopes: Mintlify's resource advertises write, deploy and billing scopes that a docs integration must not request.

What a user sees

ProviderBeforeAfter
Carettanpx mcp-remote, a python3 glob over ~/.mcp-auth/**, paste 3 valuesone button
Circlebacknpm i -g @circleback/cli, cb login, cat tokens.json, paste 4 valuesone button
Krispnpx mcp-remote, two cats, paste 4 values incl. a client secretone button

Existing pasted credentials keep working. One connection row holds both shapes and the MCP token set wins when present, so nobody has to reconnect on deploy.

Bugs found on the way

  • createConnection would have inserted a second row when a provider with an existing api_key connection connected over MCP: the conflict target is (userId, providerId, externalId) and the callback keyed on the server URL. Two rows break credential lookup and double-process the backfill cron.
  • mcp-token-refresh's expiryUnchanged guard compiled to NULL IS NOT DISTINCT FROM NULL whenever a provider omits expires_in, so concurrent writers both landed and could persist an already-rotated refresh token. That is also the connection shape with the worst concurrency, since nothing refreshes proactively and every process 401s at the same instant.
  • updateMcpConnection rebuilt metadata from three inputs and full-replaced the column. Harmless while providerId: 'mcp' meant static-header only; this change puts OAuth rows under that id, so it would have wiped their refresh tokens.

Security fixes from review

Four of the five review commits are security. Each is pinned by a test confirmed to fail without its fix.

  • The OAuth state was unauthenticated. userId sat outside the AES-GCM sealed blob while the callback route, which has no auth middleware, trusted it to decide whose account to install a connection on. An attacker could run a real connect in their own account, obtain a genuine code and sealed blob, rewrite userId, and replay the callback. Encryption is not integrity, and the previous shape conflated them: it looked authenticated without being so, which is worse than the plainly-unauthenticated base64 it replaced.
  • Discovery trusted a server-controlled authorization server. No RFC 9728 check that the returned resource matched the one requested, so a hostile server could name Notion's real AS, and the resulting Notion bearer would be shipped to the attacker's host on every call.
  • The SSRF guard covered only the entry URL, not the issuer, registration and token URLs discovery then fetches from a document the server controls.
  • **The vault's tokenUrl was validated by `z.string().url()
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/docs/agent-workspace.mdno production surface mapped
  • apps/mail/jest.config.cjsno production surface mapped
  • apps/mail/modules/integrations/__tests__/meeting-integration-card-oauth.test.tsxno production surface mapped
  • apps/mail/modules/integrations/mcp-integration-card.tsxno production surface mapped
  • apps/mail/modules/integrations/meeting-integration-card.tsxno production surface mapped
  • apps/mail/modules/integrations/oauth-mcp-integration-card.tsxno production surface mapped
  • apps/mail/modules/integrations/systems/__tests__/add-mcp-step.test.tsxno production surface mapped
  • apps/mail/modules/integrations/systems/add-mcp-step.tsxno production surface mapped
  • apps/mail/modules/integrations/systems/add-system-dialog.tsxno production surface mapped
  • apps/mail/modules/integrations/systems/credential-form.tsxno production surface mapped
  • apps/mail/modules/integrations/systems/scope-select.tsxno production surface mapped
  • apps/mail/modules/integrations/systems/system-row.tsxno production surface mapped
  • apps/mail/modules/integrations/systems/systems-and-credentials-section.tsxno production surface mapped
  • apps/mail/modules/integrations/systems/types.tsno production surface mapped
  • apps/server/.claude/skills/external-systems/SKILL.mdno production surface mapped
  • apps/server/docs/customer-feedback-loop.mdno production surface mapped
  • apps/server/docs/design/mcp-tool-allowlist.mdno production surface mapped
  • apps/server/scripts/circleback-mcp-probe.tsno production surface mapped
  • apps/server/src/env.tsno production surface mapped
  • apps/server/src/http/app.tsno production surface mapped
  • apps/server/src/mastra/agents/automation-agent.tsno production surface mapped
  • apps/server/src/mastra/agents/chat-agent.tsno production surface mapped
  • apps/server/src/mastra/skills/__tests__/external-systems.test.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/skills/kb/__tests__/kb-mcp-connections.test.tsno production surface mapped
  • apps/server/src/mastra/skills/kb/kb-management.tsno production surface mapped
  • apps/server/src/mastra/tools/config/__tests__/configTool.test.tsno production surface mapped
  • apps/server/src/mastra/tools/config/config-read-tool.tsno production surface mapped
  • apps/server/src/mastra/tools/integrations/__tests__/callMcpTool.background-gate.test.tsno production surface mapped
  • apps/server/src/mastra/tools/integrations/__tests__/provider-credentials-vault.test.tsno production surface mapped
  • apps/server/src/mastra/tools/integrations/callMcpTool.tsno production surface mapped
  • apps/server/src/mastra/tools/integrations/getProviderCredentialsTool.tsno production surface mapped
  • apps/server/src/mastra/tools/subagent-tool-allowlists.tsno production surface mapped
  • apps/server/src/mastra/tools/tool-names.tsno production surface mapped
  • apps/server/src/mastra/utils/credential-surface.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/__tests__/mcp-connection-external-id.test.tsno production surface mapped
  • apps/server/src/services/integrations/connections.tsno production surface mapped
  • apps/server/src/services/integrations/constants.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/__tests__/fake-db.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/__tests__/refresh.test.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/__tests__/resolve.test.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/__tests__/response-body-disclosure.test.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/__tests__/token-refresh.test.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/__tests__/token-url-guard.test.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/__tests__/unified.test.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/__tests__/vault.test.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/compiled-providers.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/index.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/provider-id.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/refresh.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/resolve.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/token-refresh.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/token-url-guard.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/types.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/unified.tsno production surface mapped
  • apps/server/src/services/integrations/credentials/vault.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/__tests__/callability.test.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/__tests__/mcp-backfill.test.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/__tests__/mcp-token-refresh.test.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/__tests__/oauth-discovery.test.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/__tests__/oauth-drivers.test.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/__tests__/oauth-state.test.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/callability.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/index.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/mcp-backfill.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/mcp-token-refresh.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/oauth-discovery.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/oauth-driver.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/oauth-state.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/provider-ids.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/providers/caretta.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/providers/circleback.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/providers/clari.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/discovered-driver.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/providers/fireflies.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/providers/gong.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/providers/granola.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/providers/krisp.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/services/integrations/mcp/server-url.tsno production surface mapped
  • apps/server/src/services/integrations/mcp/types.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/__tests__/caretta-mcp.test.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/__tests__/circleback-mcp.test.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/__tests__/circleback-search.test.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/__tests__/krisp-mcp.test.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/caretta.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/circleback-search.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/circleback.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/driver.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/index.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/krisp.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/provider-ids.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/recorder-mcp-access.tsno production surface mapped
  • apps/server/src/services/integrations/provider-credentials.tsno production surface mapped
  • apps/server/src/trpc/index.tsno production surface mapped
  • apps/server/src/trpc/routes/__tests__/credential-vault-org-admin.test.tsno production surface mapped
  • apps/server/src/trpc/routes/__tests__/integrations-mcp-delete.test.tsno production surface mapped
  • apps/server/src/trpc/routes/__tests__/integrations-mcp-org-scope.test.tsno production surface mapped
  • apps/server/src/trpc/routes/credential-vault.tsno production surface mapped
  • apps/server/src/trpc/routes/integrations.tsno production surface mapped
  • apps/server/src/trpc/routes/org-admin.tsno production surface mapped
  • aws/lib/runtime-contract.tsno production surface mapped
  • docs/design/mcp-oauth-pylon-mintlify.mdno production surface mapped