#Agents in discord have lost the ability to SSH or execute shell

1 messages · Page 1 of 1 (latest)

wild yew
#

Not sure what I’ve done, but for some reason now all my discord agents have lost the ability to perform shell or SSH commands. I’m not quite sure what I need to edit to be able to put them back in.

buoyant grottoBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> âś… Mark Solution

thick gladeBOT
#

This is almost always one of these three things:

  1. Tool policy changed (exec got removed via tools.profile / tools.allow / tools.deny)
  2. Exec host/sandbox mismatch (exec defaults to host=sandbox, but if sandboxing is off it now fails closed)
  3. Exec approvals/allowlist started denying (especially if you’re running host=gateway/node from a sandboxed session)

Can you paste (a) the exact error text your agent says when you ask it to run a command, and (b) your version?

openclaw --version

Then run these and paste output:

openclaw config get tools.profile
#
openclaw config get tools.allow
openclaw config get tools.deny
openclaw config get tools.byProvider
openclaw config get tools.exec.host
openclaw config get agents.defaults.sandbox.mode

The two most common “fix it immediately” cases

A) tools.profile is set to messaging / minimal (or tools.allow doesn’t include runtime tools)
Make sure runtime tools are allowed. exec lives in group:runtime (exec, bash, process).

Config idea (JSON5) — add/append group:runtime:

#
{
  tools: {
    allow: ["group:runtime"],
  },
}

Docs: https://docs.openclaw.ai/tools (see tool profiles + group:runtime)

B) tools.exec.host is sandbox but agents.defaults.sandbox.mode is off
This matches the “worked before, now exec/ssh dead” symptom after an update: exec won’t silently run on the host anymore.

Either enable sandboxing, or set exec to run on the gateway host:

#
{
  tools: {
    exec: { host: "gateway" },
  },
}

Docs: https://docs.openclaw.ai/tools/exec (note about “fails closed” when sandbox is off)

If exec is allowed but commands are being denied

That’s usually exec approvals (host=gateway/node is gated). Check:

openclaw approvals get --gateway
#

…and/or add an allowlist entry for your ssh binary (path depends on OS; check which ssh on the gateway host):

openclaw approvals allowlist add --gateway --agent "*" "/usr/bin/ssh"

Docs: https://docs.openclaw.ai/tools/exec-approvals and https://docs.openclaw.ai/cli/approvals

Paste the outputs and the exact error line and I’ll tell you which of the above you hit and the smallest config change to restore it.

wild yew
#

this is the error I just tested my available tools again — and no, I still cannot execute SSH from this session.

I only have messaging/session tools here, not terminal tools (exec/SSH/tmux). So I can’t even run a test command myself in this chat context.

If you want, I can give you a single SSH smoke test command now and once you paste output I’ll continue immediately:
this is the version: 2026.3.7. output of tools openclaw config get tools.allow
openclaw config get tools.deny
openclaw config get tools.byProvider
openclaw config get tools.exec.host
openclaw config get agents.defaults.sandbox.mode

thick gladeBOT
#

That error message is basically a dead giveaway: your config has put the agent into a messaging-only tool profile (or an equivalent tools.allow allowlist), so exec never even makes it into the toolset for Discord sessions.

On 2026.3.7, the built-in profiles are (from config ref):

  • messaging ⇒ no exec/process
  • coding ⇒ includes group:runtime (so exec + process)
  • full ⇒ no restriction

So the fix is in tool policy (tools.profile / tools.allow / tools.byProvider and possibly per-agent overrides).

What to edit (most common fixes)

Option A (simple): switch back to coding/full globally
In ~/.openclaw/openclaw.json:

#
{
  tools: { profile: "coding" }, // or "full"
}

Option B (keep messaging profile, but add runtime tools explicitly)

{
  tools: {
    profile: "messaging",
    allow: ["group:runtime"], // adds exec + process
  },
}

Option C (you accidentally restricted only the provider you’re using)

#

If tools.byProvider pins your model/provider to profile: "messaging"/"minimal", remove that entry or add runtime there too.

Docs: https://docs.openclaw.ai/gateway/configuration-reference (Tools → Tool profiles / byProvider)


