Authentication
MCPlexer injects credentials into downstream server connections so you can manage access centrally. Auth scopes define what credentials to inject and how — environment variables for stdio servers or HTTP headers for remote ones.
Auth Scope Fields
| Name | Type | Default | Description |
|---|---|---|---|
id | string | — | Unique identifier |
name | string | — | Human-readable display name |
type | "env" | "header" | "oauth2" | — | Credential injection method |
encrypted_data | bytes | — | age-encrypted credential payload |
redaction_hints | string[] | — | Parameter names to redact in audit logs |
oauth_provider_id | string | — | Linked OAuth provider (oauth2 type only) |
oauth_token_data | bytes | — | Encrypted OAuth token storage (managed automatically) |
source | "yaml" | "api" | "seed" | — | How this scope was created |
Auth Scope Types
Environment Variables (env)
For stdio transport servers. MCPlexer injects key-value pairs as environment variables when spawning the downstream process.
auth_scopes:
- name: "GitHub Token"
type: env
# Secret values set via CLI or UI — never in YAMLAfter creating the scope, set the secret:
When the GitHub MCP server starts, it receives GITHUB_PERSONAL_ACCESS_TOKEN=ghp_xxxxxxxxxxxx in its environment.
HTTP Headers (header)
For http transport servers. MCPlexer adds headers to every request forwarded to the downstream server.
auth_scopes:
- name: "API Key"
type: headerOAuth2 (oauth2)
For servers that need OAuth2 tokens. MCPlexer handles the full authorization flow including PKCE, token storage, and automatic refresh.
OAuth2 + PKCE Flow
MCPlexer implements the OAuth2 Authorization Code flow with PKCE (Proof Key for Code Exchange) for secure token acquisition:
- Initiate — via the web UI or API, MCPlexer generates a PKCE challenge and redirects the user to the provider's authorization page
- Authorize — the user grants access in the provider's UI
- Callback — the provider redirects back to MCPlexer with an authorization code
- Exchange — MCPlexer exchanges the code + PKCE verifier for access and refresh tokens
- Store — tokens are encrypted with age and stored in the database
- Inject — on each tool call, MCPlexer injects the access token (as env var or header, depending on the downstream transport)
Automatic Token Refresh
When an access token expires, MCPlexer automatically uses the refresh token to obtain a new one. This happens transparently — no user interaction required. If the refresh token itself expires, the user is prompted to re-authorize.
Provider Templates
MCPlexer ships with built-in OAuth provider templates for popular services. These pre-configure the authorization URL, token URL, and default scopes:
| Provider | Auth URL | Default Scopes |
|---|---|---|
| GitHub | github.com/login/oauth | repo, read:org |
| GitLab | gitlab.com/oauth | api, read_user |
| accounts.google.com/o/oauth2 | openid, email | |
| Notion | api.notion.com/v1/oauth | — |
| Linear | linear.app/oauth | read, write |
| ClickUp | app.clickup.com/api | — |
| Microsoft | login.microsoftonline.com | User.Read |
Quick Setup
When using a built-in provider template, you only need to supply your client ID and client secret. MCPlexer fills in the authorization URLs, token endpoints, and default scopes automatically.
Quick Setup
- Navigate to Config > Auth Scopes in the web UI
- Click Add Auth Scope and select type OAuth2
- Choose a provider template (e.g., GitHub)
- Enter your OAuth app's Client ID and Client Secret
- Click Authorize — you'll be redirected to the provider
- Grant access and you'll be redirected back to MCPlexer
- Link the auth scope to a route rule via
auth_scope_id
Manual Configuration
For providers not in the template list, configure the OAuth provider manually:
oauth_providers:
- name: "Custom Provider"
auth_url: "https://auth.example.com/authorize"
token_url: "https://auth.example.com/token"
scopes: ["read", "write"]Then create an auth scope linked to this provider:
auth_scopes:
- name: "Custom OAuth"
type: oauth2
oauth_provider_id: custom-providerCredential Injection
How credentials reach the downstream server depends on the transport:
| Transport | env type | header type | oauth2 type |
|---|---|---|---|
| stdio | Env vars on process | N/A | Token as env var |
| http | N/A | HTTP headers | Authorization: Bearer header |
Transport compatibility
The env type only works with stdio servers (credentials are process environment variables). The header type only works with HTTP servers. OAuth2 adapts to the transport automatically.
Redaction Hints
Auth scopes support redaction_hints — a list of parameter names that should be scrubbed from audit logs. This prevents sensitive data from appearing in logs even when full request/response logging is enabled.
auth_scopes:
- name: "GitHub Token"
type: env
redaction_hints: ["GITHUB_PERSONAL_ACCESS_TOKEN", "password", "secret"]When audit logging encounters these parameter names in tool call arguments or responses, their values are replaced with [REDACTED].
Linking Auth Scopes to Routes
Auth scopes are connected to downstream servers through route rules. Set the auth_scope_id on a route rule to specify which credentials to inject when that rule matches:
route_rules:
- name: "GitHub with personal token"
workspace_id: default
tool_match: ["github__*"]
downstream_server_id: github
auth_scope_id: github-personal-token
policy: allowThis means different workspaces or route rules can use different credentials for the same downstream server — for example, a personal token for development and an org token for production.