# How OpenSEO's MCP Server Handles OAuth vs. Self-Hosted Authentication in Request Dispatch

> Discover how OpenSEO's MCP server manages OAuth and self-hosted authentication in request dispatch. Learn about token validation and local admin context injection.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: internals
- Published: 2026-09-12

---

**OpenSEO's MCP server routes every request through [`src/server/mcp/transport.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/transport.ts), which validates OAuth bearer tokens for cloud clients while automatically injecting a local admin context for self-hosted deployments that lack an `Origin` header or present a local admin token.**

The OpenSEO repository implements a dual-mode authentication system in its Machine-Callable-Procedures (MCP) server to accommodate both public cloud deployments and private self-hosted instances. Understanding how OpenSEO's MCP server handles OAuth vs. self-hosted authentication in its request dispatch reveals a unified transport layer that applies strict OAuth scope validation for external clients while offering a streamlined, token-free path for local administrators.

## The Transport Layer Dispatch Architecture

All MCP requests enter through [`src/server/mcp/transport.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/transport.ts), which functions as the centralized authentication gateway. The transport first applies standard CORS headers via `MCP_CORS_HEADERS` to every response, then extracts authentication metadata from the incoming request. This layer remains agnostic to the deployment environment, delegating actual credential validation to specialized provider modules while maintaining responsibility for final scope enforcement.


## OAuth Authentication for Cloud-Hosted Clients

For production deployments and third-party integrations, the server enforces full OAuth 2.0 bearer token validation through a multi-step verification process.

### Bearer Token Extraction and Validation

Incoming requests bearing an `Authorization` header trigger the OAuth validation path in [`src/server/mcp/oauth-provider.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/oauth-provider.ts). This module decrypts the JWT—typically signed by Cloudflare Access or another configured issuer—and verifies the token's expiration, audience claims, and cryptographic signature. Upon successful validation, the provider constructs an authentication context object and attaches it to the request using the `MCP_AUTH_CONTEXT_PROP` property.

```typescript
// src/server/mcp/oauth-provider.ts – token resolution
export async function resolveOAuth(request: Request) {
  const authHeader = request.headers.get("Authorization");
  // Verify JWT, extract scopes, return { MCP_AUTH_CONTEXT_PROP: { scopes, ... } }
}

```

### Scope Verification and Enforcement

After OAuth validation, [`transport.ts`](https://github.com/every-app/open-seo/blob/main/transport.ts) inspects the resolved context to confirm the presence of `MCP_SCOPE`. At line 166, the transport checks `result.data[MCP_AUTH_CONTEXT_PROP].scopes.includes(MCP_SCOPE)`, returning a **403 Forbidden** response if the required scope is absent. This gate ensures that even valid OAuth tokens cannot access MCP resources without explicit authorization.

```typescript
// src/server/mcp/transport.ts – core auth check
if (!result.data[MCP_AUTH_CONTEXT_PROP].scopes.includes(MCP_SCOPE)) {
  return new Response("MCP scope required", { status: 403 });
}
const authContext = result.data[MCP_AUTH_CONTEXT_PROP];

```


## Self-Hosted Authentication Bypass

Self-hosted installations bypass the external OAuth flow through origin detection and pre-registered admin credentials, eliminating the need for external identity providers in local development environments.

### Local Admin Context Detection

The transport identifies self-hosted requests by detecting the absence of an `Origin` header or the presence of a special local admin token configured by the self-hosted runtime. In these cases, the server short-circuits the OAuth provider and immediately injects a local admin auth context that inherently contains the required MCP scope permissions.

### Admin Client Registration

The [`src/server/mcp/oauth-registration.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/oauth-registration.ts) module handles the registration of the "local admin" client during self-hosted startup. This registration pre-configures a client identity with full MCP scopes, enabling the transport to generate valid authentication contexts without network requests to external identity providers.

### Test Verification of No-Auth Flow

The self-hosted path is explicitly validated in [`src/server/mcp/transport.test.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/transport.test.ts) at lines 140-150. The test case **"accepts local no-auth MCP requests with the local admin context"** confirms that POST requests to `MCP_RESOURCE` succeed with a 200 status when the local admin context is active, demonstrating that the transport correctly bypasses OAuth validation for trusted local origins.

```typescript
// src/server/mcp/transport.test.ts – self‑hosted admin case
it("accepts local no-auth MCP requests with the local admin context", async () => {
  const resp = await fetch(MCP_RESOURCE, { method: "POST" });
  expect(resp.status).toBe(200);
});

```


## Summary

- [`src/server/mcp/transport.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/transport.ts) serves as the unified dispatch layer for all MCP requests, handling both OAuth and self-hosted authentication paths.
- Cloud deployments require valid bearer tokens verified by [`src/server/mcp/oauth-provider.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/oauth-provider.ts) and must include the `MCP_SCOPE` permission or receive a **403 Forbidden** response at line 166.
- Self-hosted instances bypass OAuth by detecting local origin headers or admin tokens, injecting a pre-authorized context via [`src/server/mcp/oauth-registration.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/oauth-registration.ts) without external network calls.
- The architecture maintains security through strict scope validation while offering flexibility for local development and internal deployments.


## Frequently Asked Questions

### How does the MCP server distinguish between OAuth and self-hosted requests?

The transport layer in [`src/server/mcp/transport.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/transport.ts) checks for the presence of an external `Origin` header or a configured local admin token. Requests lacking external origin indicators trigger the self-hosted path, which injects a local admin context instead of validating a bearer token against an external OAuth provider.

### What happens if an OAuth token lacks the required MCP scope?

The server returns a **403 Forbidden** response. At line 166 of [`transport.ts`](https://github.com/every-app/open-seo/blob/main/transport.ts), the code explicitly validates that `result.data[MCP_AUTH_CONTEXT_PROP].scopes.includes(MCP_SCOPE)` returns true; otherwise, it rejects the request with "MCP scope required" before reaching the MCP resource handler.

### Which file handles the local admin client registration for self-hosted instances?

[`src/server/mcp/oauth-registration.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/oauth-registration.ts) manages the registration of the local admin client. This module runs during self-hosted initialization to create a client identity with full MCP scopes, allowing the transport to generate valid authentication contexts without external OAuth round-trips.

### How is the authentication flow tested in the codebase?

The test suite in [`src/server/mcp/transport.test.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/transport.test.ts) includes specific coverage for both paths. Lines 140-150 contain the test "accepts local no-auth MCP requests with the local admin context", which verifies that self-hosted requests receive 200 OK responses without bearer tokens, while separate tests confirm that missing or insufficient OAuth scopes result in 403 errors.