Web Authentication
Web Authentication
The web MCP endpoint supports two authentication methods, tried in order.
Bearer Token (Recommended)
Authorization: Bearer <your-mcp-token>
Tokens are created in the CP at Tools > MCP > Tokens. Each token is:
- SHA-256 hashed at rest — the plaintext is shown once at creation
- Scoped — carries specific permissions (see Token Scopes)
- Tied to a user — audit logs show which user's token was used
- Optionally expiring — set an expiry date or leave as permanent
Expired tokens are rejected automatically. Revoked tokens are deleted from the database.
Basic Auth (Fallback)
Authorization: Basic <base64(email:password)>
Authenticates against Statamic's user system. The user must have the access cp permission. Basic Auth users get no scope restrictions — they can access all tools. Use Bearer tokens for production.
OAuth 2.1 (Browser-Based Clients)
For MCP clients that support the OAuth 2.1 specification, the addon provides a full authorization server with PKCE (S256).
Authorization Code Flow with PKCE
- Dynamic Client Registration: The client registers via
POST /mcp/oauth/register(RFC 7591), providing aclient_nameandredirect_uris. The server returns aclient_idandclient_secret. - Authorization Request: The client redirects to
GET /{cp}/mcp/oauth/authorizewithcode_challenge(S256) and requested scopes. - Consent Screen: The user sees the consent screen in the Statamic CP and approves or denies the request.
- Token Exchange: The client exchanges the authorization code at
POST /mcp/oauth/tokenwith thecode_verifier. - Refresh: The client can refresh tokens via
POST /mcp/oauth/tokenwithgrant_type=refresh_token.
Token Metadata Tracking
OAuth-created tokens store oauth_client_id and oauth_client_name for integration tracking. The CP dashboard shows an "OAuth" badge and hides the regenerate button for OAuth-created tokens.
Token Revocation
Clients can revoke tokens via POST /mcp/oauth/revoke (RFC 7009), supporting both access and refresh token revocation.
Discovery
OAuth metadata is available at:
/.well-known/oauth-authorization-server— RFC 8414 metadata/.well-known/oauth-protected-resource— RFC 9728 protected resource metadata
Configuration
OAuth is enabled by default. See the Configuration Reference for all OAuth settings including TTLs, default scopes, and max clients.
Authentication Flow
- Request arrives at the web endpoint
HandleMcpCorshandles CORS preflight and headers (ifallowed_originsconfigured)EnsureSecureTransportrejects plain HTTP in production (ifrequire_httpsenabled)AuthenticateForMcpmiddleware extracts theAuthorizationheader- If
Bearerprefix: validate token hash, check expiry, load scopes - If
Basicprefix: authenticate against Statamic users, verify CP access - If neither: return
401 Authentication required - Rate limiter applies per-token or per-IP throttling
RequireMcpPermissionmiddleware checks token scopes against the requested tool
Security Best Practices
HTTPS Enforcement
The web endpoint rejects plain HTTP requests by default in production and staging environments. This is controlled by the require_https config:
STATAMIC_MCP_WEB_REQUIRE_HTTPS=true # default — enforces HTTPS
STATAMIC_MCP_WEB_REQUIRE_HTTPS=false # disable if behind a TLS-terminating proxy that strips the header
Local and testing environments always allow HTTP regardless of this setting.
CORS (Browser-Based Clients)
Desktop MCP clients (Claude Desktop, Cursor, etc.) don't need CORS. If you're building a browser-based client, configure allowed origins:
// config/statamic/mcp.php
'web' => [
'allowed_origins' => ['https://your-app.com'],
// or ['*'] to allow all origins (not recommended for production)
],
When allowed_origins is empty (the default), no CORS headers are sent.
Production Checklist
- HTTPS is enforced by default — the middleware rejects HTTP in production
- Create dedicated tokens with minimal scopes per client
- Set token expiry for non-permanent integrations
- Enable audit logging (
STATAMIC_MCP_AUDIT_LOGGING=true, on by default) - Disable unused tool domains in
config/statamic/mcp.php - Rotate tokens periodically
- Review the Activity tab in the CP dashboard for unexpected usage
Rate Limiting
The endpoint applies rate limiting by default (60 requests per minute). Configure in .env:
STATAMIC_MCP_RATE_LIMIT_MAX=120
Force Web Mode
By default, CLI access bypasses authentication. To require tokens even in CLI context:
STATAMIC_MCP_FORCE_WEB_MODE=true
Maximum Token Lifetime
Set the maximum lifetime (in days) for tokens:
STATAMIC_MCP_MAX_TOKEN_LIFETIME=365
This is the upper bound — tokens cannot be created with an expiry beyond this limit. Leave unset or set to null for no maximum.