Add org-scoped MCP routes for the cloud app#878
Merged
Conversation
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
executor-marketing | 1b638a4 | Commit Preview URL Branch Preview URL |
Jun 01 2026, 07:45 AM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
executor-cloud | 1b638a4 | Jun 01 2026, 07:46 AM |
@executor-js/cli
@executor-js/config
@executor-js/execution
@executor-js/sdk
@executor-js/codemode-core
@executor-js/runtime-quickjs
@executor-js/plugin-file-secrets
@executor-js/plugin-graphql
@executor-js/plugin-keychain
@executor-js/plugin-mcp
@executor-js/plugin-onepassword
@executor-js/plugin-openapi
executor
commit: |
Let an MCP client pin a specific organization in the URL (`/<org_id>/mcp`) instead of relying on the organization claim in the OAuth access token. This unblocks clients that hold a single sign-in session but need to target one of several organizations. Server: - Serve `/<org_id>/mcp` and the matching `/.well-known/oauth-protected-resource/<org_id>/mcp` discovery document alongside the existing bare `/mcp`. - Take the organization from the URL when present, falling back to the token claim otherwise. Membership is verified against the auth provider on every request, so the URL is a selector, not a trust boundary. - Consolidate MCP path ownership behind one predicate shared by the request middleware, the handler, and the test worker. Only `org_`-shaped segments are claimed, so unrelated `/<segment>/mcp` paths still fall through to routing. Frontend: - The cloud "Connect your MCP client" page and the install card now hand out the org-scoped URL. The shared install card stays unscoped for local/desktop, where there is no organization. Tests cover org-scoped discovery metadata, URL-supplied organization, membership denial before session creation, non-org paths falling through, and org-scoped URL/command rendering. Draft: interim org-id form; migrates to organization handles once URL-based org routing lands.
90b3538 to
1b638a4
Compare
RhysSullivan
pushed a commit
that referenced
this pull request
Jun 1, 2026
Resolves the conflict with #878 (org-scoped MCP routes), which added URL-pinned org selection to the monolithic apps/cloud/src/mcp.ts this branch had already split into the shared @executor-js/host-mcp envelope + cloud seams. The feature is preserved, re-implemented cloud-only on the new architecture (the shared envelope stays org-agnostic so self-host/CF are untouched): - mcp/mount.ts: classifyMcpPath is now org-aware (recognizes /org_xxx/mcp and the org-scoped protected-resource doc; only org_-shaped segments claimed) and a new prepareMcpOrgScope rewrites an org-scoped path to the bare path the envelope routes, carrying the URL-pinned org in an internal header. - mcp/auth.ts: MCP_ORGANIZATION_HEADER + reader, org-scoped resource/metadata URL builders, org-aware bearerChallengeFor. - mcp/auth-provider.ts: resourceMetadataUrl, the discovery doc, finishAuthorized, and the 401 challenge all take the org from the header (falling back to the token claim); membership is still re-checked per request, so the URL is a selector, not a trust boundary. - start.ts + testing/test-worker.ts: apply prepareMcpOrgScope at the dispatch boundary; old mcp.ts deleted. Verified: typecheck 38/38, lint clean, mcp-flow 22/22 (incl. the org-scoped routing + membership-denial cases), cloud node MCP 24/24, reachability 4/4, react mcp-install-card 11/11.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Let an MCP client pin a specific organization in the URL (
/<org_id>/mcp)instead of relying on the organization claim in the OAuth access token. This
unblocks clients that hold a single sign-in session but need to target one of
several organizations.
Server:
/<org_id>/mcpand the matching/.well-known/oauth-protected-resource/<org_id>/mcpdiscovery documentalongside the existing bare
/mcp.claim otherwise. Membership is verified against the auth provider on every
request, so the URL is a selector, not a trust boundary.
middleware, the handler, and the test worker. Only
org_-shaped segments areclaimed, so unrelated
/<segment>/mcppaths still fall through to routing.Frontend:
org-scoped URL. The shared install card stays unscoped for local/desktop,
where there is no organization.
Tests cover org-scoped discovery metadata, URL-supplied organization, membership
denial before session creation, non-org paths falling through, and org-scoped
URL/command rendering.
Draft: interim org-id form; migrates to organization handles once URL-based org
routing lands.