Skip to content

OAuth 2.1 Setup Guide

Henry edited this page Sep 27, 2025 · 1 revision

OAuth 2.1 Setup Guide

Complete guide for setting up OAuth 2.1 Dynamic Client Registration with MCP Memory Service to enable Claude Code HTTP transport and team collaboration features.

🚀 Overview

MCP Memory Service v7.0.0 introduces OAuth 2.1 Dynamic Client Registration (RFC 7591) for enterprise-ready authentication. This enables:

  • 🔗 Claude Code HTTP Transport: Direct team collaboration support
  • 🔐 Automatic Client Registration: Zero-configuration setup for OAuth clients
  • 🛡️ Enterprise Security: JWT-based authentication with proper scope validation
  • 🔄 Backward Compatibility: Existing API key authentication continues to work

⚡ Quick Start

1. Enable OAuth

Set the OAuth environment variable and start the server:

# Enable OAuth 2.1
export MCP_OAUTH_ENABLED=true

# Start HTTP server with OAuth
uv run memory server --http

# Your server now supports OAuth at http://localhost:8000

2. Test OAuth Endpoints

Verify OAuth is working:

# Test OAuth discovery
curl http://localhost:8000/.well-known/oauth-authorization-server/mcp

# Test client registration
curl -X POST http://localhost:8000/oauth/register \
     -H "Content-Type: application/json" \
     -d '{"client_name": "Test Client"}'

3. Connect Claude Code

Claude Code will automatically discover and register:

# Add HTTP transport server
claude mcp add --transport http memory-service http://localhost:8000/mcp

# Claude Code automatically:
# ✅ Discovers OAuth endpoints
# ✅ Registers as OAuth client
# ✅ Completes authorization
# ✅ Uses JWT tokens for requests

🔧 Configuration

Environment Variables

Essential OAuth configuration variables:

Variable Default Description
MCP_OAUTH_ENABLED true Enable/disable OAuth 2.1 endpoints
MCP_OAUTH_SECRET_KEY Auto-generated JWT signing key (set for persistence)
MCP_OAUTH_ISSUER Auto-detected OAuth issuer URL
MCP_OAUTH_ACCESS_TOKEN_EXPIRE_MINUTES 60 Access token lifetime
MCP_OAUTH_AUTHORIZATION_CODE_EXPIRE_MINUTES 10 Authorization code lifetime

Production Configuration

Secure Production Setup:

# Essential production settings
export MCP_OAUTH_ENABLED=true
export MCP_OAUTH_SECRET_KEY="your-secure-256-bit-secret-key"
export MCP_OAUTH_ISSUER="https://your-domain.com"
export MCP_HTTPS_ENABLED=true

# Optional security enhancements
export MCP_OAUTH_ACCESS_TOKEN_EXPIRE_MINUTES=30  # Shorter token lifetime
export MCP_API_KEY="fallback-api-key"            # Dual authentication

Development Configuration:

# Local development settings
export MCP_OAUTH_ENABLED=true
export MCP_OAUTH_ISSUER="http://localhost:8000"  # Match server port
export MCP_HTTPS_ENABLED=false                   # Optional for localhost

🔗 OAuth Endpoints

Discovery Endpoints

OAuth clients use these for automatic discovery:

  • GET /.well-known/oauth-authorization-server/mcp - OAuth server metadata
  • GET /.well-known/openid-configuration/mcp - OpenID Connect discovery

OAuth Flow Endpoints

Core OAuth 2.1 flow endpoints:

  • POST /oauth/register - Dynamic client registration
  • GET /oauth/authorize - Authorization endpoint
  • POST /oauth/token - Token endpoint

Management Endpoints

For debugging and administration:

  • GET /oauth/clients/{client_id} - Client information

🎯 Claude Code Integration

Automatic Setup (Recommended)

Claude Code automatically handles the complete OAuth flow:

  1. Discovery: Requests /.well-known/oauth-authorization-server/mcp
  2. Registration: Automatically registers as OAuth client
  3. Authorization: Completes authorization (auto-approved in current version)
  4. Token Exchange: Exchanges authorization code for access token
  5. API Access: Uses Bearer token for all MCP-over-HTTP requests

Simple Setup:

# Start OAuth-enabled server
export MCP_OAUTH_ENABLED=true
uv run memory server --http

# Add to Claude Code (automatic OAuth)
claude mcp add --transport http memory-service http://localhost:8000/mcp

Manual Configuration

For custom OAuth settings:

{
  "memoryService": {
    "protocol": "http",
    "http": {
      "endpoint": "http://localhost:8000",
      "oauth": {
        "enabled": true,
        "discoveryUrl": "http://localhost:8000/.well-known/oauth-authorization-server/mcp",
        "clientName": "My Claude Code Instance"
      }
    }
  }
}

🔐 Authentication Methods

OAuth 2.1 Bearer Tokens

Primary authentication method for HTTP transport:

# Get access token via OAuth flow
export ACCESS_TOKEN="your-jwt-access-token"

# Use Bearer token for API requests
curl -H "Authorization: Bearer $ACCESS_TOKEN" \
     http://localhost:8000/api/memories

API Key Authentication (Legacy)

Continues to work for backward compatibility:

# Legacy API key authentication
export MCP_API_KEY="your-api-key"
curl -H "Authorization: Bearer $MCP_API_KEY" \
     http://localhost:8000/api/memories

Dual Authentication

Both methods can be used simultaneously:

# Environment supports both
export MCP_OAUTH_ENABLED=true      # OAuth for new clients
export MCP_API_KEY="fallback-key"  # API key for legacy clients

Scope-Based Authorization

OAuth supports fine-grained permissions:

  • read: Access to read-only endpoints
  • write: Access to create/update endpoints
  • admin: Access to administrative endpoints

🛡️ Security Considerations

Production Security Checklist

  • Use HTTPS: Always enable HTTPS for production deployments
  • Set Secret Key: Provide secure MCP_OAUTH_SECRET_KEY for JWT signing
  • Secure Storage: Use persistent storage for production client data
  • Monitor Access: Implement logging and monitoring for OAuth endpoints
  • Rate Limiting: Consider rate limiting for OAuth registration/token endpoints

OAuth 2.1 Compliance

The implementation follows OAuth 2.1 security best practices:

  • 🔒 HTTPS required for non-localhost URLs
  • 🔑 Secure client credential generation
  • 🎫 JWT access tokens with proper validation
  • ⏰ Authorization code expiration (configurable)
  • 🎯 Proper redirect URI validation

🔍 Troubleshooting

Common Issues

OAuth endpoints return 404:

# Check if OAuth is enabled
echo $MCP_OAUTH_ENABLED  # Should be 'true'

# Restart server after configuration changes
uv run memory server --http

Claude Code connection fails:

# Test OAuth discovery
curl http://localhost:8000/.well-known/oauth-authorization-server/mcp

# Check server logs
tail -f logs/mcp-memory-service.log | grep -i oauth

# Verify HTTPS configuration for production
openssl s_client -connect your-domain.com:443

Invalid token errors:

# Check JWT secret consistency
echo $MCP_OAUTH_SECRET_KEY

# Verify token hasn't expired
# Check server logs for JWT validation errors

Debug Commands

Test Complete OAuth Flow:

# 1. Test discovery
curl http://localhost:8000/.well-known/oauth-authorization-server/mcp

# 2. Test client registration
curl -X POST http://localhost:8000/oauth/register \
     -H "Content-Type: application/json" \
     -d '{"client_name": "Debug Client", "redirect_uris": ["http://localhost:3000/callback"]}'

# 3. Check server health with OAuth status
curl http://localhost:8000/api/health

Enable Debug Logging:

# Start with OAuth debug logging
export LOG_LEVEL=DEBUG
export MCP_OAUTH_ENABLED=true
uv run memory server --http --debug

# Monitor OAuth activity
tail -f logs/mcp-memory-service.log | grep -E "(oauth|jwt|auth)"

📖 API Reference

Client Registration Request

{
  "client_name": "My Application",
  "redirect_uris": ["https://myapp.com/callback"],
  "grant_types": ["authorization_code"],
  "response_types": ["code"],
  "scope": "read write"
}

Client Registration Response

{
  "client_id": "mcp_client_abc123",
  "client_secret": "secret_xyz789",
  "redirect_uris": ["https://myapp.com/callback"],
  "grant_types": ["authorization_code"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "client_secret_basic"
}

Token Response

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "read write"
}

🧪 Testing & Development

Running OAuth Tests

# Test OAuth functionality
python tests/integration/test_oauth_flow.py

# Run full OAuth test suite
pytest tests/ -k oauth -v

# Manual OAuth flow testing
./scripts/test_oauth_flow.sh

Custom OAuth Client Development

# Example Python OAuth client
import requests

# Step 1: Register client
registration_data = {
    "client_name": "My Custom Client",
    "redirect_uris": ["http://localhost:3000/callback"]
}

response = requests.post(
    "http://localhost:8000/oauth/register",
    json=registration_data
)
client_info = response.json()

# Step 2: Start authorization flow
auth_url = f"http://localhost:8000/oauth/authorize?" \
           f"client_id={client_info['client_id']}&" \
           f"response_type=code&" \
           f"redirect_uri=http://localhost:3000/callback&" \
           f"scope=read write"

# Step 3: Exchange code for token (after user authorization)
token_data = {
    "grant_type": "authorization_code",
    "code": "received_auth_code",
    "redirect_uri": "http://localhost:3000/callback",
    "client_id": client_info['client_id'],
    "client_secret": client_info['client_secret']
}

token_response = requests.post(
    "http://localhost:8000/oauth/token",
    data=token_data
)
access_token = token_response.json()['access_token']

# Step 4: Use access token for API requests
headers = {"Authorization": f"Bearer {access_token}"}
memories = requests.get("http://localhost:8000/api/memories", headers=headers)

📚 Related Documentation


🔗 Standards & References


Ready to enable enterprise-grade team collaboration? Follow this guide to set up OAuth 2.1 with Claude Code HTTP transport!

Clone this wiki locally