Documentation Index
Fetch the complete documentation index at: https://docs.praison.ai/llms.txt
Use this file to discover all available pages before exploring further.
MCP Authentication
PraisonAI MCP Server supports multiple authentication methods per the MCP 2025-11-25 specification, including OAuth 2.1 with PKCE, OpenID Connect Discovery, and API Key authentication.
Protocol Version
This feature implements MCP Protocol Version 2025-11-25.
Authentication Methods
| Method | Description | Use Case |
|---|
| OAuth 2.1 | Full OAuth flow with PKCE | Web applications, user auth |
| OIDC Discovery | Auto-discover OAuth endpoints | Enterprise SSO |
| API Key | Simple bearer token | CLI tools, scripts |
Python API
OIDC Discovery
import asyncio
from praisonai.mcp_server.auth.oidc import OIDCDiscovery
async def main():
discovery = OIDCDiscovery()
# Discover from any OIDC provider
config = await discovery.discover("https://accounts.google.com")
if config:
print(f"Issuer: {config.issuer}")
print(f"Auth endpoint: {config.authorization_endpoint}")
print(f"Token endpoint: {config.token_endpoint}")
print(f"JWKS URI: {config.jwks_uri}")
asyncio.run(main())
OAuth 2.1 with PKCE
from praisonai.mcp_server.auth.oauth import OAuthConfig, OAuthManager
# Configure OAuth
config = OAuthConfig(
authorization_endpoint="https://auth.example.com/authorize",
token_endpoint="https://auth.example.com/token",
client_id="my-mcp-client",
default_scopes=["openid", "profile", "tools:read"],
use_pkce=True, # Required for OAuth 2.1
)
oauth = OAuthManager(config)
# Create authorization URL with PKCE
auth_url, auth_request = oauth.create_authorization_url(
scopes=["openid", "profile", "tools:call"],
)
print(f"Auth URL: {auth_url}")
print(f"State: {auth_request.state}")
print(f"Code verifier: {auth_request.code_verifier}")
print(f"Code challenge: {auth_request.code_challenge}")
# After user authorizes, exchange code for token
# token = await oauth.exchange_code(code, auth_request)
API Key Authentication
from praisonai.mcp_server.auth.api_key import APIKeyAuth
api_key_auth = APIKeyAuth()
# Generate a new API key
raw_key, api_key = api_key_auth.generate_key(
name="my-api-key",
scopes=["tools:read", "tools:call", "resources:read"],
)
print(f"Key: {raw_key}") # mcp_xxx... (store securely!)
print(f"Key ID: {api_key.key_id}")
print(f"Scopes: {api_key.scopes}")
# Validate a key
is_valid, validated_key = api_key_auth.validate(raw_key)
print(f"Valid: {is_valid}")
# Validate from Authorization header
is_valid, key = api_key_auth.validate_header("Bearer mcp_xxx...")
Scope Management
from praisonai.mcp_server.auth.scopes import ScopeManager
scope_manager = ScopeManager()
# Check if required scopes are granted
required = ["tools:read"]
granted = ["tools:call"] # tools:call implies tools:read
is_valid, challenge = scope_manager.validate_scopes(required, granted)
print(f"Valid: {is_valid}")
# Expand scopes (show implied scopes)
expanded = scope_manager.expand_scopes(["tools:call"])
print(f"Expanded: {expanded}") # {'tools:call', 'tools:read'}
# Admin scope expands to all
admin_expanded = scope_manager.expand_scopes(["admin"])
print(f"Admin expands to: {list(admin_expanded)[:5]}...")
CLI Usage
Start Server with API Key
praisonai mcp serve --transport http-stream --api-key YOUR_SECRET_KEY
Generate API Key
praisonai mcp auth generate-key --name "my-key" --scopes "tools:read,tools:call"
Validate API Key
praisonai mcp auth validate-key YOUR_KEY
Available Scopes
| Scope | Description | Implies |
|---|
tools:read | List and describe tools | - |
tools:call | Execute tools | tools:read |
resources:read | Read resources | - |
resources:subscribe | Subscribe to resource updates | resources:read |
prompts:read | List and get prompts | - |
prompts:execute | Execute prompts | prompts:read |
tasks:read | View tasks | - |
tasks:write | Create/cancel tasks | tasks:read |
admin | Full access | All scopes |
WWW-Authenticate Challenge
challenge = oauth.create_www_authenticate_challenge(
required_scopes=["admin"],
error="insufficient_scope",
error_description="Admin access required",
)
# Bearer scope="admin", error="insufficient_scope", error_description="Admin access required"
Security Best Practices
- Always use PKCE - Required for OAuth 2.1
- Validate origins - Use
--allowed-origins for HTTP transport
- Rotate API keys - Regularly rotate keys
- Minimal scopes - Request only needed scopes
- Secure storage - Never commit keys to version control
Environment Variables
# OAuth configuration
export OAUTH_CLIENT_ID=your_client_id
export OAUTH_CLIENT_SECRET=your_client_secret # Optional for public clients
export OIDC_ISSUER_URL=https://auth.example.com
# API key (for server)
export MCP_API_KEY=your_api_key