Skip to content

fix(mcp,google-discovery): persist pending OAuth sessions via binding store - #221

Merged
RhysSullivan merged 2 commits into
mainfrom
fix/mcp-oauth-session-persistence
Apr 13, 2026
Merged

fix(mcp,google-discovery): persist pending OAuth sessions via binding store#221
RhysSullivan merged 2 commits into
mainfrom
fix/mcp-oauth-session-persistence

Conversation

@RhysSullivan

Copy link
Copy Markdown
Collaborator

Summary

  • MCP and Google Discovery plugins kept pending OAuth sessions in an in-process Map on the plugin closure. In cloud, createOrgExecutor runs per-request on Cloudflare Workers (apps/cloud/src/api/protected.ts:43), so the OAuth provider's redirect-back request built a fresh plugin instance with an empty Map and completeOAuth failed with OAuth session not found: mcp_oauth_<uuid>.
  • Persist pending sessions through the existing KV-backed binding stores under a new ${namespace}.oauth-sessions scoped namespace.
  • Sessions carry an expiresAt (15 min TTL) and are filtered + cleaned up on read. In-memory binding stores get a third in-memory KV so apps/local and tests behave the same.

Notes

  • codeVerifier and (for MCP) dynamically-registered client info now land in plain KV alongside the existing bindings/sources data — same trust level as what's already there. The actual access/refresh tokens still go through ctx.secrets → WorkOS Vault unchanged.
  • TTL is hard-coded to 15 minutes, exported as MCP_OAUTH_SESSION_TTL_MS / GOOGLE_DISCOVERY_OAUTH_SESSION_TTL_MS if we want to tune it later.

Test plan

  • bunx vitest run in packages/plugins/mcp — 19/19 pass
  • bunx vitest run in packages/plugins/google-discovery — 6/6 pass
  • bun --filter=@executor/plugin-mcp typecheck
  • bun --filter=@executor/plugin-google-discovery typecheck
  • Manual: start MCP OAuth in cloud, complete the redirect flow, confirm completeOAuth succeeds and stores tokens

… store

The mcp and google-discovery plugins kept pending OAuth sessions in an
in-process Map on the plugin closure. In cloud, createOrgExecutor runs
per-request on Cloudflare Workers, so the redirect-back request built a
fresh plugin with an empty Map and completeOAuth failed with
"OAuth session not found".

Persist sessions through the existing KV-backed binding stores under a
new ${namespace}.oauth-sessions scoped namespace, with a 15-minute TTL
enforced via an expiresAt field filtered on read.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Apr 13, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
executor-marketing 7e49e4c Commit Preview URL

Branch Preview URL
Apr 13 2026, 06:50 AM

@pkg-pr-new

pkg-pr-new Bot commented Apr 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

@executor/sdk

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/sdk@221

@executor/plugin-file-secrets

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/plugin-file-secrets@221

@executor/plugin-google-discovery

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/plugin-google-discovery@221

@executor/plugin-graphql

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/plugin-graphql@221

@executor/plugin-keychain

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/plugin-keychain@221

@executor/plugin-mcp

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/plugin-mcp@221

@executor/plugin-onepassword

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/plugin-onepassword@221

@executor/plugin-openapi

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/plugin-openapi@221

@executor/plugin-workos-vault

npm i https://pkg.pr.new/RhysSullivan/executor/@executor/plugin-workos-vault@221

commit: 7e49e4c

Promote McpOAuthSession and GoogleDiscoveryOAuthSession from plain TS
interfaces to Schema.Struct definitions, and swap JSON.parse/stringify
with Schema.parseJson in both binding stores so corrupt or
schema-drifted KV entries surface a parse error instead of silently
flowing through as unchecked any. Matches the StoredBindingEntry
pattern already used in the same files.
@RhysSullivan
RhysSullivan merged commit 3efffbb into main Apr 13, 2026
7 checks passed
RhysSullivan added a commit that referenced this pull request May 31, 2026
… store (#221)

* fix(mcp,google-discovery): persist pending OAuth sessions via binding store

The mcp and google-discovery plugins kept pending OAuth sessions in an
in-process Map on the plugin closure. In cloud, createOrgExecutor runs
per-request on Cloudflare Workers, so the redirect-back request built a
fresh plugin with an empty Map and completeOAuth failed with
"OAuth session not found".

Persist sessions through the existing KV-backed binding stores under a
new ${namespace}.oauth-sessions scoped namespace, with a 15-minute TTL
enforced via an expiresAt field filtered on read.

* refactor(mcp,google-discovery): schema-encode persisted OAuth sessions

Promote McpOAuthSession and GoogleDiscoveryOAuthSession from plain TS
interfaces to Schema.Struct definitions, and swap JSON.parse/stringify
with Schema.parseJson in both binding stores so corrupt or
schema-drifted KV entries surface a parse error instead of silently
flowing through as unchecked any. Matches the StoredBindingEntry
pattern already used in the same files.
@RhysSullivan
RhysSullivan deleted the fix/mcp-oauth-session-persistence branch June 11, 2026 08:01
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