Skip to main content

Connect your AI client

Permaura speaks MCP (Model Context Protocol), so any MCP client can use it. Step 5 of Getting started covers the flow; this page is the per-client detail.

Everything starts in the console, under Agents → Connect agent. That dialog gives you two values, and every route below is a way of handing one or both to a client:

What it isWhen a client needs it
MCP server URLYour gateway's addressAlways
Authorization headerA one-time setup code, valid 15 minutesWhen the client cannot open a browser sign-in

Which should I use?​

The client decides, not where the gateway runs:

  • A client that can open a browser sign-in (Claude Desktop's Connectors, ChatGPT, claude.ai, Claude Code) needs only the URL. It signs in to Permaura, that sign-in is the credential, and the agent arrives already approved. This needs a gateway with a public address, which a hosted gateway always has and one on your own machine gets from remote access.
  • Anything that cannot (a script, a CI runner, anything driven by curl, a client that only reads a config file) sends the one-time code as its bearer token instead, and arrives Pending for you to approve. This works on any gateway, hosted included.

The code looks like pgc_ENRL-7F3A-9C21-4B8D-E0F1-A2B3-C4D5-E6F7-0819 (eight groups from gateway 1.3.56, four from 1.3.22), is single-use and lives 15 minutes. Once redeemed it is that agent's own token: keep sending the same value. From gateway 1.3.46, a code minted from the console or the Permaura app starts pgc_ENRL-, and the gateway treats the agent it opens as a remote caller wherever it connects from, even over loopback on the same machine; a code minted at the gateway's own machine starts ENRL-. Older gateways issue ENRL- codes everywhere.

A cloud client needs a public URL

ChatGPT, claude.ai and other hosted clients hand your URL to their vendor's servers, which cannot reach a gateway on your own machine. Turn on remote access first, or use a client that runs locally.

Let the agent set itself up​

Copy agent instructions in the dialog puts the whole setup on your clipboard as a two-sentence prompt, carrying whichever URL and code are live at that moment. Paste it into any agent that can edit its own MCP config and it will connect itself. The steps below are for when you would rather do it by hand.

Claude Code​

The dialog provides a command for your operating system. It prompts for the code, keeping it out of shell history and command arguments. On macOS and Linux, paste the generated command into bash or zsh, then paste the code at its hidden prompt:

(umask 077 && mkdir -p ~/.permaura && IFS= read -rs T && printf '{"Authorization":"Bearer %s"}\n' "$T" > ~/.permaura/claude-code-header.json && chmod 600 ~/.permaura/claude-code-header.json) && { claude mcp remove --scope user permaura >/dev/null 2>&1; claude mcp add-json --scope user permaura "{\"type\":\"http\",\"url\":\"https://your-gateway.permaura.app/mcp\",\"headersHelper\":\"cat '$HOME/.permaura/claude-code-header.json'\"}"; }

Replace the example URL with your gateway's MCP URL, or copy the command from the dialog with that URL already filled in. The code is saved in ~/.permaura/claude-code-header.json, readable and writable only by your account. The user-scoped server entry uses headersHelper to read that file whenever Claude Code connects, so it also works from a new terminal or an IDE without the original shell's environment. After enrollment the saved value remains the agent's token; keep the file private.

On Windows, use the dialog's PowerShell or Command Prompt form. Those commands save PERMAURA_AGENT_TOKEN in your user environment and register the server with --scope user. Open a new terminal or restart your IDE afterward: an already-running process does not receive the saved variable. Command Prompt shows the code as you paste it. If the variable is missing, Claude Code sends the literal ${PERMAURA_AGENT_TOKEN} and the gateway refuses it.

Confirm the entry with claude mcp list. Your capabilities appear as tools named after their connection, like db1.uptime.

Claude Code speaks streamable HTTP natively, so there is no bridge process to install. For a public gateway, it can also connect without a code using claude mcp add --transport http permaura https://your-gateway.permaura.app/mcp; it opens a Permaura sign-in in your browser on the first call.

Scripts, CI runners and curl​

Anything that can set an HTTP header can connect with the code. The MCP endpoint is plain JSON-RPC over POST, so a first call from a shell, with the code in PERMAURA_AGENT_TOKEN and the header read from a process substitution so the code is never one of curl's arguments, looks like this:

curl -s https://your-gateway.permaura.app/mcp \
-H @<(printf 'Authorization: Bearer %s\n' "$PERMAURA_AGENT_TOKEN") \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

The -H @<(…) form reads the header from a process substitution, so the token is never one of curl's arguments; it needs bash or zsh, since a POSIX sh does not know <(…).

That first request redeems the code, and the agent appears as Pending on the Agents page. Approve it and grant it what it needs; until then its tool calls are refused.

From then on the code is the agent's token, not a setup step. Store it where the runner keeps its other secrets (a CI secret, not the repository) and send the same value on every call. It stays valid while the agent is in use and lapses after 30 days with no calls; removing the agent on the Agents page ends it immediately. A runner that needs a fresh identity gets a fresh code from Refresh in the dialog, or from Connect an agent in the Permaura iPhone app, which is on the App Store.

Claude Desktop, Cursor, and other config-file clients​

These launch MCP servers as local processes, so they reach a streamable-HTTP gateway through mcp-remote. The dialog builds the block for you:

{
"mcpServers": {
"permaura": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://your-gateway.permaura.app/mcp",
"--header", "Authorization:${AUTH_HEADER}",
"--transport", "http-only"
],
"env": {
"AUTH_HEADER": "Bearer pgc_ENRL-A1B2-C3D4-E5F6-A7B8-C9D0-E1F2-A3B4-C5D6"
}
}
}
}

