How OpenSEO Routes MCP Requests Across Authentication Modes
OpenSEO uses a single /mcp endpoint that branches into three distinct authentication flows—Hosted OAuth, Cloudflare Access self-hosted, and local no-auth—to validate requests before converging on a shared MCP server handler.
OpenSEO implements a centralized MCP (Model Context Protocol) routing system in the every-app/open-seo repository that handles diverse authentication requirements through unified entry points. The architecture delegates credential validation to mode-specific handlers in src/server/mcp/transport.ts before funneling all requests through a common processing pipeline that ensures consistent tool execution regardless of deployment context.
The Three Authentication Entry Points
The routing logic in src/server/mcp/transport.ts exposes two primary functions that handle three distinct authentication scenarios. Each path validates credentials differently but ultimately produces a standardized ToolAuthContext for downstream processing.
Hosted OAuth Mode
The hosted flow begins at handleAuthenticatedOpenSeoMcpRequest, designed for multi-tenant SaaS deployments using OAuth 2.0 authentication.
The request must carry a valid OAuth token parsed by hostedWorkersOAuthMcpPropsSchema, which enforces the presence of the MCP scope (MCP_SCOPE). The system then verifies the token's user-organization membership via AuthRepository.getMembership (defined in src/server/auth/repositories/AuthRepository.ts) to confirm the user still belongs to the claimed organization.
After validation, the handler builds a ToolAuthContext and passes it to createWorkersOAuthMcpProps. The request then flows to createRequestHandler, which instantiates createOpenSeoMcpServer and processes the call.
// Hosted (OAuth) – called from the OAuth provider
await handleAuthenticatedOpenSeoMcpRequest(
request, // incoming HTTP request
props, // OAuth-derived props (contains MCP auth context)
env, // Cloudflare environment
ctx // Execution context
);
Self-Hosted Cloudflare Access
For enterprises using Cloudflare Access, the handleSelfHostedOpenSeoMcpRequest function accepts an authMode parameter set to cloudflare_access.
This path resolves identity through resolveCloudflareAccessContext (implemented in src/middleware/ensure-user/cloudflareAccess.ts) without requiring OAuth tokens. The function examines the request for Cloudflare-issued identity headers, extracting the user ID, email, and organization ID.
The resolved identity wraps into createWorkersOAuthMcpProps and proceeds to createRequestHandler, utilizing the same MCP server implementation as the hosted mode but bypassing OAuth-client specific checks.
// Self-hosted – Cloudflare Access
await handleSelfHostedOpenSeoMcpRequest(
request,
"cloudflare_access", // auth mode
env,
ctx
);
Local No-Auth Development Mode
Development and on-premise deployments use the same handleSelfHostedOpenSeoMcpRequest entry point with authMode set to local_noauth.
The resolveLocalNoAuthContext function (located in src/middleware/ensure-user/delegated.ts) generates a synthetic admin-level identity, enabling unrestricted access for local development. This fake identity feeds into createWorkersOAuthMcpProps and follows the identical routing path to createRequestHandler as the Cloudflare Access mode.
// Self-hosted – Local no-auth (development)
await handleSelfHostedOpenSeoMcpRequest(
request,
"local_noauth",
env,
ctx
);
Request Validation and Context Creation
All authentication paths converge on a standardized validation and context-building phase defined in src/server/mcp/context.ts.
Token Verification and Membership Checks
The hosted mode performs the most rigorous validation. After schema validation via hostedWorkersOAuthMcpPropsSchema, the system queries AuthRepository.getMembership to verify the user-organization relationship remains active. This prevents revoked or transferred users from accessing organizational MCP resources.
Self-hosted modes skip membership database lookups, instead trusting Cloudflare Access headers or the local development identity.
Building the ToolAuthContext
The createMcpToolContext function transforms validated McpProps into a ToolAuthContext containing:
userIdorganizationIdroleorgScope- Granted scopes list
This context attaches to every MCP tool invocation, ensuring authorization decisions have access to identity and permission metadata regardless of which authentication mode initiated the request.
Unified Processing Pipeline
After authentication-specific handling, all requests flow through shared middleware and processing logic defined in src/server/mcp/transport.ts.
CORS and Legacy Request Handling
Every response passes through withMcpCors, which injects fixed CORS headers (MCP_CORS_HEADERS) to support cross-origin browser requests.
The system then performs legacy detection via isLegacyRequest. Legacy JSON-RPC calls route to handleLegacyJsonRequest, while modern MCP protocol requests dispatch through createMcpHandler from the Agents SDK. This dual-path support ensures backward compatibility while enabling new MCP features.
MCP Server Initialization
The final routing stage calls createRequestHandler, which initializes createOpenSeoMcpServer. This centralized server definition ensures consistent tool availability and behavior across all authentication modes, preventing drift between hosted and self-hosted deployments.
Summary
- Single endpoint architecture: OpenSEO exposes one
/mcproute handled byhandleAuthenticatedOpenSeoMcpRequest(hosted) orhandleSelfHostedOpenSeoMcpRequest(self-hosted) insrc/server/mcp/transport.ts. - Three authentication modes: Hosted OAuth validates tokens against
AuthRepositorymembership; Cloudflare Access resolves identity from Cloudflare headers viasrc/middleware/ensure-user/cloudflareAccess.ts; local no-auth generates synthetic admin identities viasrc/middleware/ensure-user/delegated.ts. - Convergent processing: All modes use
createWorkersOAuthMcpPropsto build a standardizedToolAuthContextbefore passing control tocreateRequestHandlerand the shared MCP server. - Shared infrastructure: CORS handling via
withMcpCors, legacy request support throughisLegacyRequest, and tool context creation viacreateMcpToolContextremain consistent across all authentication paths.
Frequently Asked Questions
How does OpenSEO verify organization membership in hosted mode?
In hosted OAuth mode, after validating the token schema and MCP scope, OpenSEO calls AuthRepository.getMembership to confirm the user ID extracted from the token still belongs to the claimed organization. This prevents access from users who have been removed from an organization but possess old tokens.
Can self-hosted instances use the same MCP tools as the hosted version?
Yes. Both self-hosted modes (Cloudflare Access and local no-auth) ultimately call createRequestHandler, which instantiates the same createOpenSeoMcpServer used by the hosted flow. This ensures feature parity and prevents tool implementation fragmentation between deployment models.
What security headers does OpenSEO apply to MCP responses?
All MCP responses pass through withMcpCors, which attaches MCP_CORS_HEADERS to enable cross-origin requests from browser-based MCP clients. This handling applies uniformly across all three authentication modes.
Where does the local no-auth mode generate its identity?
The resolveLocalNoAuthContext function in src/middleware/ensure-user/delegated.ts, called within handleSelfHostedOpenSeoMcpRequest when authMode equals local_noauth, generates a synthetic admin-level identity. This bypasses external authentication services and is restricted to development or trusted on-premise environments.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →