OAuth Implementation Guide

Overview

This MCP server supports OAuth 2.1 authentication using stateless mode for secure, scalable API access.

How It Works

Authentication Flow

  1. Initial Request: Client sends request without credentials
  2. OAuth Challenge: Server returns 401 with WWW-Authenticate header
  3. Token Acquisition: Client obtains OAuth token from authorization server
  4. Authenticated Request: Client includes token in Authorization header
  5. Token Validation: Server validates JWT token on each request

Stateless Mode

The server operates in stateless mode (stateless: true in config), which means:
  • No server-side session storage
  • Each request is independently authenticated
  • Tokens are validated in real-time
  • Perfect for horizontal scaling

Authentication Methods

OAuth JWT Token

curl -X POST https://api.agentic.scope3.com/mcp \
  -H "Authorization: Bearer <jwt-token>" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "id": "1", "method": "ping"}'

API Key

curl -X POST https://api.agentic.scope3.com/mcp \
  -H "x-scope3-api-key: <api-key>" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "id": "1", "method": "ping"}'

Performance Considerations

What Happens on Each Request

  1. JWT Validation (~5-10ms): Cryptographic signature verification
  2. Customer Lookup (~20-50ms with cache): BigQuery query for OAuth users
  3. Total Overhead: ~30-60ms per request with caching

Optimizations

  • In-memory caching: Reduces BigQuery lookups
  • Preloading: Common queries cached proactively
  • Connection pooling: Reuses database connections

Security Benefits

  • Real-time validation: Expired tokens rejected immediately
  • No session hijacking: No server sessions to compromise
  • Token revocation: Works instantly (no cached sessions)
  • Audit trail: Every request independently authenticated

Testing OAuth

Use the provided test script:
# Test local server
./scripts/test-oauth.sh local

# Test production
./scripts/test-oauth.sh production

Configuration

The OAuth setup is configured in src/server.ts:
server.start({
  httpStream: {
    endpoint: config.endpoint,
    host: defaultHost,
    port,
    stateless: true, // Enable stateless OAuth support
  },
  transportType: "httpStream",
});

FAQ

Q: Do users need to reauthenticate on every request? A: No. Users provide their token/key with each request, but tokens remain valid until expiration. Q: Is stateless mode less secure? A: No, it’s more secure. Tokens are validated in real-time, preventing use of expired credentials. Q: What’s the performance impact? A: ~30-60ms overhead per request, mostly mitigated by caching. Q: Can we switch back to stateful mode? A: Yes, but OAuth discovery won’t work properly due to mcp-proxy session requirements.