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"usesgateway.auth.token(orOPENCLAW_GATEWAY_TOKEN).mode="password"usesgateway.auth.password(orOPENCLAW_GATEWAY_PASSWORD).mode="trusted-proxy"requires the HTTP request to originate from a configured trusted proxy source; same-host loopback proxies require explicitgateway.auth.trustedProxy.allowLoopback = true.- Internal callers on the same host that bypass the proxy can rely on
gateway.auth.password/OPENCLAW_GATEWAY_PASSWORDas a local direct fallback. Any evidence ofForwarded,X-Forwarded-*, orX-Real-IPheaders keeps the request on the trusted-proxy path instead. - When
gateway.auth.rateLimitis configured and authentication failures exceed the limit, the endpoint responds with429andRetry-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 (
tokenandpassword), the endpoint restores the full operator defaults even when the caller provides a narrowerx-openclaw-scopesheader. - 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) respectx-openclaw-scopeswhen 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 mode | Behavior |
|---|---|
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,nametakes priority.action(string, optional): inserted intoargs.actionwhen the tool schema includes anactionproperty andargshas 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 (respectingsession.mainKeyand the default agent, orglobalin global session scope).agentId(string, optional): resolves the session key for that agent. Returns error400if it clashes with an explicitsessionKeyalready 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.profiletools.allow/tools.byProvider.allowagents.<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/invokedoes not introduce an additional approval prompt per call. - If
execis reachable here, treat it as a mutating shell surface. Blockingwrite,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):
| Tool | Reason |
|---|---|
exec | Direct command execution (RCE surface) |
spawn | Arbitrary child process creation (RCE surface) |
shell | Shell command execution (RCE surface) |
fs_write | Arbitrary file mutation on the host |
fs_delete | Arbitrary file deletion on the host |
fs_move | Arbitrary file move/rename on the host |
apply_patch | Patch application can rewrite arbitrary files |
sessions_spawn | Session orchestration; spawning agents remotely is RCE |
sessions_send | Cross-session message injection |
cron | Persistent automation control plane |
gateway | Gateway control plane; prevents reconfiguration via HTTP |
nodes | Node 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
| Status | Meaning |
|---|---|
200 | { ok: true, result } |
400 | { ok: false, error: { type, message } } (bad request or tool input is wrong) |
401 | Not authorized |
403 | { ok: false, error: { type, message, requiresApproval? } } (policy prevented the tool call) |
404 | Tool unavailable (could not be found or is not allowlisted) |
405 | HTTP method not permitted |
408 | Reading the request body timed out |
413 | Request body went over the maximum allowed size |
429 | Auth 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": {}
}'