One thing I still need from you

You listed the commands you ran, but not the actual outputs. Can you paste these outputs (wrap in a code block) so I can point to the exact line causing it?

openclaw config get tools.profile
openclaw config get tools.allow
openclaw config get tools.deny
openclaw config get tools.byProvider
openclaw config get agents.list
#

(If agents.list is huge, paste just the parts that mention tools.profile, tools.allow, tools.deny, or tools.byProvider.)

Once exec shows up again, if SSH still fails we’ll move to step 2 (exec host + approvals/allowlist), but right now you’re blocked earlier: the runtime tools aren’t even enabled.

wild yew
#

do I need to add that for each agent, because I'm seeing a lot of these "tools": {}

thick gladeBOT
#

No — you only need to set it per agent if you want that agent to behave differently from the global default.

In OpenClaw, tool policy is inherited like this:

  • Global: tools.profile / tools.allow / tools.deny
  • Per-agent override (optional): agents.list[].tools.*

So when you see lots of:

"tools": {}

that just means “this agent doesn’t override anything” → it inherits whatever you set at the top-level tools.

If you want all agents to get terminal tools

Set it once globally:

#
{
  tools: { profile: "coding" } // (includes exec/process via group:runtime)
}

(or profile: "full" if you really want everything)

If you only want some agents to get terminal tools

Keep global restrictive, and override only the ops/coding agent(s):

{
  tools: { profile: "messaging" },
  agents: {
    list: [
#
      { id: "ops", tools: { allow: ["group:runtime"] } }
    ]
  }
}

If you paste your current tools.profile + the top-level tools.allow/tools.deny, I can tell you the smallest change to get exec back without accidentally opening up every agent.

wild yew
#

I see it below the agents like this "tools": {
"profile": "messaging",
"web": {

thick gladeBOT
#

Yep — that’s the line that’s removing exec.

If an agent has:

tools: {
  profile: "messaging",
  web: { ... }
}

…then that agent is explicitly pinned to the messaging tool profile, which (by design) does not include exec / process (aka terminal/SSH/tmux capability).

Fix options (pick one)

Option 1: Change that agent to a runtime-capable profile
Change profile: "messaging" → profile: "coding" (or "full"):

#
tools: {
  profile: "coding",
  web: { ... } // keep this as-is
}

Option 2: Keep “messaging” but add runtime tools

tools: {
  profile: "messaging",
  allow: ["group:runtime"],
  web: { ... }
}

Option 3: Remove the per-agent tools.profile entirely

#

Then the agent will inherit whatever you set globally under top-level tools.profile.


If you want all your Discord agents to be able to run SSH, you’ll need to apply this to each agent that currently has profile: "messaging" (or remove that override so they inherit).

After editing, restart (or let hot-reload apply it), then re-test in Discord. If exec shows up but SSH is still blocked, we’ll move to the next layer (exec host + approvals/allowlist).

wild yew
#

this is what it looks like "tools": {
"profile": "coding",
"web": {
"search": {
"provider": "brave",
"apiKey": "REDACTED"
}
},
"exec": {
"security": "full",
"ask": "off"
}

thick gladeBOT
#

That config block should make exec available again (since profile: "coding" includes group:runtime).

If it still won’t actually run commands, the next gotcha is: exec defaults to host: "sandbox". If you don’t have sandboxing enabled, recent builds will fail closed instead of silently running on the gateway host.

Do this next (pick one)

1) Run exec on the gateway host (simplest)
Add host: "gateway":

"exec": {
  "host": "gateway",
  "security": "full",
  "ask": "off"
}
#

2) Or enable sandboxing
Set agents.defaults.sandbox.mode to "all" (or "non-main" depending on what you want), and keep host: "sandbox".

Also: start a fresh session after config changes

In the Discord chat/thread where you’re testing, send:

  • /new (or restart the gateway)

One more important check

Make sure you don’t have a tools.byProvider rule that’s narrowing tools back down (it applies after the base profile and can still remove exec).

Can you paste:

openclaw config get tools.byProvider
openclaw config get agents.defaults.sandbox.mode