Summary
For a Claude CLI (claude-cli) backed agent, a config hot reload (e.g. tools.agentToAgent.allow or agents.defaults.contextInjection) rotates the loopback MCP client grants but does not invalidate the agent's resumable CLI session. From the next turn on, the resumed Claude session reconnects to the openclaw loopback MCP server with its previously cached bearer header, gets HTTP 401 {"error":"unauthorized"}, and every mcp__openclaw__* tool is unavailable for that session — on every subsequent turn, and also after gateway restarts. Fresh sessions are unaffected.
Environment
- OpenClaw 2026.9.2 (3928bad), Ubuntu 26.04, node v26.8.1
- Agent runtime:
claude-cli (Claude Code), main Telegram session, long-lived and resumed across turns
Timeline (from the gateway journal and the Claude session file)
- 15:07:59 — turn runs with
useResume=true reuse=reusable; mcp__openclaw__* tools work (called agents_list).
- 15:10:06 —
[reload] config hot reload applied (tools.agentToAgent.allow)
- 15:12:31 —
[reload] config hot reload applied (agents.defaults.contextInjection)
- 15:27:41 — next turn:
cli exec … useResume=true … reuse=reusable (no invalidation). Claude Code reports for server openclaw: AUTH_HEADER_REJECTED: Server rejected the configured Authorization header (HTTP 401) … OAuth fallback is disabled when headers.Authorization is set … { error : unauthorized }. First AUTH_HEADER_REJECTED record in the session's .jsonl is exactly this turn.
- Every later turn of that session (15:51, 16:12 — the last one after a full gateway restart at 16:11) shows the same 401. Meanwhile new sessions of other agents call OpenClaw MCP tools normally.
What I verified
- The current run's grant is valid: taking
OPENCLAW_MCP_TOKEN and OPENCLAW_MCP_CLI_CAPTURE_KEY from /proc/<claude pid>/environ and POSTing initialize to the URL in that run's --mcp-config (http://127.0.0.1:<port>/mcp) returns HTTP 200 with serverInfo.name = "openclaw". So the server side and the freshly minted grant are fine; the rejected header is the one Claude Code re-uses for the resumed session.
- A change to
mcp.servers does invalidate reuse (reuse=invalidated:mcp in the log). The two config keys above do not, although the loopback grants issued to the running session no longer resolve afterwards (resolveMcpLoopbackClientGrant → 401).
mcpResumeHash canonicalises the loopback URL and the ${OPENCLAW_MCP_*} templates, so it is unchanged by a grant rotation — which is presumably why reuse stays "reusable".
Expected
Either (a) a hot reload that rotates/revokes loopback client grants invalidates CLI session reuse (like mcp.servers changes do, reason=mcp), or (b) the resumed session is re-seeded with the new grant so Claude Code's cached openclaw server header stays valid.
Workaround
/new on the affected session (fresh CLI session → fresh grant). Gateway restarts do not help.
Summary
For a Claude CLI (
claude-cli) backed agent, a config hot reload (e.g.tools.agentToAgent.alloworagents.defaults.contextInjection) rotates the loopback MCP client grants but does not invalidate the agent's resumable CLI session. From the next turn on, the resumed Claude session reconnects to theopenclawloopback MCP server with its previously cached bearer header, gets HTTP 401{"error":"unauthorized"}, and everymcp__openclaw__*tool is unavailable for that session — on every subsequent turn, and also after gateway restarts. Fresh sessions are unaffected.Environment
claude-cli(Claude Code), main Telegram session, long-lived and resumed across turnsTimeline (from the gateway journal and the Claude session file)
useResume=true reuse=reusable;mcp__openclaw__*tools work (calledagents_list).[reload] config hot reload applied (tools.agentToAgent.allow)[reload] config hot reload applied (agents.defaults.contextInjection)cli exec … useResume=true … reuse=reusable(no invalidation). Claude Code reports for serveropenclaw:AUTH_HEADER_REJECTED: Server rejected the configured Authorization header (HTTP 401) … OAuth fallback is disabled when headers.Authorization is set … { error : unauthorized }. FirstAUTH_HEADER_REJECTEDrecord in the session's.jsonlis exactly this turn.What I verified
OPENCLAW_MCP_TOKENandOPENCLAW_MCP_CLI_CAPTURE_KEYfrom/proc/<claude pid>/environand POSTinginitializeto the URL in that run's--mcp-config(http://127.0.0.1:<port>/mcp) returns HTTP 200 withserverInfo.name = "openclaw". So the server side and the freshly minted grant are fine; the rejected header is the one Claude Code re-uses for the resumed session.mcp.serversdoes invalidate reuse (reuse=invalidated:mcpin the log). The two config keys above do not, although the loopback grants issued to the running session no longer resolve afterwards (resolveMcpLoopbackClientGrant→ 401).mcpResumeHashcanonicalises the loopback URL and the${OPENCLAW_MCP_*}templates, so it is unchanged by a grant rotation — which is presumably why reuse stays "reusable".Expected
Either (a) a hot reload that rotates/revokes loopback client grants invalidates CLI session reuse (like
mcp.serverschanges do,reason=mcp), or (b) the resumed session is re-seeded with the new grant so Claude Code's cachedopenclawserver header stays valid.Workaround
/newon the affected session (fresh CLI session → fresh grant). Gateway restarts do not help.