Make the control plane usable before adding more autonomy.
This page turns endpoint health, model connectors, devices, session capture, capture inbox and autonomous execution into a setup checklist. Use it when deploying a new device, connecting a new model, or checking what still needs attention.
Open Brain memory lives in one shared Postgres on Railway. Every device you connect sees the same brain β there is no syncing to wait for. Pick the AI app you want to connect below, follow the steps, and the same memory you have here will be available there.
No API key saved yet β installer downloads and JSON snippets below will use a placeholder until you paste one.
Token expired? "Connection issue" in Claude.ai? That's the OAuth access token timing out β it does not mean your account or memory is gone. Three reconnect paths, in order of effort:
One-click (easiest): click the white Connect button on the expired-connection dialog. Approve the OAuth screen. Done.
If Connect does nothing: in the host app's connector settings, Disconnect the Open Brain entry, then add it again using the steps for your platform below.
Make it permanent: set MCP_OAUTH_ACCESS_TOKEN_TTL_SECONDS=0 in Railway β Open Brain server variables, redeploy, then reconnect once. All tokens issued after that never expire (revoke from /api-keys).
Run one command
Claude Code speaks HTTP MCP natively, so no bridge is needed. Open a terminal anywhere and run:
Approve the OAuth screen
Claude Code opens your browser to the Open Brain consent page. Approve it once. The token is stored locally; tools mcp__open-brain__* appear in your next prompt.
Verify
Run claude mcp list. You should see open-brain with a green β Connected. If it says Needs authentication, run claude mcp remove open-brain then re-add with the same command.
Re-authenticate when the token expires:claude mcp remove open-brain && claude mcp add --transport http open-brain <MCP_URL> β same command, takes 5 seconds. Or set MCP_OAUTH_ACCESS_TOKEN_TTL_SECONDS=0 on Railway so you never have to.
One-click install (recommended): save your API key above first, then download the installer for your OS. It writes claude_desktop_config.json for you (backing up any existing config), so you only have to install Node and relaunch Claude Desktop.
Install Node.js (one time per device)
Claude Desktop only speaks stdio MCP, so we bridge to the Open Brain HTTPS endpoint via a small Node helper called mcp-remote. Install Node 18 or newer from nodejs.org. Verify with node --version in a terminal.
Locate claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
If the file does not exist, create it with {} as its contents.
Add the Open Brain MCP server block
Paste the snippet below into the file. If mcpServers already exists, just add the "open-brain" entry inside it.
Quit and relaunch Claude Desktop
Fully quit (not just close the window). When it reopens, the Open Brain tools appear under the connector list. Try a prompt like "Use Open Brain to find recent memories about [a topic you know is in your brain]."
Tip: first launch will take a few seconds while npx downloads mcp-remote on this device. Subsequent launches are instant.
Re-authenticate: if Claude Desktop shows "Open Brain disconnected" in the connector list, click the entry β Reconnect. The browser opens, you approve, done. If reconnect fails, replace the x-api-key value in claude_desktop_config.json with a fresh key from /api-keys and relaunch.
One-click install: save your API key above, then download the installer. It merges the open-brain entry into ~/.cursor/mcp.json (creating it if missing, backing up the old file).
Install Node.js (one time per device)
Cursor uses the same mcp-remote bridge as Claude Desktop. Install Node 18+ from nodejs.org.
Locate mcp.json
Windows: %USERPROFILE%\.cursor\mcp.json
macOS / Linux: ~/.cursor/mcp.json
If the file does not exist, create it with { "mcpServers": {} }.
Add the Open Brain MCP server block
Paste the snippet into the mcpServers object.
Restart Cursor
Fully quit Cursor, reopen it, then open Cursor Settings β MCP and confirm open-brain appears with a green status. Use Composer or chat and ask it to search Open Brain for something you know is stored there.
Tip: Cursor reads mcp.json only at startup. If you edit the file while Cursor is running, restart it.
Re-authenticate: Cursor uses the API key in mcp.json, not OAuth, so the key never "expires" on its own. If open-brain shows red in Cursor Settings β MCP, the API key was probably revoked. Mint a new key at /api-keys, paste it into the --header line, and restart Cursor.
Open Claude.ai connector settings
Sign in at claude.ai, open Settings β Connectors (or Integrations). The same connector works on the web app, the desktop app, and the mobile app β set it up once on your account and it follows you.
Add a custom connector
Choose "Add custom connector" (or similar). Paste the URL below. Claude.ai will start an OAuth handshake β your browser opens, you authorise the connector, and a token is saved to your Claude account.
Enable the connector in a chat
Open a Claude conversation, click the connectors icon, toggle Open Brain on. From now on every Claude.ai chat β including on your phone β has access to the same memory.
Why this is the simplest path for mobile: no Node, no config files, no per-device install. The OAuth token is stored on your Claude account, so signing into Claude on a new phone or laptop instantly inherits the connector.
Re-authenticate ("Connection has expired"): Claude.ai's stored OAuth token timed out (default 90 days, unless you set permanent tokens β see callout above). Click the white Connect button on the dialog; the OAuth flow runs again and saves a fresh token. If that fails, go to Settings β Connectors β Open Brain β Disconnect, then re-add the URL above.
"Couldn't reach the MCP server" in Claude.ai? If you self-host Open Brain behind Cloudflare Access (email-gated zero-trust), the connector dies on a 302 redirect to a Cloudflare login page before reaching your server. β Full click-by-click fix below.
Open ChatGPT custom GPT or connector settings
In ChatGPT, go to Explore GPTs β Create (or Settings β Connectors if your account has the connector beta). Custom GPTs let you wire an external MCP-compatible API and reuse it across devices linked to the same OpenAI account.
Point it at the Open Brain MCP endpoint
Use the URL below. ChatGPT will request authentication β paste your Open Brain API key when prompted, or use the OAuth flow if you have it configured.
Test the connection
In a chat, ask the GPT to search Open Brain for something you know exists in your memory. A successful response confirms the link.
Note: ChatGPT's MCP support is newer and varies by plan. If your account does not yet expose connector settings, the Claude.ai or Claude Desktop paths above are more mature today.
Re-authenticate: in ChatGPT, open the custom GPT or connector entry and click Reconnect / Re-authorise. If that's missing, delete the connector and re-add it using the URL above with a fresh API key.
How is this persistent across devices? Your memories live in one Railway Postgres database. Every connector β Claude Desktop on your laptop, Cursor on your work machine, Claude.ai on your phone β talks to the same MCP endpoint and reads the same brain. There is nothing to sync. Sessions on the server side now hold for 7 days of idle and reconnect cleanly after that, so once a device is set up you can leave it alone.
Self-hosting Β· troubleshooting
"Couldn't reach the MCP server" β fix Cloudflare Access
If you self-host Open Brain behind Cloudflare Access (email-gated zero-trust), MCP connectors cannot reach /mcp. Every request is 302-redirected to a Cloudflare login page before it touches your server, and the connector expects JSON-RPC. The reliable fix is to expose /mcp on a dedicated subdomain that is not enrolled in any Access app β your MCP route already ships its own OAuth 2.1 (PKCE + dynamic client registration + setup-code approval), so this loses zero security. CF Access was duplicative auth for an endpoint that isn't a browser surface; connectors can't follow its email-link login flow anyway.
Confirm this is the symptom you're hitting (10-second probe)
From any terminal, run a raw POST against your MCP endpoint:
You have this problem if: response is HTTP/1.1 302 Found with header Www-Authenticate: Cloudflare-Access and a Location: pointing at *.cloudflareaccess.com. You're already OK if: response is HTTP/1.1 401 with WWW-Authenticate: Bearer resource_metadata=β¦ β that's Open Brain's own OAuth layer asking the client to authenticate, which is correct.
Phase 1 β Pick a connector setup code
When CF Access is not in front of the request, /oauth/authorize falls back to a "Connector setup code" prompt. Without the env var below set, every code is rejected and the OAuth flow can't complete.
Generate a long random string
PowerShell: -join ((1..32) | %{ [char]((48..57)+(65..90)+(97..122) | Get-Random) }). Or use any password manager β 32+ chars, alphanumeric. Save it; you'll paste it once per connecting device.
Add it to Railway as MCP_OAUTH_SETUP_CODE
Railway dashboard β your Open Brain project β server service β Variables tab β New Variable. Name MCP_OAUTH_SETUP_CODE, value = the random string. Save.
Wait for the redeploy
Railway redeploys automatically (~30β60s). Watch the deploy log until you see Server listening.
Phase 2 β Add a CNAME in Cloudflare DNS
Open the Cloudflare DNS panel
dash.cloudflare.com β select your zone β DNS β Records β Add record.
Create the CNAME
Type: CNAME. Name: mcp (just the subdomain β Cloudflare appends the zone). Target: your existing Railway custom-domain target (find it in Railway β Project β Settings β Networking β same target as your apex domain uses). Proxy status: Proxied (orange cloud ON) β required for TLS. TTL: Auto.
Verify DNS
From any shell: nslookup mcp.your-domain. Cloudflare DNS propagates within seconds.
Phase 3 β Add the custom domain on Railway
Open Railway's domain panel
Railway β your project β click the Open Brain server service β Settings tab β scroll to Networking / Domains.
Add the custom domain
+ Custom Domain β enter mcp.your-domain β Add Domain. Railway probes DNS and provisions a TLS cert automatically.
Wait for "Active" status
Usually 15β90 seconds. If still pending after 5 min, hard-refresh the Railway page β its UI sometimes caches stale state.
Quick browser test
Open https://mcp.your-domain/health. A JSON 401 (or similar from auth middleware) means TLS works and CF Access is not in the way. A Cloudflare login page means Phase 4 still has work to do.
Phase 4 β Confirm Cloudflare Access doesn't catch the new subdomain
Audit your Access applications
Top-right account menu β Zero Trust β Access β Applications. Inspect each app's Application domain column.
Make sure none of them catches mcp.your-domain
If you see a wildcard like *.your-domain, the new subdomain is re-gated. Three fixes β pick one:
Narrow that app's domain to just the apex (your-domain) plus any specific subdomains you do want gated.
In the same app, replace the wildcard with one explicit domain row per gated host.
Create a new Access app scoped to mcp.your-domain/* with a single Action: Bypass, Include: Everyone policy. Bypass apps short-circuit any wildcard parent.
Smoke-test again
Re-run the curl probe at the top of this article against https://mcp.your-domain/mcp. Pass = HTTP/1.1 401 with WWW-Authenticate: Bearer β¦. Fail = HTTP/1.1 302 with Location: β¦cloudflareaccess.com. If still 302, the audit missed something β re-check.
Phase 5 β Connect from Claude.ai
Open Claude's connector settings
claude.ai β your avatar (top-right) β Settings β Connectors (or Integrations depending on plan).
Add a custom connector
Name: Open Brain. URL: https://mcp.your-domain/mcp. Click Add / Connect.
Approve the OAuth flow
A popup opens. You should see an Open Brain-branded "Approve Claude connector" page asking for a Connector setup code. If you see a Cloudflare login page instead β Phase 4 failed; go back. Paste the value of MCP_OAUTH_SETUP_CODE from Phase 1. Click Approve Claude connector.
Enable it in a chat
Open any Claude conversation β click the connector icon β toggle Open Brain ON. Send a test message like "Search my Open Brain for X". A successful tool call confirms end-to-end.
Phase 6 β (optional) Make this setup page advertise the new URL
The MCP URL in the snippets above is derived from whichever host you load this page from. If you usually open this page at the (still-gated) apex, the displayed URL won't match the working MCP subdomain. Two ways to fix:
Page-level override (simplest, no redeploy)
Edit server/public/setup.html. In <head> find <meta name="ob-public-mcp-url" content=""> and set content="https://mcp.your-domain/mcp". All connector snippets on this page (Claude Code, Claude Desktop, Cursor, Claude.ai, ChatGPT) will use it. Commit and push.
Server-wide override
Set PUBLIC_BASE_URL=https://mcp.your-domain in Railway env. This makes OAuth metadata and other server-generated URLs advertise the MCP subdomain. (The setup-page snippets above are rendered client-side, so you still want the meta tag too.)
Revoke MCP Access
Disconnect a client or kill a permanent token
Every OAuth handshake mints a row in api_keys named Remote MCP OAuth <client> (claude|chatgpt|unknown). Deleting that row revokes the token instantly β the next request from that client gets a 401 and the connection drops. Use this when you suspect a token leaked, when a client is stuck in a bad state, or when retiring a device.
Easiest β Dashboard
UI
Open the API Keys panel in the main dashboard, scroll to entries named Remote MCP OAuth β¦, and click Delete on the one you want to kill.
Kill one connector (e.g. only the Claude.ai one) without touching the others. Run on Railway Postgres:
DELETE FROM api_keys
WHERE name LIKE 'Remote MCP OAuth%(claude)%';
Swap (claude) for (chatgpt) or (unknown) to target a different client.
Nuclear β revoke all MCP
SQL
Kill every OAuth-issued MCP token in one shot. Every connected client will need to reconnect. Static API keys you minted yourself are untouched.
DELETE FROM api_keys
WHERE name LIKE 'Remote MCP OAuth%';
Audit β see what's live
SQL
List every active OAuth token, when it was issued, when it was last used, and when (if ever) it expires:
SELECT name, created_at, last_used_at,
COALESCE(expires_at::text, 'never') AS expires
FROM api_keys
WHERE name LIKE 'Remote MCP OAuth%'
ORDER BY created_at DESC;
expires = never means a permanent token (issued while MCP_OAUTH_ACCESS_TOKEN_TTL_SECONDS=0). Delete it explicitly to end its life.
Permanent tokens never auto-expire. The only way to invalidate one is to delete its row. If a laptop is lost, a connector was added by mistake, or you suspect a token leaked, run the targeted or nuclear DELETE above β it takes effect on the very next request.