@phake/mcp supports five authentication strategies. Set AUTH_STRATEGY in your environment to pick one explicitly, or let the server infer it automatically from whichever variables are present.
Automatic inference
If you do not setAUTH_STRATEGY, the server inspects your environment and picks the best match:
| Condition | Strategy selected |
|---|---|
AUTH_ENABLED=true | oauth |
API_KEY is set | api_key |
BEARER_TOKEN is set | bearer |
| None of the above | none |
AUTH_STRATEGY explicitly when you want deterministic behaviour regardless of which other variables happen to be set.
Strategy reference
oauth — Full OAuth 2.1 PKCE flow
oauth — Full OAuth 2.1 PKCE flow
When to use it
Useoauth when you want end-users to authenticate with a third-party provider (Google, GitHub, etc.) through a full browser-based OAuth 2.1 PKCE flow. The server issues its own RS (Resource Server) tokens and maps them to provider access tokens stored in KV.Required environment variables
| Variable | Description |
|---|---|
OAUTH_CLIENT_ID | Your MCP server’s OAuth client ID |
OAUTH_CLIENT_SECRET | Your MCP server’s OAuth client secret |
OAUTH_SCOPES | Space-separated scopes (e.g., openid profile email) |
OAUTH_REDIRECT_URI | Redirect URI registered with your provider |
OAUTH_AUTHORIZATION_URL | Provider authorization endpoint |
OAUTH_TOKEN_URL | Provider token endpoint |
PROVIDER_CLIENT_ID | Upstream provider client ID |
PROVIDER_CLIENT_SECRET | Upstream provider client secret |
PROVIDER_ACCOUNTS_URL | Provider user-info / accounts endpoint |
TOKENS | Cloudflare KV binding for token storage |
RS_TOKENS_ENC_KEY | AES-256-GCM encryption key for tokens at rest |
Tool context
WhenAUTH_STRATEGY=oauth, successful authentication populates the tool context with:context.providerToken— the mapped provider access token (e.g., Google access token)context.resolvedHeaders— pre-built headers withAuthorization: Bearer <providerToken>context.provider— provider info object (accessToken,refreshToken,expiresAt)context.authStrategy—"oauth"
Example tool
Example environment setup
.dev.vars
bearer — Static bearer token
bearer — Static bearer token
When to use it
Usebearer for server-to-server integrations where a single long-lived token authenticates all requests. There is no user login flow — the token is read from BEARER_TOKEN and injected into every tool call.Required environment variables
| Variable | Description |
|---|---|
BEARER_TOKEN | The static bearer token value |
Tool context
context.providerToken— the value ofBEARER_TOKENcontext.resolvedHeaders—{ Authorization: "Bearer <BEARER_TOKEN>" }context.authStrategy—"bearer"
Example tool
Example environment setup
api_key — Static API key header
api_key — Static API key header
When to use it
Useapi_key when the upstream service authenticates via a custom header (e.g., x-api-key) rather than a standard Authorization header. The key is read from API_KEY and injected under the header named by API_KEY_HEADER.Required environment variables
| Variable | Description | Default |
|---|---|---|
API_KEY | The static API key value | — |
API_KEY_HEADER | Header name to send the key in | x-api-key |
Tool context
context.providerToken— the value ofAPI_KEYcontext.resolvedHeaders—{ "<API_KEY_HEADER>": "<API_KEY>" }context.authStrategy—"api_key"
Example tool
Example environment setup
custom — Arbitrary request headers
custom — Arbitrary request headers
When to use it
Usecustom when the upstream service requires multiple non-standard headers (e.g., workspace IDs, tenant identifiers, or proprietary auth schemes). All headers are defined in a single CUSTOM_HEADERS variable and injected verbatim into every tool call.Required environment variables
| Variable | Description |
|---|---|
CUSTOM_HEADERS | Comma-separated Header-Name:value pairs |
Header-Name:value,Another-Header:value2Tool context
context.providerToken—undefined(no single token concept)context.resolvedHeaders— all parsed custom headers as a plain objectcontext.authStrategy—"custom"
Example tool
Example environment setup
none — No authentication
none — No authentication
When to use it
Usenone for public tools that do not call authenticated APIs, or during local development before you configure a real auth strategy. All tools remain accessible without any token.Required environment variables
None.Tool context
context.providerToken—undefinedcontext.resolvedHeaders—{}(empty)context.authStrategy—"none"
Example tool
Example environment setup
You can omit
AUTH_STRATEGY entirely and leave API_KEY and BEARER_TOKEN unset — the server defaults to none automatically.Summary table
| Strategy | Set AUTH_STRATEGY to | Required variables | context.providerToken | context.resolvedHeaders |
|---|---|---|---|---|
oauth | oauth | OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, OAUTH_SCOPES, OAUTH_REDIRECT_URI, OAUTH_AUTHORIZATION_URL, OAUTH_TOKEN_URL, PROVIDER_CLIENT_ID, PROVIDER_CLIENT_SECRET, PROVIDER_ACCOUNTS_URL | Mapped provider token | Authorization: Bearer <token> |
bearer | bearer | BEARER_TOKEN | Value of BEARER_TOKEN | Authorization: Bearer <BEARER_TOKEN> |
api_key | api_key | API_KEY | Value of API_KEY | <API_KEY_HEADER>: <API_KEY> |
custom | custom | CUSTOM_HEADERS | undefined | All parsed custom headers |
none | none | — | undefined | {} |
Using assertProviderToken
When a tool requires a token to function, use the assertProviderToken helper instead of writing a manual if check. It throws an "Authentication required" error if context.providerToken is absent, and narrows the TypeScript type to string for the rest of the handler.
requiresAuth: true and assertProviderToken serve different purposes. requiresAuth causes the dispatcher to reject unauthenticated requests before the handler is called. assertProviderToken is a type guard inside the handler that makes TypeScript aware the token is guaranteed to be a string.requiresAuth: true is the recommended way to protect a tool. Use assertProviderToken in addition when you need the narrowed TypeScript type, or in tools that call helper functions that expect a string rather than string | undefined.