This guide deploys Edstem MCP to Cloudflare Workers and connects it to ChatGPT web, Codex, or Claude.
You need:
- A Cloudflare account.
- An Ed API token from Ed settings.
- The hostname Cloudflare assigns after deployment.
Never put the Ed token in a URL. The Worker accepts it through Authorization or X-API-Key, validates it against Ed, and does not store it.
- Select Deploy to Cloudflare and sign in.
- Choose a repository and Worker name.
- Deploy, then copy the assigned
workers.devhostname. - Check
https://<worker-host>/healthz. It should return{"ok":true,...}.
Your MCP URL is:
https://<worker-host>/mcp
For manual deployment:
npm ci
npx wrangler login
npm run deploy:workerFor production, add these Worker variables in the Cloudflare dashboard:
MCP_ALLOWED_HOSTNAMES=<worker-host>
MCP_ALLOWED_ORIGIN_HOSTNAMES=chatgpt.com,claude.ai
MCP_TOKEN_CACHE_TTL_SECONDS=300
MCP_ALLOW_POSTING=0
MCP_TOKEN_CACHE_TTL_SECONDS controls how long a verified token stays cached in memory per isolate. It defaults to 300 seconds; set it to 0 to verify every request against Ed.
MCP_ALLOW_POSTING=1 enables the create_thread and reply_thread tools. They publish to the course forum under the token owner's name, so leave them disabled unless a client needs them.
| Client | URL | Authentication |
|---|---|---|
| ChatGPT web | https://edstem.tuuhub.com/mcp |
OAuth |
| Codex desktop, CLI, or IDE | Your Worker /mcp URL |
Ed token through an environment variable |
| Claude connector | Your Worker /mcp URL when Request headers are available |
Authorization or X-API-Key |
| Claude connector without Request headers | https://edstem.tuuhub.com/mcp |
OAuth |
Static Ed tokens are a convenience authentication mode, not MCP OAuth. ChatGPT web does not provide a field for an arbitrary API key, so it uses the hosted OAuth endpoint.
The OAuth service persists credentials so clients can reconnect without receiving your raw Ed token.
- The service verifies your Ed token against Ed's
/api/userendpoint before saving it. - It encrypts the Ed token with AES-256-GCM using a new 12-byte IV and authentication tag for each write.
- SQLite stores the ciphertext, IV, authentication tag, Ed user ID, Ed user name, verification time, and status. It does not store the plaintext Ed token.
- Operators supply a 32-byte
MASTER_KEYoutside SQLite as a server environment secret. The key encrypts and decrypts the token. MASTER_KEY_PREVIOUSsupports key rotation. The service decrypts an old record and re-encrypts it with the current key on the next read.- Plaintext exists in process memory while the service verifies the token or calls Ed. The application does not log it or include it in errors.
The service also issues its own random OAuth access and refresh tokens. These are separate from the Ed token. The current implementation stores them by token value in SQLite with client, user, scope, and expiry metadata so it can validate, refresh, revoke, and delete them. Treat the OAuth database as sensitive even though AES-256-GCM protects the raw Ed token inside it.
Deleting the hosted account removes the live encrypted Ed credential and associated OAuth records. Backups may follow the hosting provider's retention policy. See Terms of Service for the complete retention statement.
The Worker does not persist the credential.
- The client sends the Ed token in
Authorization: Bearer ...orX-API-Keyover HTTPS on each request. - The Worker verifies it against Ed, keeps it in memory for that request, and uses it for the requested Ed API calls.
- The Worker has no D1, KV, R2, Durable Object, database, or filesystem binding for credentials.
- The application does not write the header to logs. Your MCP client and hosting provider still apply their own credential and logging policies.
In this mode, “API key” means the Ed token that the client sends directly. The Worker does not mint or save a separate key.
- Open ChatGPT Settings > Security and login and enable Developer mode.
- Open ChatGPT Plugins and select the plus button.
- Enter
https://edstem.tuuhub.com/mcpas the MCP server URL. - Create the connection and complete OAuth sign-in.
- Install the plugin, open a Work chat, and select it with
@.
Your static-token Worker cannot connect directly to ChatGPT web. Use the OAuth endpoint above.
Codex desktop, CLI, and the IDE extension share MCP configuration. Export the token:
export EDSTEM_TOKEN="your-ed-token"Add this to ~/.codex/config.toml:
[mcp_servers.edstem]
url = "https://<worker-host>/mcp"
bearer_token_env_var = "EDSTEM_TOKEN"To use X-API-Key instead, replace bearer_token_env_var with:
env_http_headers = { "X-API-Key" = "EDSTEM_TOKEN" }Restart Codex, then run /mcp or codex mcp list to check the connection.
Static request headers are a beta feature with gradual availability.
For Free, Pro, or Max accounts:
- Open Claude Settings > Connectors.
- Select Add custom connector and enter your Worker
/mcpURL. - If Request headers is available, add one of:
Authorization=Bearer <your-ed-token>X-API-Key=<your-ed-token>
- Add the connector, then enable it from + > Connectors in a conversation.
For Team or Enterprise, an owner adds the connector under Admin settings > Connectors. Members connect it under Settings > Connectors.
If the Request headers field is unavailable, add https://edstem.tuuhub.com/mcp and use OAuth instead. Do not configure a static Authorization header and OAuth on the same connector.