Connect OpenClaw
OpenClaw runs agents for you: several of them inside one Gateway, on heartbeats and schedules, talking to you over chat. We run it too. Pixelite, the company behind Permaura, is moving its own WordPress plugin business onto an OpenClaw instance, and this page is the setup we are putting in place, written down as we go.
OpenClaw connects to MCP servers natively over Streamable HTTP, so there is no bridge to install. One entry in OpenClaw's config and one code from the console, and the connections on your gateway become tools its agents can call, while the keys behind them stay on your gateway.
The OpenClaw details on this page come from the OpenClaw 2026.10.4 documentation. OpenClaw releases often, so if a field is refused on your version, its MCP guide has the current shape, and openclaw mcp doctor says what it disagrees with.
OpenClaw calls its runtime the Gateway as well. On this page, "your gateway" is Permaura's and "the OpenClaw Gateway" is OpenClaw's.
Before you start
- A Permaura gateway OpenClaw can reach. OpenClaw usually runs on a server, and a server cannot reach a gateway on your laptop's loopback address. A hosted gateway already has a public URL; one you run yourself needs remote access. If OpenClaw runs on the same machine as a gateway you run yourself, and not inside a container,
http://127.0.0.1:7376/mcpworks. - Admin access to OpenClaw's config: the file
~/.openclaw/openclaw.jsonon the machine running the OpenClaw Gateway, or Settings → MCP in its Control UI.
1. Mint a code for the agent
OpenClaw reads its MCP servers from config, so it connects the way any config-file client does: it sends a one-time code as its bearer token and arrives Pending for you to approve. In the console, open Agents → Connect agent, then:
- Type a name in Agent name, such as
OpenClaw. The code carries it, so the agent's row, every approval it asks for and its audit entries show that name from the first call. If several OpenClaw agents will each get an identity of their own, mint one code per agent and name each one; see One identity per OpenClaw agent. - Copy the MCP server URL.
- Copy the code from the Authorization header: the part after
Bearer.
The code is single-use and lives 15 minutes, so have OpenClaw connect within that window (step 4). Once redeemed, it is the agent's own token for as long as the agent is in use, and lapses after 30 days with no calls.
OpenClaw can also sign in to an HTTP MCP server with OAuth (auth: "oauth", then openclaw mcp login), and a gateway with a public address offers a Permaura sign-in to clients that can do that. We have not tested that route with OpenClaw yet, so this page uses the code, which works on every gateway.
2. Store the code where OpenClaw keeps secrets
OpenClaw loads ~/.openclaw/.env itself and substitutes ${VAR} references in any config string, so the code can live there rather than in openclaw.json. On the machine running the OpenClaw Gateway, run this and paste the code at its hidden prompt:
(umask 077 && touch ~/.openclaw/.env && chmod 600 ~/.openclaw/.env && IFS= read -rs T && printf 'PERMAURA_AGENT_TOKEN=%s\n' "$T" >> ~/.openclaw/.env)
The file stays readable only by your account, and the code stays out of your shell history and out of any config you commit or back up. Restart the OpenClaw Gateway afterward so it has the new variable. If the variable is missing when OpenClaw reads its config, the reference stays unresolved and OpenClaw logs a warning.
If the OpenClaw Gateway runs in a container, put the line in the .env of the config directory that container uses.
3. Add Permaura as an MCP server
Add a permaura entry under mcp.servers in ~/.openclaw/openclaw.json, alongside any servers already there:
{
mcp: {
servers: {
permaura: {
url: "https://your-gateway.permaura.app/mcp",
transport: "streamable-http",
headers: {
Authorization: "Bearer ${PERMAURA_AGENT_TOKEN}",
},
},
},
},
}
Replace the example URL with your gateway's. Keep transport: "streamable-http": without it OpenClaw assumes SSE, and Permaura's endpoint is Streamable HTTP. The OpenClaw Gateway watches its config file and applies the change without a restart.
You can do the same from the Control UI: Settings → MCP → Add server, name it permaura, choose Streamable HTTP and paste the URL, then add the Authorization header in the scoped config editor on the same page. Or from a terminal, with the OpenClaw Gateway stopped, since OpenClaw's CLI will not edit saved servers while a Gateway owns its state:
openclaw mcp set permaura '{"url":"https://your-gateway.permaura.app/mcp","transport":"streamable-http","headers":{"Authorization":"Bearer ${PERMAURA_AGENT_TOKEN}"}}'
The single quotes stop your shell from expanding ${PERMAURA_AGENT_TOKEN}, so OpenClaw saves the reference and not the code.
4. Connect, then approve the agent
Make OpenClaw connect once, within the code's 15 minutes. With the OpenClaw Gateway stopped, openclaw mcp doctor permaura --probe checks the definition and then opens a live connection. With it running, start a new chat session: a session lists its servers' tools when it starts.
That first request redeems the code, and the agent appears as Pending on the Agents page. The console bell counts it, and on a hosted gateway, or one you run that is linked to your account, your phone hears about it too. Approve it there. If your gateway asks a paired device to confirm agent approvals, the phone asks for that as well.
Approved but with no grant, the agent sees only Permaura's own tools, the ones named permaura_…: listing what it may call, checking on an approval, explaining a refusal. A connection's tools appear once a grant points the agent at them. Check your Default grant before you approve: every approved agent inherits it, so whatever it allows, the OpenClaw agent can do from its first call. OpenClaw lists every tool under its server's name, so in OpenClaw they all start permaura__.
5. Grant something, and make one call wait
Permaura is deny-by-default, so the agent can do nothing yet. Run the whole loop once with something harmless before real work depends on it:
- Pick an action that asks for approval on a connection you already have, such as GitHub's
issues.createon a scratch repository, and switch it on from the connection page. - In Control → Policies, create a policy for that connection with its reads under Allow and
issues.createunder Needs approval. - In Control → Grants, grant that policy to the OpenClaw agent.
- Start a new OpenClaw session. Permaura does not tell clients that their tool list changed, and an OpenClaw session keeps the tool list it started with, so a session from before the grant will not see the new tools.
- Ask the agent to open a test issue.
The call neither fails nor hangs. The tool answers at once with status: pending, an approval_id and a plain description of the action, and the request lands in Control → Approvals and on your phone, showing the agent, the action, the connection and the exact arguments. Approve it and the gateway makes the call with the key it holds; the agent collects the result with permaura_get_approval_status. Deny it and that is what the agent reads instead. A held call does not expire on its own, so an ignored one waits until somebody decides it.
OpenClaw agents often work on a heartbeat, so the one that asked may not be around when you approve. A line in the agent's workspace AGENTS.md, which OpenClaw loads at the start of every session, covers it: "When a Permaura tool returns status: pending, note the approval_id and check it with permaura_get_approval_status on your next heartbeat. Do not repeat the call: a repeat is a second request for approval."
One identity per OpenClaw agent
Every agent in an OpenClaw Gateway shares what is under mcp.servers, so the setup above gives all of them one Permaura identity: one set of grants, one name in the audit log. That suits a single assistant. If you run a team, say one agent that reads the support inbox and another that publishes, give each its own identity, so Permaura's grants decide what each one may do and every approval names which one asked.
- Mint one code per agent in Agents → Connect agent, each with its own Agent name, and store each in its own variable in
~/.openclaw/.env. - Add one server per agent, and deny each agent the servers that are not its own:
{
mcp: {
servers: {
"permaura-support": {
url: "https://your-gateway.permaura.app/mcp",
transport: "streamable-http",
headers: { Authorization: "Bearer ${PERMAURA_TOKEN_SUPPORT}" },
},
"permaura-publisher": {
url: "https://your-gateway.permaura.app/mcp",
transport: "streamable-http",
headers: { Authorization: "Bearer ${PERMAURA_TOKEN_PUBLISHER}" },
},
},
},
agents: {
entries: {
support: { tools: { deny: ["permaura-publisher__*"] } },
publisher: { tools: { deny: ["permaura-support__*"] } },
},
},
}
- Approve each agent on the Agents page and grant each only what its job needs.
OpenClaw drops a server an agent is wholly denied before connecting it, so the support agent never even lists the publisher's tools. Be clear about what that separation is, though: every token sits in the same OpenClaw Gateway's environment, and an agent whose shell can reach that environment could read a sibling's token. OpenClaw's sandbox, which is off by default, moves agents' tool execution out of the Gateway process, and its own docs call it a real limit rather than a perfect boundary. What caps the damage is on Permaura's side: a token can do only what its agent's grants allow, every held action still waits for your phone, and removing the agent on the Agents page ends its token at once.
What Permaura governs here, and what it does not
Permaura sees every call made through its MCP tools, and nothing else.
Governed: connector calls through your gateway. The key stays sealed on the gateway and the agent gets results, never the key. The host is pinned, only listed parameters travel, and responses are redacted per connector. Policies, grants, budgets, approvals and the connection's kill switch all apply, and every decision gets a signed audit entry.
Not governed:
- OpenClaw's own tools: its shell and exec, file tools, browser, and whatever a skill does. Those run inside OpenClaw with the access OpenClaw gives them, and its tool policy and sandbox are where you limit them.
- Chat channels OpenClaw is connected to directly, the model provider keys OpenClaw thinks with, and other MCP servers in its config.
- Any key the agent can already reach. If a GitHub token is still in OpenClaw's environment, an agent with a shell can use it with
curland never touch Permaura. Putting a service behind Permaura means moving its key: add the connection, take the key out of OpenClaw, and rotate it, since it has already lived in that environment and in any backup of it. - The Permaura token itself. It is a credential OpenClaw holds, and anything that can read it can act as that agent, within that agent's grants.
OpenClaw has approval settings of its own for tool calls. Those run before a call leaves OpenClaw. Permaura's run at the gateway, so an action you put under Needs approval waits for you however OpenClaw is configured, and OpenClaw cannot answer it on your behalf.
Worked example: Pixelite's planned setup
This is the setup Pixelite is putting in place on its own OpenClaw instance, written before it went live. We will update this section with what changed once it has run for a while.
Pixelite makes Events Manager, a WordPress plugin for events and bookings, and sells Events Manager Pro. Its OpenClaw instance runs a small team of agents, and each gets its own Permaura identity as described above. Every connection starts the same way: reads allowed, and anything that writes, sends or touches money held for a phone approval.
| System | Connection | Runs without asking | Waits for a phone approval |
|---|---|---|---|
| The Events Manager site | WordPress with the Abilities API | Events Manager and Events Manager Pro reads: events, locations, bookings, availability, coupons, transactions | Every write: events and tickets, any booking change, coupons, RSVPs and forms |
| The plugin repositories | GitHub | Repositories, issues, pull requests, commits | Opening an issue or a pull request, merging; deleting a repository stays denied |
| The support mailbox | Gmail | Listing and reading messages, threads and labels | Sending; trash and delete stay denied |
| Subreddits, posts, comments, search, the account's inbox | Posting, commenting, editing, deleting, private messages | ||
| The mailing list | Mailchimp | Audiences, campaigns and reports, with addresses redacted | Adding or updating a member, sending a campaign |
| Events Manager Pro sales | Braintree | Nothing | Every call, reads included |
A few things that table hides:
- The site's abilities are reviewed. Events Manager 7.3 and Events Manager Pro 3.8.1 register their actions as WordPress abilities, and Permaura has reviewed them, so the reads arrive on without an approval each. Booking changes ask on every call in any case, because they reach a real attendee.
- GitHub does not push code. The connector reads and opens issues and pull requests; it has no action that pushes a commit. The agent that writes code pushes to its own branches with a deploy key OpenClaw holds, which Permaura does not see, and merging stays a human decision.
- Mail arrives unredacted. The Gmail connector redacts nothing, because reading the mail is the job. An inbox is also the most untrusted input the team has, so the agent that reads it holds nothing that writes anywhere else.
- Every Braintree call asks. The connector has one capability, a GraphQL document, and a lookup and a refund are the same request. Until Permaura can scope GraphQL operations one by one, every sales question waits for a tap, and we think that is the right trade.
- The researcher stays outside. The agent that researches with OpenClaw's browser gets Reddit's reads and nothing else through Permaura. Its browsing is OpenClaw's to govern.
If OpenClaw shows no Permaura tools
- Run the probe. With the OpenClaw Gateway stopped,
openclaw mcp doctor permaura --probe. If it reportsauthentication refused (401), the code expired before its first use or the variable did not resolve: mint a fresh one with Refresh in the console and replace the value in~/.openclaw/.env. - Only
permaura_…tools. The agent is still Pending, has no grant, or the session started before the grant. Approve it, grant it, and start a new session. - Tools in one chat but not in a channel's. Channel sessions are often sandboxed, and OpenClaw's sandbox has a tool allowlist of its own: add
bundle-mcp, orpermaura__*for this server alone, totools.sandbox.tools.alsoAllow. Theminimaltool profile hides MCP tools too;codingandmessagingshow them. - Every call refused. Permaura is deny-by-default; Troubleshooting walks through grants, switched-off capabilities and kill switches.