Blog

OpenClaw MCP setup: a remote server with a Bearer header

Aperisa ยท 9 min read

Leave one line out of an OpenClaw MCP config, transport: "streamable-http", and OpenClaw connects to your server over SSE instead. The transports page says so directly: when transport is omitted, "OpenClaw uses sse."

That is the kind of detail the conflicting guides skip. The short answer for OpenClaw MCP setup with a remote server and a Bearer header: define it under mcp.servers in ~/.openclaw/openclaw.json, set transport: "streamable-http", write the token as an environment reference in headers.Authorization, and run OpenClaw 2026.6.5 or later. Not mcpServers, and no mcporter. Our view: a dated config beats five undated guides, so check the version on anything you copy, this post included.

Checked on 2026-10-27 against the OpenClaw docs and release notes through 2026.10.9, the release GitHub marks Latest (checked October 29, 2026). We haven't run these steps on a live OpenClaw install, so the config and commands come from the docs and source, not a test. If you need the basics first, start with what an MCP server is.

Which OpenClaw MCP config key is current: mcp.servers, mcpServers or mcporter?

mcp.servers. The three names come from three different places, which is why answer engines blend them.

Name What it is Use it for a remote Bearer server?
mcp.servers OpenClaw's own MCP client registry in openclaw.json Yes
mcpServers The key Cursor and Claude-style JSON files use. Not a key under mcp in openclaw.json. In OpenClaw it shows up in plugin manifests, bundle mcp.json files and the ACPX plugin config No
mcporter A separate CLI with its own registry at config/mcporter.json, available to OpenClaw as a skill Not needed

