Invoke Tools via Gateway HTTP Endpoint

Learn how to directly invoke a single tool using the Gateway HTTP endpoint. This guide covers authentication modes and request details for developers.

Read this when

  • Calling tools without running a full agent turn
  • Building automations that need tool policy enforcement

OpenClaw's Gateway provides an HTTP endpoint for directly invoking a single tool. This endpoint is always active and relies on Gateway authentication combined with tool policy. Much like the OpenAI compatible /v1/* surface, shared-secret bearer authentication is regarded as trusted operator access for the entire gateway.

  • POST /tools/invoke
  • Operates on the same port as the Gateway (WS + HTTP multiplex): http://<gateway-host>:<port>/tools/invoke
  • Default maximum request body size: 2 MB

Authentication

Applies the Gateway authentication configuration.

Standard HTTP authentication paths include:

  • shared-secret authentication (gateway.auth.mode="token" or "password"): Authorization: Bearer <token-or-password>
  • trusted identity-bearing HTTP authentication (gateway.auth.mode="trusted-proxy"): route traffic through the configured identity-aware proxy and have it insert the necessary identity headers
  • private-ingress open authentication (gateway.auth.mode="none"): no authentication header is needed

Additional notes:

  • mode="token" uses gateway.auth.token (or OPENCLAW_GATEWAY_TOKEN).
  • mode="password" uses gateway.auth.password (or OPENCLAW_GATEWAY_PASSWORD).
  • mode="trusted-proxy" requires the HTTP request to originate from a configured trusted proxy source; same-host loopback proxies require explicit gateway.auth.trustedProxy.allowLoopback = true.
  • Internal callers on the same host that bypass the proxy can rely on gateway.auth.password / OPENCLAW_GATEWAY_PASSWORD as a local direct fallback. Any evidence of Forwarded, X-Forwarded-*, or X-Real-IP headers keeps the request on the trusted-proxy path instead.
  • When gateway.auth.rateLimit is configured and authentication failures exceed the limit, the endpoint responds with 429 and Retry-After.

Security boundary (important)

Consider this endpoint a full operator-access surface for the gateway instance.

  • HTTP bearer authentication here does not follow a narrow per-user scope model.
  • A valid Gateway token or password for this endpoint should be handled like an owner or operator credential.
  • For shared-secret authentication modes (token and password), the endpoint restores the full operator defaults even when the caller provides a narrower x-openclaw-scopes header.
  • Shared-secret authentication also treats direct tool invocations on this endpoint as owner-sender turns.
  • Trusted identity-bearing HTTP modes (trusted proxy authentication, or gateway.auth.mode="none" on a private ingress) respect x-openclaw-scopes when it is present and otherwise default to the normal operator scope set.
  • Keep this endpoint on loopback, tailnet, or private ingress only; do not expose it directly to the public internet.

Authentication matrix:

Auth modeBehavior
token or password + Authorization: Bearer ...Demonstrates possession of the shared gateway operator secret. Ignores a narrower x-openclaw-scopes. Restores the complete default operator scope set: operator.admin, operator.approvals, operator.pairing, operator.read, operator.talk.secrets, operator.write. Treats direct tool invocations as owner-sender turns.
Trusted identity-bearing HTTP (trusted proxy authentication, or mode="none" on private ingress)Authenticates an external trusted identity or deployment boundary. Honors x-openclaw-scopes when it is present. Falls back to the standard operator default scope set when the header is absent. Only loses owner semantics when the caller explicitly narrows scopes and omits operator.admin.

Request body

{
  "tool": "sessions_list",
  "action": "json",
  "args": {},
  "sessionKey": "main",
  "dryRun": false
}

