MCP CLI provides comprehensive token management for OAuth tokens, bearer tokens, API keys, and other credentials through the mcp-cli token command and integrated provider/server workflows.
All tokens are stored securely using OS-native secure storage (Keychain, Credential Manager, Secret Service) or HashiCorp Vault. Tokens are used throughout MCP CLI for:
- Provider Authentication: API keys for LLM providers (OpenAI, Anthropic, etc.)
- Server Authentication: OAuth and bearer tokens for MCP servers
- Generic Credentials: Any authentication token needed by tools or servers
See OAUTH.md for details on OAuth workflows and storage backends.
OAuth tokens are managed automatically during MCP server authentication. They include:
- Access token
- Refresh token (if available)
- Expiration time
- Issued timestamp
- Auto-refresh capability
Namespace: Stored by server name (e.g., notion, github)
Typical Usage:
- Automatically obtained through OAuth flow when connecting to OAuth-enabled MCP servers
- Refreshed automatically when expired
- Used transparently for server authentication
Example:
# View OAuth token metadata for a server
mcp-cli token get notion --oauth
# Delete OAuth token (forces re-authentication)
mcp-cli token delete notion --oauth
# List all OAuth tokens
mcp-cli token list --oauthSimple bearer tokens for HTTP authentication with APIs and MCP servers.
Namespace: bearer (default) or custom
Typical Usage:
- Static API authentication
- MCP server HTTP/SSE transport authentication
- Custom service authentication
Example:
# Store bearer token interactively (recommended - no shell history)
mcp-cli token set my-api --type bearer
# Enter token value for 'my-api': [hidden input]
# Or provide directly (less secure - visible in shell history)
mcp-cli token set my-api --type bearer --value "token_abc123"
# Use in MCP server config
{
"mcpServers": {
"my-api": {
"url": "https://api.example.com/mcp",
"headers": {
"Authorization": "Bearer ${TOKEN:bearer:my-api}"
}
}
}
}Provider API keys for LLM services (OpenAI, Anthropic, Google, etc.).
Namespace: api-key or provider
Typical Usage:
- LLM provider authentication
- Cloud service API keys
- Third-party service keys
Example:
# Store API key for OpenAI
mcp-cli token set openai --type api-key --provider openai
# Enter token value for 'openai': [hidden input]
# Store with explicit value
mcp-cli token set anthropic --type api-key --provider anthropic --value "sk-ant-..."
# Provider commands use these automatically
mcp-cli provider set openai # Uses stored api-key if available
mcp-cli --provider openai --server sqlite # Uses stored key
# Or reference explicitly
export OPENAI_API_KEY=$(mcp-cli token get openai --namespace api-key --show-value)Username/password credentials (planned feature).
View all stored tokens (metadata only, no sensitive values):
# List all tokens
mcp-cli token list
# Filter by type
mcp-cli token list --oauth # Only OAuth tokens
mcp-cli token list --api-keys # Only API keys
mcp-cli token list --bearer # Only bearer tokens
# Filter by namespace
mcp-cli token list --namespace provider-keys
# Combine filters
mcp-cli token list --no-oauth --api-keys # API keys but not OAuthOutput includes:
- Type: Token type (oauth, bearer, api_key, etc.)
- Name: Token identifier
- Created: Date token was registered
- Expires: Expiration date (if applicable, shows
⚠️ if expired) - Details: Provider, namespace, and other metadata
Manually store tokens for authentication:
# Interactive mode (recommended - more secure)
mcp-cli token set my-server --type bearer
# Enter token value for 'my-server': [hidden input]
# Store a bearer token with value
mcp-cli token set my-server --type bearer --value "abc123..."
# Store an API key
mcp-cli token set openai --type api-key --provider openai --value "sk-..."
# Store in custom namespace
mcp-cli token set my-token --type bearer --namespace custom --value "token123"
# With expiration
mcp-cli token set temp-token --type bearer --expires "2025-12-31" --value "xyz789"Security Note: The --value option should be used carefully as it may expose tokens in shell history. Using the interactive prompt (omitting --value) is more secure.
Retrieve information about a stored token (metadata only - actual values never shown):
# Get metadata
mcp-cli token get my-server
# Get from specific namespace
mcp-cli token get openai --namespace api-key
# Get OAuth token
mcp-cli token get notion --oauth
# Show value (use with caution)
mcp-cli token get my-server --show-valueRemove stored tokens:
# Delete a bearer token
mcp-cli token delete my-server
# Delete from specific namespace
mcp-cli token delete openai --namespace api-key
# Delete OAuth token for a server
mcp-cli token delete notion --oauth
# Force delete without confirmation
mcp-cli token delete my-server --forceRemove multiple tokens at once:
# Clear tokens in a namespace (with confirmation)
mcp-cli token clear --namespace bearer
# Clear ALL tokens (with confirmation)
mcp-cli token clear
# Skip confirmation
mcp-cli token clear --force
# Clear only expired tokens
mcp-cli token clear --expiredView available and active storage backends:
mcp-cli token backends
# Output shows:
# - Available backends (keyring, encrypted, vault)
# - Active backend
# - Backend health statusTokens are deeply integrated with the provider system for seamless LLM provider authentication.
When you configure or use a provider, MCP CLI automatically checks for stored API keys:
# Set provider - automatically uses stored token if available
mcp-cli provider set openai
# Or prompts for API key if not stored
# Enter API key for openai: [hidden input]
# Save to secure storage? [Y/n]: y
# Use provider - automatically retrieves stored token
mcp-cli --provider openai --server sqlite# Interactive provider setup (stores token securely)
mcp-cli provider set openai
# API key for openai: [hidden input]
# Save to secure storage? [Y/n]: y
# Set provider configuration including token
mcp-cli provider set openai api_key sk-...
# View provider status (shows if token is stored)
mcp-cli provider
# Provider: openai
# Status: ✅ Ready (API key stored securely)
# List providers with token status
mcp-cli providers
# Provider | Status | Token Status
# openai | ✅ Ready | 🔑 Stored
# anthropic | ✅ Ready | 🔑 Stored
# ollama | ✅ Ready | ⚠️ No key needed# Switch to provider that has stored token
mcp-cli provider openai
# Using stored API key ✅
# Switch to provider without token
mcp-cli provider anthropic
# No API key found. Enter API key: [hidden input]
# Save to secure storage? [Y/n]: y
# Override stored token temporarily
mcp-cli --provider openai --api-key sk-temp-key --server sqlite
# Note: Temporary key not savedTokens are used for MCP server authentication, especially for OAuth and HTTP/SSE transports.
OAuth tokens are managed automatically for OAuth-enabled MCP servers:
# Add OAuth-enabled server (triggers OAuth flow)
mcp-cli server add notion --oauth \
--client-id "your-client-id" \
--client-secret "your-secret" \
--auth-url "https://api.notion.com/v1/oauth/authorize" \
--token-url "https://api.notion.com/v1/oauth/token"
# OAuth flow starts automatically:
# 1. Browser opens to authorization page
# 2. User grants permission
# 3. Token automatically stored securely
# 4. Server connection established
# View OAuth token status
mcp-cli token get notion --oauth
# Server automatically uses stored OAuth token
mcp-cli --server notion
# Token auto-refreshes when expired
# Manual refresh if needed:
mcp-cli token refresh notion --oauthFor HTTP/SSE MCP servers requiring bearer token authentication:
# Store bearer token for server
mcp-cli token set github-mcp --type bearer --value "ghp_..."
# Configure server to use token
{
"mcpServers": {
"github-mcp": {
"transport": "http",
"url": "https://api.github.com/mcp",
"headers": {
"Authorization": "Bearer ${TOKEN:bearer:github-mcp}"
}
}
}
}
# Or add dynamically with token reference
mcp-cli server add github-mcp \
--transport http \
--header "Authorization: Bearer ${TOKEN:bearer:github-mcp}" \
-- https://api.github.com/mcpTokens can be injected as environment variables for STDIO servers:
# Store API token
mcp-cli token set my-service-key --type api-key --value "key_..."
# Reference in server config
{
"mcpServers": {
"my-service": {
"command": "node",
"args": ["server.js"],
"env": {
"API_TOKEN": "${TOKEN:api-key:my-service-key}",
"SERVICE_KEY": "${TOKEN:bearer:my-service}"
}
}
}
}Tokens are organized into namespaces for better organization:
| Namespace | Purpose | Examples |
|---|---|---|
oauth |
OAuth tokens (implicit) | Notion, GitHub, Google servers |
bearer |
Bearer tokens | Custom APIs, HTTP MCP servers |
api-key |
Provider API keys | OpenAI, Anthropic, Gemini |
provider |
Provider credentials | Alternative to api-key |
generic |
General purpose | Custom tokens |
custom-* |
User-defined | Any custom namespace |
Use the ${TOKEN:namespace:name} pattern to reference stored tokens:
{
"mcpServers": {
"custom-api": {
"url": "https://api.example.com/mcp",
"headers": {
"Authorization": "Bearer ${TOKEN:bearer:my-api}",
"X-API-Key": "${TOKEN:api-key:my-service}"
}
},
"secure-service": {
"command": "node",
"args": ["server.js"],
"env": {
"API_TOKEN": "${TOKEN:bearer:my-service}",
"OAUTH_TOKEN": "${TOKEN:oauth:my-oauth-server}"
}
}
}
}Provider tokens are stored separately from ~/.chuk_llm/config.yaml for security:
# ~/.chuk_llm/config.yaml - NO tokens stored here
openai:
api_base: https://api.openai.com/v1
default_model: gpt-4o
anthropic:
api_base: https://api.anthropic.com
default_model: claude-3-5-sonnet-20241022Tokens are stored securely in the OS keyring or encrypted storage, referenced by provider name.
- Tokens are never displayed - The CLI shows only metadata, never actual token values
- Use interactive prompts - Avoid
--valueflag to prevent shell history exposure - Use namespaces - Organize tokens by purpose for better management
- Rotate regularly - Update tokens periodically using
delete+set - Use OAuth when possible - Auto-refreshing tokens are more secure than static tokens
- Leverage OS keychains - Better than file-based storage
- Consider Vault for teams - Centralized secret management with audit logs
- Principle of least privilege - Store only necessary tokens
- Monitor expiration - Use
token listto check for expired tokens - Audit token usage - Review stored tokens periodically with
token list
# Set up OpenAI with token storage
mcp-cli provider set openai
# Enter API key: [hidden input]
# Save to secure storage? [Y/n]: y
# Set up Anthropic
mcp-cli provider set anthropic
# Enter API key: [hidden input]
# Save to secure storage? [Y/n]: y
# Verify stored tokens
mcp-cli token list --api-keys
# Provider | Status | Token
# openai | ✅ Ready | 🔑 Stored
# anthropic | ✅ Ready | 🔑 Stored# Store existing API keys from environment
mcp-cli token set openai --type api-key --provider openai --value "$OPENAI_API_KEY"
mcp-cli token set anthropic --type api-key --provider anthropic --value "$ANTHROPIC_API_KEY"
# Remove from environment for security
unset OPENAI_API_KEY
unset ANTHROPIC_API_KEY
# Verify storage
mcp-cli token list --api-keys
# Providers now use stored tokens automatically
mcp-cli --provider openai --server sqlite # Uses stored token# Add OAuth server (automatic token flow)
mcp-cli server add notion \
--transport http \
--oauth \
--client-id "oauth2_..." \
--client-secret "secret_..." \
--auth-url "https://api.notion.com/v1/oauth/authorize" \
--token-url "https://api.notion.com/v1/oauth/token" \
-- https://api.notion.com/v1/mcp
# OAuth browser flow starts automatically
# Token stored securely after authorization
# Check token status
mcp-cli token get notion --oauth
# Token used automatically when connecting
mcp-cli --server notion# Store token securely
mcp-cli token set my-service --type bearer
# Enter token value for 'my-service': [hidden input]
# Configure server with token reference
cat > server_config.json <<EOF
{
"mcpServers": {
"my-service": {
"transport": "http",
"url": "https://api.example.com/mcp",
"headers": {
"Authorization": "Bearer \${TOKEN:bearer:my-service}"
}
}
}
}
EOF
# Connect to server (uses stored token)
mcp-cli --server my-service# Configure Vault backend
export VAULT_ADDR=https://vault.company.com
export VAULT_TOKEN=s.your-token
# Verify backend
mcp-cli token backends
# Active: vault
# Status: ✅ Connected
# Store shared team tokens
mcp-cli token set shared-api --type bearer --namespace team
# Enter token value for 'shared-api': [hidden input]
# Team members with same Vault access can retrieve
mcp-cli token get shared-api --namespace team
# Provider tokens shared across team
mcp-cli token set openai --type api-key --provider openai
# All team members can now use: mcp-cli --provider openai# List tokens to find ones needing rotation
mcp-cli token list
# Rotate a bearer token
mcp-cli token delete my-api --force
mcp-cli token set my-api --type bearer
# Enter token value: [new token]
# Rotate provider API key
mcp-cli token delete openai --namespace api-key
mcp-cli provider set openai
# Enter API key: [new key]
# Save to secure storage? [Y/n]: y
# Rotate OAuth token (forces re-authentication)
mcp-cli token delete notion --oauth
mcp-cli --server notion # Triggers new OAuth flow# List tokens in test namespace
mcp-cli token list --namespace test
# Clear all test tokens
mcp-cli token clear --namespace test --force
# Clear expired tokens across all namespaces
mcp-cli token clear --expired --force# Check all namespaces
mcp-cli token list
# Try specific namespace
mcp-cli token get my-token --namespace bearer
mcp-cli token get my-token --namespace api-key
mcp-cli token get my-token --oauth
# List tokens to find it
mcp-cli token list | grep my-token# Check if token is stored
mcp-cli token list --api-keys
# Check provider status
mcp-cli provider
mcp-cli providers
# Re-set provider with new token
mcp-cli provider set openai
# Enter API key: [hidden input]# Check server token
mcp-cli token get my-server --oauth
mcp-cli token get my-server --namespace bearer
# Check server config references
cat server_config.json | grep TOKEN
# Verify token is not expired
mcp-cli token list | grep my-server
# Refresh OAuth token
mcp-cli token refresh my-server --oauth
# Re-store bearer token
mcp-cli token delete my-server
mcp-cli token set my-server --type bearer# Check available backends
mcp-cli token backends
# Verify current backend
cat ~/.mcp-cli/config.yaml | grep -A5 tokenStorage
# Switch to different backend (edit config)
{
"tokenStorage": {
"backend": "encrypted" # or "keyring", "vault"
}
}
# Test backend
mcp-cli token set test-token --type bearer --value "test123"
mcp-cli token get test-token
mcp-cli token delete test-tokenPlatform-specific solutions:
- macOS: Grant terminal access to Keychain in System Preferences > Privacy & Security
- Windows: Run as user with credential access, check Credential Manager permissions
- Linux: Ensure keyring daemon is running:
# Check daemon status ps aux | grep -E 'gnome-keyring|kwallet|keepass' # Start gnome-keyring gnome-keyring-daemon --start # Or use encrypted fallback export MCP_TOKEN_BACKEND=encrypted
- Vault: Verify token has read/write permissions to secret path
By design, token values are never displayed for security. If you need to retrieve a value:
# Use --show-value flag (use carefully)
mcp-cli token get my-token --show-value
# Or export to environment variable
export MY_TOKEN=$(mcp-cli token get my-token --show-value)Token management system consists of:
- Token Models (
token_types.py): OAuth, Bearer, APIKey, BasicAuth models - Storage Interface (
secure_token_store.py): Abstract storage interface - Storage Factory (
token_store_factory.py): Backend selection and creation - Storage Backends (
stores/): Platform-specific implementationskeyring_store.py: OS keychain integrationencrypted_store.py: Encrypted file storagevault_store.py: HashiCorp Vault integration
- Token Manager (
token_manager.py): High-level token operations - CLI Commands (
commands/token.py): Command-line interface - Provider Integration: Automatic token lookup for providers
- Server Integration: OAuth flow and bearer token injection
Planned features:
-
mcp-cli token export- Export tokens to encrypted file -
mcp-cli token import- Import tokens from file -
mcp-cli token rotate- Automatic token rotation -
mcp-cli token validate- Test token validity -
mcp-cli token refresh --all- Refresh all OAuth tokens - Support for client certificates
- Token expiration notifications
- Audit logging for token access
- Token permission scopes
- Multi-tenancy support
- Token templates for common providers
- Automatic token rotation policies
- Integration with external secret managers (AWS Secrets Manager, Azure Key Vault)