The release history explains the mix. The 2026.3.31 notes add "remote HTTP/SSE server support for mcp.servers URL configs, including auth headers" (PR #50396). Before that, mcporter was a common route to remote tools, and OpenClaw's QMD memory backend used it too. Guides from early 2026 were describing a real setup. It just isn't the current one.

The CLI docs keep the two registries apart: openclaw mcp list, show, set and unset "do not include mcporter servers from config/mcporter.json; use mcporter list for that registry." A server that only appears in mcporter list is not in mcp.servers.

If you are copying from a Cursor or Claude Code file, take the url and headers and rewrite the entry. OpenClaw accepts the CLI-native type: "http" when it is saved through openclaw mcp set, and openclaw doctor --fix repairs it in existing config (normalization landed in 2026.4.26). The docs still call transport "what embedded OpenClaw consumes directly," so write transport.

What does the current OpenClaw MCP config look like?

In ~/.openclaw/openclaw.json, which is JSON5:

{
  mcp: {
    servers: {
      records: {
        url: "https://your-server.example/mcp",
        transport: "streamable-http",
        headers: {
          Authorization: "Bearer ${MCP_TOKEN}",
        },
        connectionTimeoutMs: 10000,
        requestTimeoutMs: 30000,
        toolFilter: { include: ["search", "read_*"] },
      },
    },
  },
}

A few notes on that block:

  • ${MCP_TOKEN} is OpenClaw's general config substitution. It works in any config string value, but only uppercase names match. Per the docs, "Missing/empty vars stay visibly unresolved, emit a warning."
  • There is no auth key. Leave it out for a Bearer server (more on that below).
  • toolFilter limits which of the server's tools your agents see. It takes tool names and simple * globs.

The same server from the CLI. Use single quotes so your shell doesn't expand the variable before OpenClaw stores it:

openclaw mcp add records \
  --url https://your-server.example/mcp \
  --transport streamable-http \
  --header 'Authorization=Bearer ${MCP_TOKEN}' \
  --include 'search,read_*'

--header takes key=value and repeats. We haven't confirmed that add saves the ${MCP_TOKEN} reference unexpanded, so check the saved entry with openclaw mcp show records. add checks the server before saving, and --no-probe saves without connecting. If you edit the file by hand, the Gateway watches it and applies changes on its own.

Where does OpenClaw read the Bearer token from?

From the Gateway's process environment, plus .env in the working directory and ~/.openclaw/.env. This trips people up when the Gateway runs as a service. The env-vars FAQ: a launchd or systemd Gateway "will not inherit your shell environment." Its fixes are to put the key in ~/.openclaw/.env, set env.shellEnv.enabled: true, or add it to config env. For an MCP token, shellEnv won't help: in the 2026.10.7 source it imports only a fixed list of expected keys (provider, channel and Gateway credentials), and an MCP token isn't on it. Skip the last one for a Bearer token: config env stores the token in plaintext in openclaw.json, the file you were keeping it out of. One caveat on ~/.openclaw/.env: a user comment on #76493 (October 18) reports that its values are inherited by agent exec subprocesses. We haven't verified that.

OpenClaw SecretRef does not currently work for mcp.servers. SecretRef objects (source: "env" | "file" | "exec" | "store") would be the cleaner answer, but the schema for mcp.servers.*.headers takes only a string, number or boolean. Issue #76493 tracks it and is still open, with the latest repro on 2026.10.5 (October 20). The fix, PR #69417, was closed unmerged on October 24, 2026, after it went stale, and the maintainer asked for "a fresh, smaller PR." No fix is close. Use an environment variable through the ${VAR} reference, or a wrapper script that loads the key into the Gateway's environment before it starts. We cover the options, including the OS keychain, in keeping MCP API keys out of plaintext config files.

Why does OpenClaw ignore my Authorization header?

Three causes show up in the docs and issue tracker.

auth: "oauth" is set. From the transports page: "Static Authorization headers are ignored for a server while auth: "oauth" is enabled." openclaw mcp doctor warns about this exact case. Remove auth for a server that takes a static key.

The variable isn't visible to the Gateway. The 401 shows up in the startup log and catalog diagnostic as authentication refused (401) next to the server name. Header values stay redacted, so check the environment the Gateway runs in, not your terminal.

The header comes from a plugin manifest, not mcp.servers. Issue #184192, opened October 26 against 2026.10.7, reports a native plugin sending Bearer ${POSTHOG_MCP_TOKEN} literally. Core mcp.servers resolves references at config load; issue #70901 was closed as implemented in April.

One more you may hit: on 2026.10.3, openclaw mcp doctor reported an env-backed header as a "literal sensitive value" whenever the variable was set (#171469). The fix (PR #171737, merged October 14) is in 2026.10.10-beta.1, whose notes list "stop flagging env-backed headers as secrets." It is not in 2026.10.7, so on 2026.10.7 and earlier you'll still see the warning. There, it is the bug, not your config.

Which OpenClaw version do you need for a Bearer header?

2026.6.5 or later. Two advisories set that floor. The first, CVE-2026-53840 (GHSA-rjxq-qqhf-8hwh, published May 28, 2026) describes it: "OpenClaw before 2026.5.12 contains an information disclosure vulnerability in streamable-http MCP servers that forwards operator-configured custom headers during cross-origin redirects." It applies when sensitive headers sit under mcp.servers.*.headers and the endpoint is malicious, compromised or able to redirect. The 2026.5.12 release notes carry the fix as "Scrub streamable MCP redirect headers" (#80906). The advisory also says to rotate any MCP credentials a redirecting endpoint may have exposed.

There is a second advisory for SSE. CVE-2026-62208 (GHSA-9c3v-684m-579c): OpenClaw "before 2026.6.5 could forward Authorization headers during MCP SSE redirects." Since a server with no transport line uses SSE, this one matters even if you meant to use Streamable HTTP.

So use 2026.6.5 as the single floor. 2026.10.9, the release GitHub marks Latest, clears both. So does 2026.9.36, a gateway-only extended-stable release published October 29.

How do you check the server before an agent uses it?

openclaw mcp status --verbose          # config only, starts nothing
openclaw mcp doctor records            # static checks
openclaw mcp doctor records --probe    # live connection, lists tools

The docs are clear that a saved definition doesn't prove the server answers. Run the probe. list --json and show replace header values with __OPENCLAW_REDACTED__, so their output is safe to paste into an issue. And openclaw mcp reload only refreshes runtimes in the current CLI process. A Gateway running elsewhere needs its own reload or a restart.

Where does Aperisa fit?

Aperisa is a remote MCP server. Your data is available to any harness that connects over Streamable HTTP with a Bearer key: OpenClaw, Hermes, Cursor, Codex, Antigravity, n8n or your own code. Give each agent its own key and set what it can reach: which data areas, work or personal, and how much detail, from full records down to totals only. Aperisa enforces those limits on the server.

The config that holds today

One mcp.servers entry, transport: "streamable-http" written out, the token as ${MCP_TOKEN}, no auth key, and a version at or past 2026.6.5. Then probe it. If you are wiring the same agent to an inbox, see OpenClaw Gmail read-only. For what it should remember versus look up, see OpenClaw memory.

Aperisa connects as a remote MCP server over Streamable HTTP with a Bearer key, and each key can be limited by data area and level of detail. Try it out.

FAQ

Does OpenClaw support remote MCP servers natively? Yes. Since the 2026.3.31 release, mcp.servers accepts URL configs for remote HTTP and SSE servers, including auth headers. You do not need mcporter for a remote server with a Bearer header.

Should I use mcp.servers or mcpServers in OpenClaw? mcp.servers in ~/.openclaw/openclaw.json. mcpServers is the key Cursor and Claude-style files use. It is not a key under mcp in openclaw.json. In OpenClaw it shows up in other places, such as plugin manifests, bundle mcp.json files and the ACPX plugin config.

Which OpenClaw version should I run with a Bearer header? 2026.6.5 or later. Versions before 2026.5.12 could forward custom headers on a Streamable HTTP redirect (CVE-2026-53840), and versions before 2026.6.5 could forward Authorization headers on an SSE redirect (CVE-2026-62208). A server config without a transport line uses SSE, so 2026.6.5 is the one floor to use.

Why is my OpenClaw Authorization header ignored? The usual cause is auth: "oauth" on the same server. The docs say static Authorization headers are ignored while OAuth is enabled. The other common cause is a token variable the Gateway process cannot see.

Sources

Questions

Does OpenClaw support remote MCP servers natively?

Yes. Since the 2026.3.31 release, mcp.servers accepts URL configs for remote HTTP and SSE servers, including auth headers. You do not need mcporter for a remote server with a Bearer header.

Should I use mcp.servers or mcpServers in OpenClaw?

mcp.servers in ~/.openclaw/openclaw.json. mcpServers is the key Cursor and Claude-style files use. It is not a key under mcp in openclaw.json. In OpenClaw it shows up in other places, such as plugin manifests, bundle mcp.json files and the ACPX plugin config.

Which OpenClaw version should I run with a Bearer header?

2026.6.5 or later. Versions before 2026.5.12 could forward custom headers on a Streamable HTTP redirect (CVE-2026-53840), and versions before 2026.6.5 could forward Authorization headers on an SSE redirect (CVE-2026-62208). A server config without a transport line uses SSE, so 2026.6.5 is the one floor to use.

Why is my OpenClaw Authorization header ignored?

The usual cause is auth set to oauth on the same server. The docs say static Authorization headers are ignored while OAuth is enabled. The other common cause is a token variable the Gateway process cannot see.

Published

Keep reading