Authentication
MXCP supports OAuth authentication to protect your endpoints and tools. When authentication is enabled, all tools, resources, prompts, and built-in SQL features require valid authentication tokens.
Overview
Authentication is configured in your user configuration file (~/.mxcp/config.yml
) under each profile's auth
section. MXCP supports multiple OAuth providers and can be easily extended to support additional providers.
How It Works
When authentication is enabled:
- Server Startup: The MXCP server initializes with OAuth support
- Client Registration: MCP clients can register with the OAuth server
- Authorization Flow: Clients are redirected to the OAuth provider for authentication
- Token Exchange: Provider auth codes are exchanged for access tokens
- Protected Access: All endpoints require valid tokens
Protected Features
When authentication is enabled, the following features require authentication:
- Custom Endpoints: All tools, resources, and prompts defined in your YAML files
- SQL Tools: Built-in DuckDB querying and schema exploration tools
User Information Logging
When OAuth authentication is enabled, MXCP automatically logs detailed user information for each authenticated request, including:
- Username and user ID
- OAuth provider (e.g., GitHub, Atlassian)
- User's display name and email (when available)
This information appears in the server logs whenever an authenticated user executes any tool, resource, or prompt.
Supported Providers
Currently supported providers:
none
(default, no authentication)github
(GitHub OAuth)atlassian
(Atlassian Cloud - JIRA & Confluence)salesforce
(Salesforce Cloud)keycloak
(Keycloak - Open Source Identity and Access Management)google
(Google OAuth - Google Workspace APIs)
Provider Configuration
Disable Authentication (Default)
By default, authentication is disabled:
projects:
my_project:
profiles:
dev:
auth:
provider: none
GitHub OAuth
Creating a GitHub OAuth App
-
Create a GitHub OAuth App:
- Go to GitHub Settings > Developer settings > OAuth Apps
- Click "New OAuth App"
- Set the Authorization callback URL to:
http://localhost:8000/github/callback
(adjust host/port as needed)
-
Get Your Credentials:
- Copy your Client ID and Client Secret
- Store these securely as environment variables
Environment Variables
Set these environment variables with your GitHub OAuth credentials:
export GITHUB_CLIENT_ID="your_github_client_id"
export GITHUB_CLIENT_SECRET="your_github_client_secret"
MXCP Configuration
Configure GitHub OAuth in your profile's auth section:
projects:
my_project:
profiles:
dev:
auth:
provider: github
clients:
- client_id: "${GITHUB_CLIENT_ID}"
client_secret: "${GITHUB_CLIENT_SECRET}"
name: "My MXCP Application"
redirect_uris:
- "http://localhost:8000/github/callback"
scopes:
- "mxcp:access"
github:
client_id: "${GITHUB_CLIENT_ID}"
client_secret: "${GITHUB_CLIENT_SECRET}"
scope: "user:email"
callback_path: "/github/callback"
auth_url: "https://github.com/login/oauth/authorize"
token_url: "https://github.com/login/oauth/access_token"
Configuration Options
client_id
: Your GitHub OAuth app client IDclient_secret
: Your GitHub OAuth app client secretscope
: OAuth scope to request (default: "user:email")callback_path
: Callback path for OAuth flow (default: "/github/callback")auth_url
: GitHub authorization URLtoken_url
: GitHub token exchange URL
Testing Your Configuration
-
Start your MXCP server:
mxcp serve --debug
-
The authentication flow will begin when a client connects
-
Users will be redirected to GitHub for authorization
-
After approval, they'll be redirected back to your callback URL
-
Check the logs for successful authentication
Troubleshooting
Common Issues:
-
Invalid Client Configuration:
ValueError: GitHub OAuth configuration is incomplete
- Ensure all required GitHub configuration fields are provided
-
Environment Variables Not Set:
ValueError: Environment variable GITHUB_CLIENT_ID is not set
- Set the required environment variables before starting the server
-
Callback URL Mismatch:
HTTPException: Invalid state parameter
- Ensure the callback URL in your GitHub OAuth app matches the configured callback_path
Atlassian OAuth (JIRA & Confluence Cloud)
MXCP supports OAuth authentication with Atlassian Cloud products including JIRA and Confluence. This allows your MCP server to authenticate users and access Atlassian APIs on their behalf.
Creating an Atlassian OAuth App
Before configuring MXCP, you need to create an OAuth 2.0 (3LO) app in the Atlassian Developer Console:
Step 1: Access the Developer Console
- Go to developer.atlassian.com
- Sign in with your Atlassian account
- Click your profile icon in the top-right corner
- Select Developer console from the dropdown
Step 2: Create a New App
- Click Create and select OAuth 2.0 (3LO)
- Enter your app details:
- App name: A descriptive name for your application
- Description: Brief description of what your app does
Step 3: Configure OAuth 2.0
- In your app, select Authorization from the left menu
- Next to OAuth 2.0 (3LO), click Configure
- Set the Callback URL to match your MXCP server:
- For local development:
http://localhost:8000/atlassian/callback
- For production:
https://your-domain.com/atlassian/callback
- For local development:
- Click Save changes
Step 4: Add API Permissions
- Select Permissions from the left menu
- Add the APIs you need:
- Jira platform REST API - for JIRA access
- Confluence Cloud REST API - for Confluence access
- User Identity API - for user profile information
- For each API, click Add and configure the required scopes.
Step 5: Get Your Credentials
- Go to Settings in the left menu
- Copy your Client ID and Secret
- Store these securely as environment variables
Environment Variables
Set these environment variables with your Atlassian OAuth credentials:
export ATLASSIAN_CLIENT_ID="your_client_id_here"
export ATLASSIAN_CLIENT_SECRET="your_client_secret_here"
MXCP Configuration
Configure Atlassian OAuth in your profile's auth section:
projects:
my_project:
profiles:
production:
auth:
provider: atlassian
clients:
- client_id: "${ATLASSIAN_CLIENT_ID}"
client_secret: "${ATLASSIAN_CLIENT_SECRET}"
name: "My MXCP Application"
redirect_uris:
- "https://your-domain.com/atlassian/callback"
scopes:
- "mxcp:access"
atlassian:
client_id: "${ATLASSIAN_CLIENT_ID}"
client_secret: "${ATLASSIAN_CLIENT_SECRET}"
scope: "read:me read:jira-work read:jira-user read:confluence-content.all read:confluence-user offline_access"
callback_path: "/atlassian/callback"
auth_url: "https://auth.atlassian.com/authorize"
token_url: "https://auth.atlassian.com/oauth/token"
OAuth Scopes
Atlassian uses granular scopes to control access. Common scopes include:
JIRA Scopes:
read:jira-work
- Read issues, projects, and work itemswrite:jira-work
- Create and update issuesread:jira-user
- Read user informationmanage:jira-project
- Manage projects (admin level)manage:jira-configuration
- Manage JIRA configuration (admin level)
Confluence Scopes:
read:confluence-content.all
- Read all Confluence contentwrite:confluence-content
- Create and update contentread:confluence-user
- Read user informationmanage:confluence-configuration
- Manage Confluence settings (admin level)
Universal Scopes:
read:me
- Read user profile informationoffline_access
- Enable refresh tokens for long-term access
Accessing Multiple Sites
Atlassian OAuth grants access to all sites where your app is installed. To work with specific sites:
-
Get accessible resources:
curl -H "Authorization: Bearer ACCESS_TOKEN" \
https://api.atlassian.com/oauth/token/accessible-resources -
Use the cloud ID in API requests:
# JIRA API example
curl -H "Authorization: Bearer ACCESS_TOKEN" \
https://api.atlassian.com/ex/jira/{cloudid}/rest/api/2/project
# Confluence API example
curl -H "Authorization: Bearer ACCESS_TOKEN" \
https://api.atlassian.com/ex/confluence/{cloudid}/rest/api/space
Testing Your Configuration
-
Start your MXCP server:
mxcp serve --debug
-
The authentication flow will begin when a client connects
-
Users will be redirected to Atlassian for authorization
-
After approval, they'll be redirected back to your callback URL
-
Check the logs for successful authentication
Troubleshooting
Common Issues:
-
Invalid Client Configuration:
ValueError: Atlassian OAuth configuration is incomplete
- Ensure
client_id
andclient_secret
are provided - Check that environment variables are set correctly
- Ensure
-
Callback URL Mismatch:
HTTPException: Invalid state parameter
- Verify the callback URL in your Atlassian app matches your MXCP configuration
- Ensure the URL scheme (http/https) is correct
-
Insufficient Permissions:
403 Forbidden
- Check that your app has the required API permissions in the Developer Console
- Verify the user has access to the requested resources
-
Site Access Issues:
No accessible resources found
- Ensure your app is installed on the Atlassian site
- Check that the user has granted access to your app
Debug Tips:
- Enable debug logging:
mxcp serve --debug
- Check the Atlassian Developer Console for app installation status
- Verify OAuth scopes match your API requirements
- Test with a simple scope like
read:me
first
Security Best Practices
- Store credentials securely: Use environment variables, not config files
- Use HTTPS: Required for production OAuth flows
- Minimal scopes: Request only the permissions you need
- Token management: Implement proper token refresh logic
- Site validation: Verify users have access to required Atlassian sites
Salesforce OAuth (Salesforce Cloud)
MXCP supports OAuth authentication with Salesforce Cloud. This allows your MCP server to authenticate users and access Salesforce APIs on their behalf, enabling powerful integrations with CRM data, custom objects, and Salesforce automation.
Creating a Salesforce Connected App
Before configuring MXCP, you need to create a Connected App in your Salesforce org:
Step 1: Access Setup
- Log in to your Salesforce org
- Click the Setup gear icon in the top-right corner
- In the Quick Find box, search for "App Manager"
- Click App Manager under Apps
Step 2: Create a Connected App
- Click New Connected App
- Fill in the basic information:
- Connected App Name: A descriptive name for your application
- API Name: Will be auto-generated from the name
- Contact Email: Your email address
Step 3: Enable OAuth Settings
- Check Enable OAuth Settings
- Set the Callback URL to match your MXCP server:
- For local development:
http://localhost:8000/salesforce/callback
- For production:
https://your-domain.com/salesforce/callback
- For local development:
- Select OAuth Scopes (move from Available to Selected):
- Access the identity URL service (openid)
- Access your basic information (profile)
- Access and manage your data (api)
- Access your contact information (email)
- Perform requests on your behalf at any time (refresh_token, offline_access)
- Click Save
Step 4: Configure Security Settings
- After saving, click Continue
- In the API section, note down your Consumer Key and Consumer Secret
- Configure additional security settings as needed:
- IP Restrictions: Set to "Relax IP restrictions" for development
- Permitted Users: Set to "All users may self-authorize" or restrict as needed
Step 5: Deploy the Connected App
- Go back to Setup > App Manager
- Find your Connected App and click the dropdown arrow
- Select Edit Policies
- Set Permitted Users as appropriate for your use case
- Click Save
Environment Variables
Set these environment variables with your Salesforce Connected App credentials:
export SALESFORCE_CLIENT_ID="your_consumer_key_here"
export SALESFORCE_CLIENT_SECRET="your_consumer_secret_here"
MXCP Configuration
Configure Salesforce OAuth in your profile's auth section:
projects:
my_project:
profiles:
production:
auth:
provider: salesforce
clients:
- client_id: "${SALESFORCE_CLIENT_ID}"
client_secret: "${SALESFORCE_CLIENT_SECRET}"
name: "My MXCP Application"
redirect_uris:
- "https://your-domain.com/salesforce/callback"
scopes:
- "mxcp:access"
salesforce:
client_id: "${SALESFORCE_CLIENT_ID}"
client_secret: "${SALESFORCE_CLIENT_SECRET}"
scope: "api refresh_token openid profile email"
callback_path: "/salesforce/callback"
auth_url: "https://login.salesforce.com/services/oauth2/authorize"
token_url: "https://login.salesforce.com/services/oauth2/token"
OAuth Scopes
Salesforce uses specific scopes to control access to different resources:
Core Scopes:
api
- Access to Salesforce APIs and datarefresh_token
- Enable refresh tokens for long-term accessopenid
- OpenID Connect for user identificationprofile
- Access to user profile informationemail
- Access to user email address
Additional Scopes:
full
- Full access (equivalent to api scope)web
- Web-based access to Salesforcecustom_permissions
- Access to custom permissionslightning
- Access to Lightning Platform APIswave_api
- Access to Salesforce Analytics Cloud APIs
Sandbox vs Production
For development, you can use a Salesforce Sandbox:
salesforce:
client_id: "${SALESFORCE_SANDBOX_CLIENT_ID}"
client_secret: "${SALESFORCE_SANDBOX_CLIENT_SECRET}"
# Use sandbox URLs for development
auth_url: "https://test.salesforce.com/services/oauth2/authorize"
token_url: "https://test.salesforce.com/services/oauth2/token"
scope: "api refresh_token openid profile email"
callback_path: "/salesforce/callback"
Testing Your Configuration
-
Start your MXCP server:
mxcp serve --debug
-
The authentication flow will begin when a client connects
-
Users will be redirected to Salesforce for authorization
-
After approval, they'll be redirected back to your callback URL
-
Check the logs for successful authentication
Troubleshooting
Common Issues:
-
Invalid Client Configuration:
ValueError: Salesforce OAuth configuration is incomplete
- Ensure
client_id
andclient_secret
are provided - Check that environment variables are set correctly
- Ensure
-
Callback URL Mismatch:
HTTPException: Invalid state parameter
- Verify the callback URL in your Connected App matches your MXCP configuration
- Ensure the URL scheme (http/https) is correct
-
Insufficient Permissions:
403 Forbidden
- Check that your Connected App has the required OAuth scopes
- Verify the user has access to the Salesforce org
-
Sandbox vs Production Issues:
Authentication failed
- Ensure you're using the correct login URL (
login.salesforce.com
vstest.salesforce.com
) - Verify your Connected App is deployed in the correct environment
- Ensure you're using the correct login URL (
Debug Tips:
- Enable debug logging:
mxcp serve --debug
- Check the Connected App deployment status in Salesforce Setup
- Verify OAuth scopes match your API requirements
- Test with minimal scopes like
openid profile
first
Security Best Practices
- Store credentials securely: Use environment variables, not config files
- Use HTTPS: Required for production OAuth flows
- Minimal scopes: Request only the permissions you need
- IP restrictions: Configure IP restrictions in your Connected App for production
- User permissions: Use Salesforce profiles and permission sets to control user access
- Token management: Implement proper refresh token handling
- Org validation: Verify users belong to the correct Salesforce org
Working with Salesforce Data
Once authenticated, you can use the user's Salesforce token to access their data:
-- Example: Query Salesforce accounts using the user's token
SELECT *
FROM read_json_auto(
'https://your-instance.salesforce.com/services/data/v58.0/sobjects/Account',
headers = MAP {
'Authorization': 'Bearer ' || get_user_external_token(),
'Content-Type': 'application/json'
}
);
Finding Your Salesforce Instance URL:
The instance URL is provided in the OAuth token response and varies by org (e.g., https://na1.salesforce.com
, https://eu2.salesforce.com
).
Keycloak
MXCP supports OAuth authentication with Keycloak, an open-source identity and access management solution. This allows your MCP server to authenticate users through Keycloak, enabling single sign-on across multiple applications and integration with various identity providers.
Creating a Keycloak Client
Before configuring MXCP, you need to create a client in your Keycloak realm:
Step 1: Access Keycloak Admin Console
- Log in to your Keycloak Admin Console (typically at
http://your-keycloak-server:8080/admin
) - Select your realm (or create a new one if needed)
Step 2: Create a New Client
- In the sidebar, click Clients
- Click Create client
- Configure the client:
- Client type: OpenID Connect
- Client ID: Choose a unique identifier (e.g.,
mxcp-client
) - Click Next
Step 3: Configure Client Settings
- Client authentication: Toggle ON (for confidential client)
- Authorization: Can be left OFF unless you need fine-grained authorization
- Enable the following in Authentication flow:
- Standard flow (Authorization Code flow)
- Direct access grants (optional, for testing)
- Click Next
Step 4: Configure Login Settings
- Valid redirect URIs: Add your MXCP callback URL
- For local development:
http://localhost:8000/*
- For production:
https://your-domain.com/*
- For local development:
- Valid post logout redirect URIs: Same as redirect URIs
- Web origins: Add
+
to allow all Valid Redirect URI origins - Click Save
Step 5: Get Client Credentials
- Go to the Credentials tab
- Copy the Client secret (you'll need this for MXCP configuration)
Environment Variables
Set these environment variables with your Keycloak credentials:
export KEYCLOAK_CLIENT_ID="mxcp-client"
export KEYCLOAK_CLIENT_SECRET="your-client-secret-here"
export KEYCLOAK_REALM="your-realm-name"
export KEYCLOAK_SERVER_URL="http://localhost:8080" # Your Keycloak server URL
MXCP Configuration
Configure Keycloak OAuth in your profile's auth section:
projects:
my_project:
profiles:
dev:
auth:
provider: keycloak
clients:
- client_id: "${KEYCLOAK_CLIENT_ID}"
client_secret: "${KEYCLOAK_CLIENT_SECRET}"
name: "My MXCP Application"
redirect_uris:
- "http://localhost:8000/keycloak/callback"
scopes:
- "mxcp:access"
keycloak:
client_id: "${KEYCLOAK_CLIENT_ID}"
client_secret: "${KEYCLOAK_CLIENT_SECRET}"
realm: "${KEYCLOAK_REALM}"
server_url: "${KEYCLOAK_SERVER_URL}"
scope: "openid profile email"
callback_path: "/keycloak/callback"
Configuration Options
client_id
: Your Keycloak client IDclient_secret
: Your Keycloak client secretrealm
: The Keycloak realm name where your client is configuredserver_url
: Base URL of your Keycloak server (without/auth
suffix)scope
: OAuth scopes to request (default: "openid profile email")callback_path
: Callback path for OAuth flow (default: "/keycloak/callback")
Advanced Keycloak Features
Multiple Realms: You can use different realms for different environments:
# Development realm
dev:
auth:
provider: keycloak
keycloak:
realm: "development"
# ... other config
# Production realm
prod:
auth:
provider: keycloak
keycloak:
realm: "production"
# ... other config
Custom Scopes: Keycloak allows you to define custom scopes and map them to user attributes or roles:
keycloak:
scope: "openid profile email custom_scope"
Identity Brokering: Keycloak can act as a broker for other identity providers (Google, SAML, etc.). Users authenticated through these providers will work seamlessly with MXCP.
Testing Your Configuration
-
Start your MXCP server:
mxcp serve --debug
-
The authentication flow will begin when a client connects
-
Users will be redirected to Keycloak for authentication
-
After successful login, they'll be redirected back to your callback URL
-
Check the logs for successful authentication
Troubleshooting
Common Issues:
-
Invalid Client Configuration:
ValueError: Keycloak OAuth configuration is incomplete
- Ensure all required fields (
client_id
,client_secret
,realm
,server_url
) are provided - Check that environment variables are set correctly
- Ensure all required fields (
-
Callback URL Mismatch:
HTTPException: Invalid state parameter
- Verify the redirect URI in your Keycloak client matches your MXCP configuration
- Ensure the URL scheme (http/https) is correct
-
Realm Not Found:
404 Not Found
- Check that the realm name in your configuration matches the Keycloak realm
- Verify the server URL is correct (should not include
/auth
suffix)
-
Invalid Client Credentials:
401 Unauthorized
- Verify client ID and secret are correct
- Ensure the client is enabled in Keycloak
- Check that "Client authentication" is ON for confidential clients
Debug Tips:
- Enable debug logging:
mxcp serve --debug
- Check Keycloak logs for authentication errors
- Use Keycloak's built-in account console to test user login
- Verify OAuth endpoints using
.well-known/openid-configuration
:curl http://localhost:8080/realms/your-realm/.well-known/openid-configuration
Security Best Practices
- Store credentials securely: Use environment variables, not config files
- Use HTTPS: Required for production OAuth flows
- Realm isolation: Use separate realms for different environments
- Client access: Configure client-specific roles and scopes
- Session management: Configure appropriate session timeouts in Keycloak
- Token validation: Enable token signature validation
- Audit logging: Enable Keycloak's event logging for security monitoring
Working with Keycloak Tokens
Once authenticated, you can use the user's Keycloak token to access protected resources:
-- Example: Use Keycloak token to access a protected API
SELECT *
FROM read_json_auto(
'https://api.example.com/protected/resource',
headers = MAP {
'Authorization': 'Bearer ' || get_user_external_token(),
'Content-Type': 'application/json'
}
);
Keycloak tokens are JWTs that contain user claims and can be decoded to access user information directly.
Google OAuth
MXCP supports OAuth authentication with Google, enabling access to Google Workspace APIs including Calendar, Drive, Gmail, and more. This allows your MCP server to authenticate users through their Google accounts and access Google services on their behalf.
Creating a Google OAuth App
Before configuring MXCP, you need to create OAuth 2.0 credentials in the Google Cloud Console:
Step 1: Create a Google Cloud Project
- Go to the Google Cloud Console
- Click Select a project → New Project
- Enter a project name and click Create
Step 2: Enable Required APIs
- In your project, go to APIs & Services → Library
- Search for and enable the APIs you need:
- Google Calendar API (for calendar access)
- Google Drive API (for file access)
- Gmail API (for email access)
- Enable other APIs as needed
Step 3: Configure OAuth Consent Screen
- Go to APIs & Services → OAuth consent screen
- Select External for user type (or Internal for Google Workspace users)
- Fill in the required information:
- App name: Your application name
- User support email: Your email address
- Developer contact information: Your email address
- Add scopes (click Add or Remove Scopes):
.../auth/userinfo.email
(for email address).../auth/userinfo.profile
(for basic profile).../auth/calendar.readonly
(for calendar read access)- Add other scopes as needed
- Add test users if in testing mode
- Review and save
Step 4: Create OAuth 2.0 Credentials
- Go to APIs & Services → Credentials
- Click Create Credentials → OAuth client ID
- Select Web application as the application type
- Configure the client:
- Name: A descriptive name for your client
- Authorized redirect URIs: Add your callback URLs
- For local development:
http://localhost:8000/google/callback
- For production:
https://your-domain.com/google/callback
- For local development:
- Click Create
- Save your Client ID and Client Secret
Environment Variables
Set these environment variables with your Google OAuth credentials:
export GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
export GOOGLE_CLIENT_SECRET="your-client-secret"
MXCP Configuration
Configure Google OAuth in your profile's auth section:
projects:
my_project:
profiles:
production:
auth:
provider: google
clients:
- client_id: "${GOOGLE_CLIENT_ID}"
client_secret: "${GOOGLE_CLIENT_SECRET}"
name: "My MXCP Application"
redirect_uris:
- "https://your-domain.com/google/callback"
scopes:
- "mxcp:access"
google:
client_id: "${GOOGLE_CLIENT_ID}"
client_secret: "${GOOGLE_CLIENT_SECRET}"
scope: "https://www.googleapis.com/auth/calendar.readonly openid profile email"
callback_path: "/google/callback"
auth_url: "https://accounts.google.com/o/oauth2/v2/auth"
token_url: "https://oauth2.googleapis.com/token"
OAuth Scopes
Google uses fine-grained OAuth scopes to control access to different services:
Core Identity Scopes:
openid
- OpenID Connect authenticationprofile
- Basic profile informationemail
- Email address
Google Calendar Scopes:
https://www.googleapis.com/auth/calendar.readonly
- Read calendar eventshttps://www.googleapis.com/auth/calendar
- Full calendar accesshttps://www.googleapis.com/auth/calendar.events
- Manage calendar events
Google Drive Scopes:
https://www.googleapis.com/auth/drive.readonly
- Read-only access to fileshttps://www.googleapis.com/auth/drive.file
- Access to files created by the apphttps://www.googleapis.com/auth/drive
- Full Drive access
Gmail Scopes:
https://www.googleapis.com/auth/gmail.readonly
- Read emailshttps://www.googleapis.com/auth/gmail.send
- Send emailshttps://www.googleapis.com/auth/gmail.modify
- Read and modify emails
Always request the minimum scopes needed for your application.
Testing Your Configuration
-
Start your MXCP server:
mxcp serve --debug
-
The authentication flow will begin when a client connects
-
Users will be redirected to Google for authentication
-
Google will show a consent screen listing the requested permissions
-
After approval, they'll be redirected back to your callback URL
-
Check the logs for successful authentication
Troubleshooting
Common Issues:
-
Invalid Client Configuration:
ValueError: Google OAuth configuration is incomplete
- Ensure
client_id
andclient_secret
are provided - Check that environment variables are set correctly
- Ensure
-
Redirect URI Mismatch:
Error 400: redirect_uri_mismatch
- Verify the callback URL in Google Cloud Console matches your MXCP configuration
- Ensure the URL scheme (http/https) and port are exact matches
-
Insufficient Scopes:
403 Forbidden - Insufficient Permission
- Check that you've enabled the required APIs in Google Cloud Console
- Verify the requested scopes match the enabled APIs
- Ensure the user has granted all requested permissions
-
Application Not Verified:
This app isn't verified
- For development, add test users in the OAuth consent screen
- For production, submit your app for Google verification
Debug Tips:
- Enable debug logging:
mxcp serve --debug
- Check the Google Cloud Console for API quotas and errors
- Use the Google OAuth 2.0 Playground to test scopes
- Verify API enablement in your Google Cloud project
Security Best Practices
- Store credentials securely: Use environment variables, not config files
- Use HTTPS: Required for production OAuth flows
- Minimal scopes: Request only the permissions you need
- Domain verification: Verify your domain for production apps
- Regular audits: Review OAuth consent screen and app permissions
- Token management: Implement proper token refresh logic
- Rate limiting: Be aware of Google API quotas and implement appropriate rate limiting
Working with Google APIs
Once authenticated, you can use the user's Google token to access various Google services:
-- Example: List Google Calendar events
SELECT *
FROM read_json_auto(
'https://www.googleapis.com/calendar/v3/calendars/primary/events',
headers = MAP {
'Authorization': 'Bearer ' || get_user_external_token(),
'Content-Type': 'application/json'
}
);
-- Example: Search Google Drive files
SELECT *
FROM read_json_auto(
'https://www.googleapis.com/drive/v3/files?q=name+contains+''report''',
headers = MAP {
'Authorization': 'Bearer ' || get_user_external_token()
}
);
API Endpoints:
- Calendar API:
https://www.googleapis.com/calendar/v3/
- Drive API:
https://www.googleapis.com/drive/v3/
- Gmail API:
https://www.googleapis.com/gmail/v1/
For detailed API documentation, refer to Google Workspace Developer Guides.
OAuth Client Registration
MXCP supports multiple ways for OAuth clients to register and authenticate:
Pre-registered Clients (Recommended for Development)
You can pre-register OAuth clients in your configuration file. This is the most straightforward approach for development and testing:
projects:
my_project:
profiles:
dev:
auth:
provider: github
# Pre-registered OAuth clients
clients:
# MCP CLI client (public client)
- client_id: "aa27466a-fd71-4c2a-9ecf-8b5db5d34384"
name: "MCP CLI Development Client"
redirect_uris:
- "http://127.0.0.1:49153/oauth/callback"
- "http://localhost:49153/oauth/callback"
scopes:
- "mxcp:access"
# Custom application (confidential client)
- client_id: "my-custom-app-client-id"
client_secret: "${MY_APP_CLIENT_SECRET}"
name: "My Custom Application"
redirect_uris:
- "https://myapp.example.com/oauth/callback"
grant_types:
- "authorization_code"
- "refresh_token"
scopes:
- "mxcp:access"
- "mxcp:admin"
github:
# ... GitHub configuration
Client Configuration Options:
client_id
(required): Unique identifier for the clientname
(required): Human-readable name for the clientclient_secret
(optional): Secret for confidential clients (omit for public clients)redirect_uris
(optional): Allowed redirect URIs (defaults to MCP CLI callback)grant_types
(optional): Allowed OAuth grant types (defaults to["authorization_code"]
)scopes
(optional): Allowed OAuth scopes (defaults to["mxcp:access"]
)
Dynamic Client Registration (RFC 7591)
MXCP implements RFC 7591 Dynamic Client Registration. Clients can register themselves at runtime by making a POST request to /register
:
curl -X POST http://localhost:8000/register \
-H "Content-Type: application/json" \
-d '{
"client_name": "My Application",
"redirect_uris": ["https://myapp.example.com/oauth/callback"],
"grant_types": ["authorization_code"],
"scope": "mxcp:access"
}'
The server will respond with client credentials:
{
"client_id": "generated-client-id",
"client_secret": "generated-client-secret",
"client_id_issued_at": 1640995200,
"client_secret_expires_at": 0,
"redirect_uris": ["https://myapp.example.com/oauth/callback"],
"grant_types": ["authorization_code"],
"scope": "mxcp:access"
}
OAuth State Persistence
MXCP supports persistent storage of OAuth authentication state to maintain user sessions across server restarts. By default, OAuth state (access tokens, authorization codes, and dynamically registered clients) is stored in memory and lost when the server restarts.
Configuration
Configure persistence in your user config file (~/.mxcp/config.yml
):
projects:
my_project:
profiles:
production:
auth:
provider: github
# OAuth state persistence configuration
persistence:
type: sqlite
path: "/var/lib/mxcp/oauth.db" # Optional, defaults to ~/.mxcp/oauth.db
clients:
- client_id: "${GITHUB_CLIENT_ID}"
client_secret: "${GITHUB_CLIENT_SECRET}"
name: "Production Application"
redirect_uris:
- "https://myapp.example.com/oauth/callback"
Configuration Options
type
: Backend type for persistence. Currently only"sqlite"
is supported.path
: Path to the SQLite database file. Optional, defaults to~/.mxcp/oauth.db
.
What Gets Persisted
The persistence system stores:
- Access Tokens: Internal MXCP tokens and their mappings to external provider tokens
- Authorization Codes: Temporary codes during OAuth flows (with automatic expiration cleanup)
- Dynamically Registered Clients: OAuth clients registered via RFC 7591 Dynamic Client Registration
Note: Pre-configured clients from your config file are not persisted, as they are loaded from configuration on each startup.
Benefits
- Session Continuity: User sessions survive server restarts
- Zero-Downtime Deployments: Users don't need to re-authenticate during updates
- Better User Experience: No interruption of OAuth flows during server maintenance
- Production Ready: Supports scaling and disaster recovery scenarios
Security Considerations
- The SQLite database contains sensitive OAuth tokens and should be protected with appropriate file permissions (600)
- Consider encrypting the database file at rest in production environments
- Implement regular cleanup of expired tokens (automatic cleanup happens during normal operations)
- Back up the database for disaster recovery, but ensure backups are also secured
Example Production Setup
# ~/.mxcp/config.yml
projects:
my_project:
profiles:
production:
auth:
provider: github
persistence:
type: sqlite
path: "/var/lib/mxcp/oauth.db"
clients:
- client_id: "${GITHUB_CLIENT_ID}"
client_secret: "${GITHUB_CLIENT_SECRET}"
name: "Production Application"
redirect_uris:
- "https://myapp.example.com/oauth/callback"
scopes:
- "mxcp:access"
github:
client_id: "${GITHUB_CLIENT_ID}"
client_secret: "${GITHUB_CLIENT_SECRET}"
scope: "user:email"
# ... other GitHub config
Production Recommendations
For production deployments:
- Enable persistence: Always configure OAuth persistence for production
- Secure database: Set appropriate file permissions (600) on the OAuth database
- Remove development clients: Don't include test/development client IDs in production configs
- Use environment variables: Store client secrets in environment variables, not config files
- Limit redirect URIs: Only include production callback URLs
- Scope restrictions: Use minimal required scopes
- HTTPS only: Ensure all redirect URIs use HTTPS in production
- Monitor logs: Watch for OAuth persistence errors in production logs
Example production configuration:
projects:
my_project:
profiles:
prod:
auth:
provider: github
persistence:
type: sqlite
path: "/var/lib/mxcp/oauth.db"
clients:
- client_id: "${PROD_CLIENT_ID}"
client_secret: "${PROD_CLIENT_SECRET}"
name: "Production Application"
redirect_uris:
- "https://myapp.example.com/oauth/callback"
scopes:
- "mxcp:access"
github:
client_id: "${GITHUB_CLIENT_ID}"
client_secret: "${GITHUB_CLIENT_SECRET}"
# ... other GitHub config
Authorization Configuration
MXCP supports configurable scope-based authorization to control access to your endpoints and tools. You can specify which OAuth scopes are required for accessing your server's resources.
Required Scopes
Configure authorization requirements using the authorization
section in your auth configuration:
projects:
my_project:
profiles:
dev:
auth:
provider: github
# Authorization configuration
authorization:
required_scopes:
- "mxcp:access" # Require this scope for all endpoint access
- "mxcp:admin" # Also require admin scope
clients:
- client_id: "${CLIENT_ID}"
# ... client config
Configuration Options:
required_scopes
: List of OAuth scopes that users must have to access protected endpoints- If
required_scopes
is empty ([]
), only authentication is required (no authorization) - If omitted entirely, defaults to no authorization requirements
Example Configurations:
# Authentication only (no scope requirements)
authorization:
required_scopes: []
# Require basic access scope
authorization:
required_scopes:
- "mxcp:access"
# Require multiple scopes (user must have ALL listed scopes)
authorization:
required_scopes:
- "mxcp:access"
- "mxcp:admin"
- "mxcp:write"
When authorization is configured, all protected endpoints (tools, resources, prompts, SQL features) will verify that the authenticated user's token contains the required scopes before allowing access.
User Token Access in SQL
When authentication is enabled, MXCP automatically creates several built-in SQL functions that allow your DuckDB queries to access information about the authenticated user and their tokens. This enables SQL queries to make authenticated API calls or access user-specific data.
Available User Functions
The following functions are automatically available in all SQL queries when a user is authenticated:
-- Get the user's original OAuth provider token (e.g., GitHub token)
SELECT get_user_external_token() as external_token;
-- Get user information
SELECT get_username() as username;
SELECT get_user_provider() as provider; -- 'github', 'atlassian', etc.
SELECT get_user_email() as email;
Example Use Cases
Making API calls from SQL using httpfs extension:
-- Use the user's GitHub token to fetch their repositories
SELECT *
FROM read_json_auto(
'https://api.github.com/user/repos',
headers = MAP {
'Authorization': 'Bearer ' || get_user_external_token(),
'User-Agent': 'MXCP-' || get_username()
}
);
-- Filter data based on the authenticated user
SELECT *
FROM my_data_table
WHERE owner = get_username();
User-specific data filtering:
-- Only show records owned by the current user
SELECT *
FROM user_documents
WHERE created_by = get_username();
-- Log user activity
INSERT INTO audit_log (user_id, action, timestamp)
VALUES (get_username(), 'data_query', NOW());
Function Behavior
- When authentication is disabled: All functions return empty strings (
""
) - When user is not authenticated: All functions return empty strings (
""
) - When user is authenticated: Functions return the actual user data
- Token security: Tokens are only available within the SQL context and are not logged
These functions enable powerful user-aware SQL queries while maintaining security through the authentication layer.
Security Considerations
- Environment Variables: Store sensitive credentials in environment variables, not in config files
- HTTPS: Use HTTPS in production environments
- Scope Limitation: Request only the minimum required OAuth scopes
- Token Expiration: Tokens have a default expiration of 1 hour
General Troubleshooting
Debug Logging
Enable debug logging to troubleshoot authentication issues:
mxcp serve --debug
Common Patterns
Most authentication issues fall into these categories:
- Configuration Issues: Missing or incorrect OAuth app settings
- Environment Variables: Credentials not properly set
- URL Mismatches: Callback URLs don't match between provider and MXCP
- Permission Issues: Insufficient scopes or user permissions
- Network Issues: Connectivity problems with OAuth providers
Reverse Proxy Deployment
When deploying MXCP behind a reverse proxy (nginx, HAProxy, AWS ELB, etc.) that handles SSL/TLS termination, you need to configure the URL scheme properly for OAuth callbacks to work correctly.
The Problem
OAuth providers require HTTPS callback URLs in production. When MXCP runs behind a reverse proxy with SSL termination:
- Client → HTTPS → Reverse Proxy → HTTP → MXCP
- MXCP sees only HTTP requests but needs to generate HTTPS callback URLs
- Without proper configuration, OAuth flows fail with "CSRF detected" or "invalid callback URL" errors
Solution Options
MXCP provides three ways to handle this:
Option 1: Explicit Scheme Configuration (Recommended)
Set the scheme explicitly in your transport configuration:
transport:
provider: streamable-http
http:
port: 8000
host: "0.0.0.0"
scheme: "https" # Force HTTPS for all generated URLs
Option 2: Automatic Proxy Header Detection
Enable proxy header trust to automatically detect scheme from X-Forwarded-Proto
:
transport:
provider: streamable-http
http:
port: 8000
host: "0.0.0.0"
trust_proxy: true # Trust X-Forwarded-Proto and X-Forwarded-Scheme headers
Your reverse proxy must set the appropriate headers:
# nginx configuration
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Option 3: Complete Base URL Override
Specify the complete external URL:
transport:
provider: streamable-http
http:
base_url: "https://api.example.com" # Complete external URL
Example nginx Configuration
Here's a complete nginx configuration for SSL termination with MXCP:
server {
listen 80;
server_name api.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /path/to/ssl/certificate.crt;
ssl_certificate_key /path/to/ssl/private.key;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# WebSocket support (if needed)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
OAuth Client Configuration
Update your OAuth client redirect URIs to use HTTPS:
auth:
provider: github
clients:
- client_id: "${PROD_CLIENT_ID}"
client_secret: "${PROD_CLIENT_SECRET}"
name: "Production Application"
redirect_uris:
- "https://api.example.com/github/callback" # HTTPS callback
scopes:
- "mxcp:access"
Troubleshooting
"CSRF detected" errors: Usually indicates scheme mismatch. Check that:
- Your transport configuration specifies
scheme: "https"
ortrust_proxy: true
- Your reverse proxy sets
X-Forwarded-Proto: https
header - OAuth client redirect URIs use HTTPS
"Invalid callback URL" errors: OAuth provider rejects the callback URL. Verify:
- Callback URLs in OAuth provider settings match your configuration
- URLs use HTTPS in production environments
- No port numbers in URLs when using standard ports (80/443)
Adding New Providers
The authentication system is designed to be extensible. Future OAuth providers can be added by:
- Implementing the
ExternalOAuthHandler
interface in a new provider file - Adding provider-specific configuration to the schema
- Updating the
create_oauth_handler
factory function - Adding documentation following the same structure as existing providers
See Also
- SQL Reference - Quick reference for authentication SQL functions
- Policy Enforcement - Control access to endpoints based on user context
- Audit Logging - Track authentication events and access attempts
- Testing with User Context - Test authenticated endpoints
- Configuration Guide - Complete configuration reference
- Features Overview - Explore all MXCP capabilities
Ready to secure your MXCP server? Start with the Quickstart Guide and add authentication as needed.