mcp-remote fills ${AUTH_HEADER} from its environment, so the code is in env, which only your own account can read, rather than in the bridge's arguments, which every local user can read in the process list for as long as the client runs. The dialog's block carries your gateway's real address and a live code in its arguments: copy those two values into this shape. Then restart the client; most only read their MCP config at startup.

Where the file lives differs by client, and the dialog names the exact menu for the one you pick. Claude Desktop keeps it in claude_desktop_config.json under Settings → Developer → Edit Config; Cursor under Settings → MCP; VS Code behind MCP: Open User Configuration in the Command Palette.

Claude Desktop also has the easier route: Settings → Connectors → Add custom connector takes the URL on its own and runs the sign-in for you.

OpenClaw reads its MCP servers from config too, but it speaks Streamable HTTP itself and needs no mcp-remote. Connect OpenClaw has its config block, where to keep the code, and how to give each agent in an OpenClaw team an identity of its own.

ChatGPT and other hosted clients​

  1. If your gateway runs on your own machine, turn on remote access. A hosted gateway already has a public URL.
  2. Copy the MCP server URL from the dialog (https://your-gateway.permaura.app/mcp).
  3. Paste it into the client's Connectors or MCP servers settings.
  4. It sends you to a Permaura sign-in. Approve, and the agent is connected.

No code here: the sign-in is the credential, and there is nowhere to put a header anyway.

After it connects​

  • An agent that signed in through the browser arrives already approved: your sign-in was the approval.
  • An agent that redeemed a code arrives Pending on the Agents page until you click Approve. Permaura tells you it is waiting on the console bell and, on a hosted gateway, on your phone.
  • Either way it can do nothing until a grant allows it. Permaura is deny-by-default, so a freshly connected agent sees only Permaura's own permaura_… tools; a connection's tools appear once a grant points the agent at that connection, and anything the grant does not allow is still refused.
Make every new agent wait

Turn on Require manual approval for new agents at the top of the Agents page and even agents that sign in successfully land as Pending for your explicit OK.

From gateway 1.3.46, new agents wait once a device is paired. On a hosted gateway, or a self-run gateway with a public URL, Require manual approval for new agents turns on by itself when you pair your first approval device, whatever kind it is. A self-run gateway you paired before giving it a public URL turns it on when it restarts with remote access, unless you had already switched it off yourself. From then on, an agent that signs in arrives as Pending and cannot act until you approve it on the Agents page. Agents you approved before pairing keep working. With no device paired, or on a gateway reachable only from its own machine, it stays off and a successful sign-in approves the agent. You can turn it on yourself at any time.

To turn it off, switch off Require manual approval for new agents on the Agents page. From the console or the phone the change goes to your paired device, and the gate switches off only once you approve it there, unless you have lowered the approval floor, in which case it switches off at once. On a hosted gateway or one with a public URL, a choice to switch it off made before any device was paired does not carry over: pairing your first device turns the gate on, and you can switch it off again afterwards. Once a device is paired, your choice sticks: pairing or removing devices no longer changes it. If you remove your last paired device and never made a choice, it goes back to off.

If a client can't see any tools​

Work through Troubleshooting. The usual causes are a client that was not restarted, a setup code that expired before it was used (the dialog counts it down, and Refresh mints a new one), or remote access being on in the console but not yet set on the gateway itself.