Most MCP clients (Claude Code, Cursor, VS Code, Windsurf, Codex CLI, OpenCode, Claude Desktop) use API key authentication instead. OAuth is only needed for clients that initiate auth through a browser login flow.
How it works
OAuth 2.1 Authorization Code with PKCE follows this sequence:Discovery
Xquik publishes standard OAuth discovery documents so MCP clients can auto-configure endpoints.Authorization server metadata
Response
Protected resource metadata
Response
Complete flow
Register a client
Register your MCP client to get a Redirect URI requirements:
client_id. This is a one-time setup.Response
- Production: HTTPS only
- Development:
http://localhostandhttp://127.0.0.1are allowed - Exact match required — no wildcards or subpath matching
- Public (
token_endpoint_auth_method: "none"): Default. No client secret. Used by browser apps and MCP clients. - Confidential (
token_endpoint_auth_method: "client_secret_post"): Returns aclient_secretin the registration response. Used by server-side apps.
Generate PKCE parameters
Generate a cryptographically random
code_verifier and derive the code_challenge from it.Redirect to authorization
Redirect the user to the Xquik authorization endpoint with the required query parameters.Required parameters:
Optional parameters:
The user sees a login page (email magic link) followed by a consent screen. After approval, Xquik redirects back to your
| Parameter | Value |
|---|---|
response_type | code |
client_id | UUID from client registration |
redirect_uri | Must match a registered URI exactly |
code_challenge | SHA256 hex digest of the code_verifier |
code_challenge_method | S256 |
| Parameter | Default | Description |
|---|---|---|
scope | mcp:tools | Only mcp:tools is supported |
state | — | Opaque value for CSRF protection |
resource | https://xquik.com/mcp | Target resource identifier |
The
scope and resource parameters default to the only supported values (mcp:tools and https://xquik.com/mcp). You can omit them.redirect_uri.Receive the authorization code
After the user approves, Xquik redirects to your Verify the
redirect_uri with a code parameter:state parameter matches the value you sent in step 3 to prevent CSRF attacks. The authorization code expires in 60 seconds and is single-use.Exchange code for tokens
Exchange the authorization code and your
code_verifier for an access token and refresh token.Response
Token lifetimes
| Token | Lifetime | Notes |
|---|---|---|
| Access token | 1 hour | Use the refresh token to get a new one |
| Refresh token | 30 days | Single-use — each refresh issues a new pair |
| Authorization code | 60 seconds | Single-use — exchange immediately |
Refresh tokens
Access tokens expire after 1 hour. Use the refresh token to get a new access token without requiring the user to log in again.Response
Scopes
| Scope | Description |
|---|---|
mcp:tools | Full access to all 22 MCP tools (search tweets, manage monitors, run extractions, run draws, etc.) |
mcp:tools is supported. No partial scopes or scope combinations are available.
Client registration
Request
| Field | Type | Required | Description |
|---|---|---|---|
client_name | string | Yes | Display name shown on the consent screen |
redirect_uris | string[] | Yes | Allowed redirect URIs (1 or more) |
token_endpoint_auth_method | string | No | none (default) or client_secret_post |
grant_types | string[] | No | Defaults to ["authorization_code", "refresh_token"] |
Response
| Field | Type | Description |
|---|---|---|
client_id | string | UUID — use this in all subsequent OAuth requests |
client_name | string | Echoed from request |
redirect_uris | string[] | Echoed from request |
grant_types | string[] | Resolved grant types |
token_endpoint_auth_method | string | Resolved auth method |
client_secret | string | Only present for confidential clients (client_secret_post) |
Error responses
All errors follow the standard OAuth 2.0 error format:Authorization errors
| Error | When |
|---|---|
unsupported_response_type | response_type is not code |
invalid_request | Missing client_id, code_challenge, unknown client_id, or mismatched redirect_uri |
invalid_scope | Scope is not mcp:tools |
invalid_target | Resource is not https://xquik.com/mcp |
access_denied | User denied the authorization request |
Token errors
| Error | When |
|---|---|
invalid_request | Missing code, code_verifier, client_id, or refresh_token |
invalid_grant | Code/token is invalid, expired, or already used. Also: client_id mismatch, redirect_uri mismatch, or PKCE verification failed |
unsupported_grant_type | Grant type is not authorization_code or refresh_token |
invalid_target | Resource is not https://xquik.com/mcp |
Registration errors
| Error | When |
|---|---|
client_name is required | Missing or empty client_name |
redirect_uris must be a non-empty array of strings | Missing, empty, or malformed redirect_uris |
Invalid redirect URI: {uri}. Must be HTTPS or localhost. | URI is not HTTPS or localhost |
Invalid token_endpoint_auth_method | Value is not none or client_secret_post |
grant_types must be an array of strings | Malformed grant_types |
Full example
A complete Node.js implementation of the OAuth 2.1 flow:Node.js