Adds an OAuth 2.1 proxy Worker that connects cloud MCP clients (claude.ai, Claude Code, Codex) to a self-hosted Hindsight instance via Cloudflare Workers and Tunnel. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
94 lines
4.2 KiB
Markdown
94 lines
4.2 KiB
Markdown
# Cloudflare OAuth Proxy for Self-Hosted Hindsight
|
|
|
|
An [OAuth 2.1](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12) proxy that connects cloud-based MCP clients (such as [claude.ai](https://claude.ai), [Claude Code](../claude-code/), and [Codex](../codex/)) to a self-hosted [Hindsight](https://vectorize.io/hindsight) instance. Built on [Cloudflare Workers](https://developers.cloudflare.com/workers/) using the [`@cloudflare/workers-oauth-provider`](https://github.com/cloudflare/workers-oauth-provider) library.
|
|
|
|
## Why
|
|
|
|
Cloud-based MCP clients require an OAuth 2.1 flow to connect to remote MCP servers. Self-hosted Hindsight instances typically sit behind a private network or Cloudflare Tunnel, and don't natively expose an OAuth endpoint. This Worker bridges that gap: it handles the OAuth dance on a public domain, authenticates the user with a simple password gate, and proxies authenticated MCP traffic to your Hindsight origin through a Cloudflare Tunnel.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
Cloud MCP Client (claude.ai, Claude Code, Codex)
|
|
|
|
|
| HTTPS + OAuth 2.1
|
|
v
|
|
Cloudflare Worker (this proxy)
|
|
- OAuth 2.1 authorization server
|
|
- Dynamic client registration (RFC 7591)
|
|
- PKCE (S256 only)
|
|
- CORS restricted to allowlisted origins
|
|
|
|
|
| HTTPS + Cloudflare Tunnel
|
|
v
|
|
Self-hosted Hindsight (Docker)
|
|
```
|
|
|
|
## Prerequisites
|
|
|
|
- A [Cloudflare](https://www.cloudflare.com/) account with a domain
|
|
- A running self-hosted Hindsight instance (see [self-hosting quickstart](https://vectorize.io/hindsight/quickstart/self-hosting))
|
|
- A [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/) exposing your Hindsight instance
|
|
- [Node.js](https://nodejs.org/) (v18+)
|
|
|
|
## Setup
|
|
|
|
### 1. Install dependencies
|
|
|
|
```bash
|
|
cd hindsight-integrations/cloudflare-oauth-proxy
|
|
npm install
|
|
```
|
|
|
|
### 2. Configure `wrangler.toml`
|
|
|
|
Copy the included `wrangler.toml` and update the placeholder values:
|
|
|
|
- `HINDSIGHT_ORIGIN`: Your Cloudflare Tunnel origin URL (e.g., `https://hindsight-origin.yourdomain.com`)
|
|
- `kv_namespaces.id`: Create a KV namespace via `npx wrangler kv namespace create OAUTH_KV` and paste the returned ID
|
|
- `routes.pattern` / `routes.zone_name`: Your public-facing domain for the proxy
|
|
|
|
### 3. Set secrets
|
|
|
|
```bash
|
|
npx wrangler secret put SESSION_SECRET # Password for the login page
|
|
npx wrangler secret put PROXY_SECRET # X-Proxy-Secret header value (must match your origin WAF rule)
|
|
npx wrangler secret put HINDSIGHT_API_TOKEN # Bearer token for the Hindsight API
|
|
npx wrangler secret put ALLOWED_EMAIL # Your email (used as the OAuth user identity)
|
|
```
|
|
|
|
### 4. Deploy
|
|
|
|
```bash
|
|
npm run deploy
|
|
```
|
|
|
|
### 5. Secure your origin
|
|
|
|
Add a WAF rule on your Cloudflare Tunnel origin hostname to block requests that don't carry the correct `X-Proxy-Secret` header. This ensures only the Worker can reach your Hindsight instance.
|
|
|
|
## Connecting clients
|
|
|
|
Once deployed, add the Worker URL as a remote MCP server in your client:
|
|
|
|
- **claude.ai**: Settings > MCP Servers > Add > enter `https://hindsight.yourdomain.com/mcp`
|
|
- **Claude Code**: `claude mcp add hindsight-remote https://hindsight.yourdomain.com/mcp --transport http`
|
|
- **Codex**: Configure via the MCP settings with the same URL
|
|
|
|
On first connection, you'll be redirected to a login page. Enter the `SESSION_SECRET` password to authorize. This only needs to happen once per OAuth session.
|
|
|
|
## Secrets reference
|
|
|
|
| Secret | Purpose |
|
|
|--------|---------|
|
|
| `SESSION_SECRET` | Password shown on the login page to authorize a session |
|
|
| `PROXY_SECRET` | Value sent as `X-Proxy-Secret` header to the origin (for WAF validation) |
|
|
| `HINDSIGHT_API_TOKEN` | Bearer token for authenticating with the Hindsight API |
|
|
| `ALLOWED_EMAIL` | Your email address, used as the OAuth user identity |
|
|
|
|
## Security notes
|
|
|
|
- CORS is restricted to `claude.ai` origins by default. To support additional clients (e.g., ChatGPT), add their origins to the `ALLOWED_ORIGINS` set in `src/index.ts`.
|
|
- PKCE is enforced with S256 only (plain PKCE is not advertised).
|
|
- OAuth state is stored in Cloudflare KV with a 5-minute TTL.
|
|
- The proxy strips the client's `Authorization` header and replaces it with the configured `HINDSIGHT_API_TOKEN` before forwarding to the origin.
|