Skip to main content

Claude Integration

email-connector is a remote MCP server that integrates with Claude through OAuth 2.0 with PKCE. This page explains exactly what happens when you connect your email to Claude.

What Claude Expects

Claude’s MCP connector system requires:
Requirementemail-connector
TransportStreamable HTTP (POST /mcp)
AuthOAuth 2.0 with PKCE (S256)
Callback URLhttps://claude.ai/api/mcp/auth_callback
Token typeBearer
Server metadataRFC 8414 at /oauth/meta
CORSMust allow claude.ai and claude.com

Connection Flow

When you add the connector in Claude, here’s exactly what happens:
1. Claude fetches server metadata from /oauth/meta
2. Claude opens /oauth/authorize in a popup with:
   - client_id
   - redirect_uri = https://claude.ai/api/mcp/auth_callback
   - response_type = code
   - code_challenge (SHA-256 hash of a random verifier)
   - code_challenge_method = S256
   - state (CSRF protection)

3. email-connector shows the setup form
4. You enter your email + app password
5. email-connector validates via live IMAP connection
6. On success → redirects to Claude's callback with auth code

7. Claude exchanges the code at POST /oauth/token with:
   - code_verifier (proves it initiated the request)
   - client_id + client_secret

8. email-connector verifies PKCE, returns access token
9. Claude stores the token and uses it for all MCP requests

PKCE (Proof Key for Code Exchange)

PKCE prevents authorization code interception attacks. The flow works like this:
  1. Claude generates a random code_verifier (43–128 chars)
  2. Claude computes code_challenge = BASE64URL(SHA256(code_verifier))
  3. Claude sends code_challenge + code_challenge_method=S256 to /oauth/authorize
  4. email-connector stores the challenge alongside the pending auth
  5. At token exchange, Claude sends the original code_verifier
  6. email-connector recomputes the hash and verifies it matches the stored challenge
This ensures that even if an attacker intercepts the authorization code, they cannot exchange it for a token without the original verifier.

Redirect URIs

email-connector accepts these callback URLs:
ClientRedirect URI
Claude.aihttps://claude.ai/api/mcp/auth_callback
Claude.comhttps://claude.com/api/mcp/auth_callback
Claude Codehttp://localhost:6274/oauth/callback
MCP Inspectorhttp://localhost:6274/oauth/callback/debug
Any other redirect URI is rejected.

Token Lifecycle

PropertyValue
Token typeBearer
Expiry30 days
Scopeemail:read email:write
RevocationPOST /oauth/revoke
Tokens are opaque strings (32 random bytes, hex-encoded). They map to encrypted credentials in the server’s credential store.

MCP Session Management

After auth, Claude communicates via MCP Streamable HTTP:
  1. POST /mcp — Initialize a new session or send messages to an existing one. Returns Mcp-Session-Id header on first request.
  2. GET /mcp — SSE upgrade for streaming responses within an active session.
  3. DELETE /mcp — Close a session and free server resources.
Sessions time out after 30 minutes of inactivity. When a session expires, Claude automatically creates a new one on the next request.

CORS Configuration

email-connector allows requests from:
  • https://claude.ai
  • https://claude.com
  • https://email-connector.fly.dev
  • https://connectmyemail.com
The Mcp-Session-Id header is exposed in CORS responses so Claude can maintain session continuity.

Server Metadata

Claude discovers endpoints via RFC 8414 OAuth Server Metadata at GET /oauth/meta:
{
  "issuer": "https://email-connector.fly.dev",
  "authorization_endpoint": "https://email-connector.fly.dev/oauth/authorize",
  "token_endpoint": "https://email-connector.fly.dev/oauth/token",
  "revocation_endpoint": "https://email-connector.fly.dev/oauth/revoke",
  "response_types_supported": ["code"],
  "grant_types_supported": ["authorization_code"],
  "code_challenge_methods_supported": ["S256"],
  "token_endpoint_auth_methods_supported": ["client_secret_post"]
}

Security Headers

All responses include:
  • Strict-Transport-Security: max-age=63072000; includeSubDomains
  • X-Frame-Options: DENY
  • X-Content-Type-Options: nosniff
  • Referrer-Policy: no-referrer
  • x-powered-by disabled