Fields:

  • tool / name (string, required): the name of the tool to call. If both are provided, name takes priority.
  • action (string, optional): inserted into args.action when the tool schema includes an action property and args has not already defined one.
  • args (object, optional): arguments specific to the tool.
  • sessionKey (string, optional): the target session key. When omitted or set to "main", the Gateway uses the configured main session key (respecting session.mainKey and the default agent, or global in global session scope).
  • agentId (string, optional): resolves the session key for that agent. Returns error 400 if it clashes with an explicit sessionKey already mapped to a different agent.
  • idempotencyKey (string, optional): used to generate a stable tool-call identifier for this invocation.
  • dryRun (boolean, optional): reserved for later use; currently disregarded.

Policy + routing behavior

Tool availability is governed by the same policy chain that applies to Gateway agents:

  • tools.profile / tools.byProvider.profile
  • tools.allow / tools.byProvider.allow
  • agents.<id>.tools.allow / agents.<id>.tools.byProvider.allow
  • group policies (when the session key points to a group or channel)
  • subagent policy (when using a subagent session key for invocation)

A tool blocked by policy causes the endpoint to return 404.

Key boundary notes:

  • Execution approvals act as operator safeguards, not an extra authorization layer for this HTTP endpoint. When a tool is accessible here through Gateway authentication and tool policy, /tools/invoke does not introduce an additional approval prompt per call.
  • If exec is reachable here, treat it as a mutating shell surface. Blocking write, edit, apply_patch, or HTTP filesystem-write tools does not make shell execution read-only.
  • Never share Gateway bearer credentials with untrusted callers. To separate trust boundaries, run independent gateways (preferably on different OS users or hosts).

Gateway HTTP also enforces a hard deny list by default (even when session policy permits the tool):

ToolReason
execDirect command execution (RCE surface)
spawnArbitrary child process creation (RCE surface)
shellShell command execution (RCE surface)
fs_writeArbitrary file mutation on the host
fs_deleteArbitrary file deletion on the host
fs_moveArbitrary file move/rename on the host
apply_patchPatch application can rewrite arbitrary files
sessions_spawnSession orchestration; spawning agents remotely is RCE
sessions_sendCross-session message injection
cronPersistent automation control plane
gatewayGateway control plane; prevents reconfiguration via HTTP
nodesNode command relay can reach system.run on paired hosts

cron, gateway, and nodes are also owner-only: even outside this default deny list, non-owner callers cannot invoke them on this surface.

Customize the general deny list using gateway.tools:

{
  gateway: {
    tools: {
      // Additional tools to block over HTTP /tools/invoke
      deny: ["browser"],
      // Remove tools from the default deny list for owner/admin callers
      allow: ["gateway"],
    },
  },
}

gateway.tools.allow is an exposure override, not a scope upgrade. In identity-bearing HTTP modes, cron, gateway, and nodes remain inaccessible to callers without owner or admin identity (operator.admin), even when included in gateway.tools.allow. Shared-secret bearer auth continues to follow the full trusted-operator rule described above.

To assist group policies with context resolution, you can optionally set:

  • x-openclaw-message-channel: <channel> (example: slack, telegram)
  • x-openclaw-account-id: <accountId> (when multiple accounts are present)
  • x-openclaw-message-to: <target> (delivery target for message-tool policy)
  • x-openclaw-thread-id: <threadId> (thread context for message-tool policy)

Responses

StatusMeaning
200{ ok: true, result }
400{ ok: false, error: { type, message } } (bad request or tool input is wrong)
401Not authorized
403{ ok: false, error: { type, message, requiresApproval? } } (policy prevented the tool call)
404Tool unavailable (could not be found or is not allowlisted)
405HTTP method not permitted
408Reading the request body timed out
413Request body went over the maximum allowed size
429Auth rate cap reached (Retry-After applied)
500{ ok: false, error: { type, message } } (unexpected tool failure; message cleaned up)

Example

curl -sS http://127.0.0.1:18789/tools/invoke \
  -H 'Authorization: Bearer secret' \
  -H 'Content-Type: application/json' \
  -d '{
    "tool": "sessions_list",
    "action": "json",
    "args": {}
  }'
1,235 words · updated Jul 27, 2026