Connect

Connect your agent

One URL, sign in when asked. API keys are the fallback for scripts and CI.

Every agent connects to the same place:

text
https://mcp.formalogic.io/mcp

You do not need an API key. The server uses OAuth: the first time your agent calls a Forma tool, it opens your browser, you sign in with your Forma account, and the agent is connected. The Overview shows the moment it happens.

You need a Forma account first. Signing in from an agent never creates one.

Claude

Claude

Claude on the web and Claude Desktop use the same connector.

  1. Settings → Connectors → Add custom connector.
  2. Name it Forma and paste the URL above.
  3. Click Connect and sign in.

Claude Code

Claude Code

bash
claude mcp add --transport http forma https://mcp.formalogic.io/mcp

Then type /mcp in Claude Code, pick forma, and choose Authenticate. claude mcp list should read forma … ✔ Connected.

ChatGPT

  1. Settings → Apps & Connectors → Advanced → turn on Developer mode.
  2. Create a connector named Forma with the URL above and OAuth authentication.
  3. Sign in when ChatGPT asks.

Cursor

Cursor

Add to Cursor, or add this to ~/.cursor/mcp.json:

json
{
  "mcpServers": {
    "forma": { "url": "https://mcp.formalogic.io/mcp" }
  }
}

Cursor shows Needs login next to forma. Click it and sign in.

VS Code

bash
code --add-mcp '{"name":"forma","type":"http","url":"https://mcp.formalogic.io/mcp"}'

Start forma from the MCP view and sign in when asked.

Windsurf

Windsurf

Add to ~/.codeium/windsurf/mcp_config.json, then sign in when Windsurf asks:

json
{
  "mcpServers": {
    "forma": { "serverUrl": "https://mcp.formalogic.io/mcp" }
  }
}

Codex

bash
codex mcp add forma --url https://mcp.formalogic.io/mcp
codex mcp login forma

The second command opens your browser to sign in.

Any other client

Give it the URL. A client that supports MCP authorization finds everything else itself: the server publishes its OAuth metadata at https://mcp.formalogic.io/.well-known/oauth-protected-resource/mcp and supports dynamic client registration, so there is nothing to pre-register.

Confirm it worked

Ask your agent:

Use forma_status and tell me which Forma account this session is signed in as.

It should answer with an organisation id and a plan. Nothing but a live, authenticated connection can return that — list_oracles answers identically for every caller, so it cannot tell you whose account you are on.

the browser never opens Your client needs a restart after adding the server, or it does not support MCP authorization yet. Use an API key below
"this account has no Forma organisation yet" You signed in with an account that has never opened the console. Sign in to the console once, then connect again
the tools do not appear Most clients start MCP servers once, at launch. Restart it

With an API key instead

For a client that cannot do OAuth, or for scripts and CI, send an API key as a bearer token. Create one on the API keys page — it is shown once.

Claude Code with a key

Two commands, so the key is never on a command line:

bash
read -rs -p 'Forma API key: ' FORMA_KEY
bash
claude mcp add --transport http forma https://mcp.formalogic.io/mcp \
  --header "Authorization: Bearer $FORMA_KEY"

Pasting the key into the command itself would work, and would also write it verbatim into your shell history — persisted, often synced with your dotfiles, and readable by anything running as you. read -rs takes it from the terminal instead: not echoed, not recorded. (claude mcp add still stores the header in ~/.claude.json; that part is inherent to configuring a client.)

Check it registered:

bash
claude mcp list

forma should read ✔ Connected.

Claude Desktop with a key

Settings → Developer → Edit Config, then add to claude_desktop_config.json:

json
{
  "mcpServers": {
    "forma": {
      "type": "http",
      "url": "https://mcp.formalogic.io/mcp",
      "headers": {
        "Authorization": "Bearer fk_live_…"
      }
    }
  }
}

Restart Claude Desktop afterwards. MCP servers are started once, at launch.

Cursor with a key

Add to .cursor/mcp.json in your project, or ~/.cursor/mcp.json for every project:

json
{
  "mcpServers": {
    "forma": {
      "url": "https://mcp.formalogic.io/mcp",
      "headers": {
        "Authorization": "Bearer fk_live_…"
      }
    }
  }
}

VS Code with a key

Add to .vscode/mcp.json:

json
{
  "servers": {
    "forma": {
      "type": "http",
      "url": "https://mcp.formalogic.io/mcp",
      "headers": {
        "Authorization": "Bearer fk_live_…"
      }
    }
  }
}

Windsurf with a key

Add to ~/.codeium/windsurf/mcp_config.json:

json
{
  "mcpServers": {
    "forma": {
      "serverUrl": "https://mcp.formalogic.io/mcp",
      "headers": {
        "Authorization": "Bearer fk_live_…"
      }
    }
  }
}

Codex with a key

bash
read -rs -p 'Forma API key: ' FORMA_KEY
bash
codex mcp add forma --url https://mcp.formalogic.io/mcp \
  --header "Authorization: Bearer $FORMA_KEY"

Same reason as Claude Code above — the key stays out of your shell history.

Any other client with a key

The server speaks streamable HTTP. Give your client the URL and one header:

text
POST https://mcp.formalogic.io/mcp
Authorization: Bearer fk_live_…

Everything is behind that header — initialize and tools/list included, so an unauthenticated caller cannot enumerate what the server does. The one open route is /healthz, which answers {"ok": true} and nothing else.

If your client cannot send a header, it cannot connect yet — every route except /healthz is behind that header.

With a key, a 401 means the header is missing or the key is wrong; KEY_REVOKED and KEY_EXPIRED say which. A 403 ORG_DISABLED means the key is fine and its organisation is not active — see Authentication.

A note on these instructions

Claude Code is the only client tested end to end against this server, with OAuth and with a key. The other clients follow each vendor's published MCP configuration as of 2026-09-28 — the shape is right, but their settings screens move, and if one of these is wrong we would rather you told us than assumed it was you.