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:
https://mcp.formalogic.io/mcpYou 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 on the web and Claude Desktop use the same connector.
- Settings → Connectors → Add custom connector.
- Name it
Formaand paste the URL above. - Click Connect and sign in.
Claude Code
claude mcp add --transport http forma https://mcp.formalogic.io/mcpThen type /mcp in Claude Code, pick forma, and choose Authenticate.
claude mcp list should read forma … ✔ Connected.
ChatGPT
- Settings → Apps & Connectors → Advanced → turn on Developer mode.
- Create a connector named
Formawith the URL above and OAuth authentication. - Sign in when ChatGPT asks.
Cursor
Add to Cursor, or add this to ~/.cursor/mcp.json:
{
"mcpServers": {
"forma": { "url": "https://mcp.formalogic.io/mcp" }
}
}Cursor shows Needs login next to forma. Click it and sign in.
VS Code
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
Add to ~/.codeium/windsurf/mcp_config.json, then sign in when Windsurf asks:
{
"mcpServers": {
"forma": { "serverUrl": "https://mcp.formalogic.io/mcp" }
}
}Codex
codex mcp add forma --url https://mcp.formalogic.io/mcp
codex mcp login formaThe 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:
read -rs -p 'Forma API key: ' FORMA_KEYclaude 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:
claude mcp listforma should read ✔ Connected.
Claude Desktop with a key
Settings → Developer → Edit Config, then add to claude_desktop_config.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:
{
"mcpServers": {
"forma": {
"url": "https://mcp.formalogic.io/mcp",
"headers": {
"Authorization": "Bearer fk_live_…"
}
}
}
}VS Code with a key
Add to .vscode/mcp.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:
{
"mcpServers": {
"forma": {
"serverUrl": "https://mcp.formalogic.io/mcp",
"headers": {
"Authorization": "Bearer fk_live_…"
}
}
}
}Codex with a key
read -rs -p 'Forma API key: ' FORMA_KEYcodex 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:
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.