#lobster and llm task

1 messages · Page 1 of 1 (latest)

distant stump
#

Has anyone managed to get a lobster file to work that makes a call to llm-task i.e. it runs a prompt successfully? If so could you paste an example here so I can understand the syntax. I've tried everything and nothing works

Thanks

bright badgeBOT
#

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

gentle vaporBOT
#

Yep — but there’s an important gotcha here: llm-task from a .lobster workflow only works reliably today with the standalone Lobster CLI + openclaw.invoke configured with gateway/auth context. The bundled embedded Lobster runner inside OpenClaw does not reliably inherit that context for nested openclaw.invoke calls yet, so examples using this inside embedded Lobster can look correct and still fail.

Minimal config pieces:

{
  "plugins": {
    "entries": {
      "llm-task": { "enabled": true }
    }
  },
  "tools": {
    "alsoAllow": ["lobster", "llm-task"]
  }
}
#

Standalone .lobster example:

openclaw.invoke --tool llm-task --action json --args-json '{
  "prompt": "Classify this message. Return only JSON matching the schema.",
  "thinking": "low",
  "input": {
    "message": "Can you help me install OpenClaw on Ubuntu?"
  },
  "schema": {
    "type": "object",
    "properties": {
      "category": { "type": "string" },
      "summary": { "type": "string" }
    },
    "required": ["category", "summary"],
#
    "additionalProperties": false
  }
}'

If you’re running this through the OpenClaw embedded lobster tool, the current recommendation is: call llm-task directly outside Lobster, or keep Lobster steps to normal CLI/script commands until the embedded bridge lands.

Docs:
https://docs.openclaw.ai/tools/lobster
https://docs.openclaw.ai/tools/llm-task

If you paste your openclaw --version plus the exact error/output, I can sanity-check whether you’re hitting this limitation or a config/auth issue. And for “has anyone personally got this working?” style examples, #users-helping-users is also a good place for human war stories.

distant stump
#

I've tried running your example but I got this error message back from openclaw

  1. The .lobster file isn't a valid YAML workflow. The lobster CLI's run command expects YAML workflow files (with name, steps, etc.), but this file is a raw shell-style pipeline (openclaw.invoke --tool llm-task ...). That's why lobster run choked with:

Error: Implicit keys need to be on a single line at line 1, column 1
2. Even when I ran the pipeline directly as a string (bypassing the file format issue), the openclaw.invoke call itself failed with a 500 error — tool execution failed. This means the lobster CLI's openclaw.invoke integration isn't working in this environment (likely missing CLAWD_URL/CLAWD_TOKEN env vars or the invoke handler isn't wired up in this lobster build).

Bottom line: The file content is fine as a pipeline concept, but it can't run as-is because (a) lobster run doesn't accept raw pipeline syntax in .lobster files, and (b) the openclaw.invoke tool isn't functional in this lobster installation.

gentle vaporBOT
#

Yep — you caught a real mismatch there. My example mixed two Lobster modes, sorry about that.

The split is:

  1. lobster run some-file.lobster expects a YAML/JSON workflow file, like:
name: llm-task-test
steps:
  - id: classify
    command: >-
      openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Return { ok: true } as JSON","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'
  1. The raw pipeline form:
openclaw.invoke --tool llm-task --action json --args-json '{...}'
#

is meant to be passed as the pipeline string to the OpenClaw lobster tool, not saved directly as a .lobster workflow file and run as YAML.

For the 500: most likely one of these is missing:

{
  "plugins": {
    "entries": {
      "llm-task": { "enabled": true }
    }
  },
  "tools": {
    "alsoAllow": ["lobster", "llm-task"]
  }
}

If you’re using the standalone Lobster CLI, then yeah, openclaw.invoke also needs to know how to reach your running OpenClaw gateway — so gateway URL/token/env wiring can matter there. The embedded OpenClaw Lobster tool path is the cleaner route.

distant stump
#

openclaw --version returns OpenClaw 2026.5.7 (eeef486)
How should I pass this pipeline to openclaw

gentle vaporBOT
#

For OpenClaw, don’t pass it to the standalone lobster run CLI. Pass it to the OpenClaw agent, and have the agent call the lobster tool with the pipeline string.

From terminal, the shape is:

openclaw agent --message "Run the lobster tool with action=run, timeoutMs=30000, and this pipeline:

openclaw.invoke --tool llm-task --action json --args-json '{...}'
"

More reliable quoting version:

cat > /tmp/lobster-prompt.txt <<'EOF'
Run the lobster tool with this payload:

{
#
  "action": "run",
  "timeoutMs": 30000,
  "pipeline": "openclaw.invoke --tool llm-task --action json --args-json '{\"prompt\":\"Return JSON with ok=true\",\"schema\":{\"type\":\"object\",\"properties\":{\"ok\":{\"type\":\"boolean\"}},\"required\":[\"ok\"],\"additionalProperties\":false}}'"
}
EOF

openclaw agent --message "$(cat /tmp/lobster-prompt.txt)"

Same thing in Control UI / chat: paste the JSON payload and say “run this with the lobster tool.” The important bit is that pipeline is a string field on the OpenClaw lobster tool call.

Also make sure both tools are enabled/allowed:

{
  "plugins": {
#
    "entries": {
      "llm-task": { "enabled": true }
    }
  },
  "tools": {
    "alsoAllow": ["lobster", "llm-task"]
  }
}

If you still get the 500 after that, check openclaw logs --follow while running it — the gateway log should show whether llm-task is missing, blocked by tool allowlist, or failing model/auth resolution.

Docs: https://docs.openclaw.ai/tools/lobster / https://docs.openclaw.ai/tools/llm-task

distant stump
#

I have those entries in openclaw.json. I also have the script saved in a file, so how would I prompt openclaw to execute that file?

gentle vaporBOT
#

If the file is a YAML/JSON Lobster workflow file (name:, steps:, etc.), prompt OpenClaw like this:

openclaw agent --message 'Use the lobster tool to run this workflow file:

{
  "action": "run",
  "pipeline": "/absolute/path/to/your-workflow.lobster",
  "timeoutMs": 30000
}'

If the workflow file needs args:

openclaw agent --message 'Use the lobster tool to run this workflow file:
#

{
  "action": "run",
  "pipeline": "/absolute/path/to/your-workflow.lobster",
  "argsJson": "{\"tag\":\"family\"}",
  "timeoutMs": 30000
}'

Important: that file path must be readable from the machine running the OpenClaw gateway, not just your terminal.

If the file is still a raw pipeline script like:

openclaw.invoke --tool llm-task --action json --args-json '{...}'
#

then don’t pass the filename as pipeline; pass the file contents as the pipeline string:

openclaw agent --message "Use the lobster tool with action=run, timeoutMs=30000, and pipeline set to this exact pipeline:

$(cat /absolute/path/to/pipeline.lobster)
"

My recommendation: convert it to the YAML workflow-file form if you want to keep it on disk and run it by path. Use raw pipeline strings for quick one-offs.

distant stump
#

How would I run this if I can only use telegram to communicate?

gentle vaporBOT
#

If Telegram is your only interface, you run it by messaging your OpenClaw Telegram bot/agent directly. No terminal needed.

Send a Telegram message like:

Run the lobster tool with this payload:

{
  "action": "run",
  "pipeline": "/absolute/path/on-the-gateway/your-workflow.lobster",
  "timeoutMs": 30000
}

If it needs args:

#
Run the lobster tool with this payload:

{
  "action": "run",
  "pipeline": "/absolute/path/on-the-gateway/your-workflow.lobster",
  "argsJson": "{\"tag\":\"family\"}",
  "timeoutMs": 30000
}

Two important gotchas:

  1. The file path has to exist on the machine running the OpenClaw gateway. Your phone/Telegram attachment path won’t count unless you’ve saved it onto that machine.
  2. If your saved file is a raw pipeline, not YAML workflow format, paste/send the pipeline contents instead and say:
#
Run the lobster tool with action=run, timeoutMs=30000, and pipeline set to this exact text:

openclaw.invoke --tool llm-task --action json --args-json '...'

So the clean Telegram-only workflow is: save the .lobster YAML workflow on the gateway box once, then trigger it from Telegram by asking OpenClaw to run the lobster tool with pipeline set to that absolute path.

distant stump
#

I tried that and get this message
The lobster CLI can't run this pipeline. Here's why:

openclaw.invoke is not a lobster command. The lobster CLI (node /home/admin/tools/lobster/bin/lobster.js) is a standalone Node.js tool that only understands its own pipeline syntax (exec, where, pick, approve, etc.). It has no built-in integration with OpenClaw's tool system.

The openclaw.invoke syntax only works when lobster is embedded inside an OpenClaw agent session (like the one I'm running in right now), not when invoked directly from the shell.

To make this work, you'd need to either:

  1. Run it as an OpenClaw agent task (which is what I did earlier with llm_task — that worked because I'm inside the OpenClaw runtime)
  2. Wrap it in a shell script that uses openclaw CLI commands instead of lobster's openclaw.invoke
  3. Use lobster's exec to call the OpenClaw CLI from within a lobster pipeline
gentle vaporBOT
#

That error means the agent is still taking the wrong route: it’s invoking the standalone Lobster CLI (node /home/admin/tools/lobster/bin/lobster.js) instead of calling the OpenClaw lobster tool.

From Telegram, try being extremely explicit:

Do not use exec, shell, terminal, node, or the standalone lobster CLI.
Call the OpenClaw agent tool named `lobster` directly.

Use this exact tool payload:

{
  "action": "run",
  "pipeline": "/absolute/path/on-the-gateway/your-workflow.lobster",
  "timeoutMs": 30000
}
#
If the `lobster` tool is not available to you, stop and say: "lobster tool unavailable".

If your saved file is a raw pipeline containing openclaw.invoke ..., don’t pass the path. Send:

Do not use exec, shell, terminal, node, or the standalone lobster CLI.
Call the OpenClaw agent tool named `lobster` directly with action=run.
Use this as the pipeline string:

openclaw.invoke --tool llm-task --action json --args-json '...'

If it still says “lobster CLI can’t run this,” then the Telegram-facing agent likely does not actually have the lobster tool exposed, even if your config has the entries. Common causes:

  • config changed but gateway wasn’t restarted
#
  • tools.alsoAllow was added under a different agent than the one Telegram routes to
  • a restrictive tools.allow is overriding/limiting tools
  • the lobster plugin isn’t installed/loaded for that runtime

Quick checks on the gateway box:

openclaw plugins list | grep lobster
openclaw plugins doctor
openclaw status --all
openclaw logs --follow

The key phrase is: call the OpenClaw lobster tool directly. Anything involving lobster run, node .../lobster.js, or shell execution is the standalone CLI path, and openclaw.invoke won’t work there.

distant stump
#

I get the message lobster tool unavailable

gentle vaporBOT
#

That confirms it: your Telegram-routed agent cannot see the embedded lobster tool. So the prompt is fine now — the tool exposure isn’t.

Fix checklist:

  1. Verify the plugin is installed/loaded on the gateway:
openclaw plugins list | grep lobster
openclaw plugins doctor

If it’s not installed, install/enable it:

openclaw plugins install @openclaw/lobster
openclaw plugins enable lobster
  1. Make sure the Telegram agent specifically allows it. If your Telegram route uses a non-main agent, root tools.alsoAllow may not be enough depending on overrides. Add it to that agent too:
#
{
  tools: {
    alsoAllow: ["lobster", "llm-task"]
  },
  agents: {
    list: [
      {
        id: "YOUR_TELEGRAM_AGENT_ID",
        tools: {
          alsoAllow: ["lobster", "llm-task"]
        }
      }
    ]
  }
}
#
  1. If that agent has tools.profile: "messaging" or "minimal", that’s probably the culprit. Those profiles are intentionally narrow; either add alsoAllow as above or switch to tools.profile: "full" for that agent if you trust the surface.

  2. Restart/reload the gateway after config/plugin changes:

openclaw gateway restart

Then from Telegram send the same explicit prompt again:

Do not use shell or the standalone lobster CLI. Call the OpenClaw tool named lobster directly. If unavailable, say so.

Payload:
{
  "action": "run",
  "pipeline": "/absolute/path/on-the-gateway/your-workflow.lobster",
  "timeoutMs": 30000
#
}

If it still says unavailable after restart, paste the redacted agents.list entry for the Telegram agent and the output of openclaw plugins list | grep lobster.

distant stump
#

This is my config
{
"id": "lead-scout",
"name": "DBA Lead Scout",
"workspace": "~/.openclaw/workspace-dba-scout",
"model": "lmstudio/qwen/qwen3.6-35b-a3b",
"params": {
"temperature": 0.1
},
"tools": {
"allow": [
"*"
],
"deny": [
"web-search"
]
}
},

gentle vaporBOT
#

That agent config isn’t the part that enables Lobster. tools.allow: ["*"] means “allow all tools that are already loaded/available” — it does not make optional plugin tools load by itself.

Two things I’d change/check:

  1. Your deny entry is the wrong tool name:
"deny": ["web_search"]

not web-search. Not the Lobster issue, but worth fixing.

  1. You need the Lobster plugin loaded globally, and not blocked by plugins.allow.

At top-level config, you want something like:

{
  plugins: {
#
    entries: {
      lobster: { enabled: true },
      "llm-task": { enabled: true }
    }
    // If you have plugins.allow set, it MUST include both:
    // allow: ["lobster", "llm-task", ...]
  },

  agents: {
    list: [
      {
        id: "lead-scout",
        name: "DBA Lead Scout",
        workspace: "~/.openclaw/workspace-dba-scout",
        model: "lmstudio/qwen/qwen3.6-35b-a3b",
#
        params: { temperature: 0.1 },
        tools: {
          allow: ["*"],
          deny: ["web_search"]
        }
      }
    ]
  }
}

Then restart the gateway:

openclaw gateway restart
#

If you’re on the gateway box, run:

openclaw plugins list | grep -E 'lobster|llm-task'
openclaw plugins doctor
openclaw doctor

If plugins.allow exists anywhere in your config and does not include lobster, that’s the most likely reason the tool says unavailable. tools.allow: ["*"] won’t bypass plugins.allow.

One more caveat: Qwen via LM Studio may be shaky at tool calling. Once Lobster appears in the tool list, if the agent still tries shell/CLI instead of the tool, test once with a tool-reliable cloud model to separate “tool not exposed” from “model chose the wrong tool path.”

distant stump
#

ah ok, so the lobster plugin was not installed. I installed it and I ran the prompt again and got a different error

The lobster tool is available, but it doesn't support running .lobster workflow files directly — it only accepts inline pipeline command strings. The file examples/simple-llm-example.lobster is a workflow file (not an inline pipeline), so the tool can't execute it.

gentle vaporBOT
#

Nice, progress. That new error sounds like either the installed @openclaw/lobster plugin is older than the OpenClaw docs, or the model is paraphrasing the tool schema incorrectly.

The current docs say the embedded Lobster tool should accept workflow file paths as pipeline:

{
  "action": "run",
  "pipeline": "/path/to/inbox-triage.lobster",
  "argsJson": "{\"tag\":\"family\"}"
}

So I’d check/update the plugin first:

openclaw plugins list | grep lobster
openclaw plugins update
openclaw plugins doctor
#
openclaw gateway restart

Then try again from Telegram with an absolute path:

Call the OpenClaw tool named lobster directly. Do not use shell/exec/CLI.
Use payload:
{
  "action": "run",
  "pipeline": "/home/admin/path/to/examples/simple-llm-example.lobster",
  "timeoutMs": 30000
}

If it still says file workflows aren’t supported, use the workaround: paste the inline pipeline contents as the pipeline string instead of the filename.

#

For your example, that means something like:

Call the OpenClaw tool named lobster directly with action=run.
Use this inline pipeline string:

openclaw.invoke --tool llm-task --action json --args-json '...'

But I’d treat “doesn’t support workflow files” as suspicious, because the docs for 2026.5.7 say it does. If plugin update doesn’t fix it, this is probably worth a GitHub issue with openclaw --version, openclaw plugins list, and the exact tool error: https://github.com/openclaw/openclaw/issues

distant stump
#

Can you give me the prompt in full

gentle vaporBOT
#

Yep — here’s the full Telegram prompt I’d send.

Replace the path with the real absolute path on your gateway machine:

Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.
Do not run `lobster run`.

Use this exact tool payload:

{
  "action": "run",
  "pipeline": "/home/admin/examples/simple-llm-example.lobster",
  "timeoutMs": 30000,
  "maxStdoutBytes": 512000
#
}

If the `lobster` tool reports that workflow files are not supported, stop and tell me the exact error. Do not try to work around it by using shell or the standalone Lobster CLI.

If that still gives the “workflow files not supported” error, use this version instead, but replace the pipeline line with the actual raw pipeline text from your file:

Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.
Do not run `lobster run`.

Use this exact tool payload:

{
#
  "action": "run",
  "pipeline": "openclaw.invoke --tool llm-task --action json --args-json '{\"prompt\":\"Return JSON with ok=true\",\"schema\":{\"type\":\"object\",\"properties\":{\"ok\":{\"type\":\"boolean\"}},\"required\":[\"ok\"],\"additionalProperties\":false}}'",
  "timeoutMs": 30000,
  "maxStdoutBytes": 512000
}

The first prompt is the intended file-based path. The second is the inline-pipeline fallback.

distant stump
#

ok, the prompt worked

gentle vaporBOT
#

Awesome — glad we got it unstuck 🎉

So the final path was: install/enable the Lobster plugin, then explicitly prompt Telegram/OpenClaw to call the embedded lobster tool directly instead of the standalone CLI.

If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow indexes it for the next person who hits this.

distant stump
#

I still can't quite get the file to work, can you give me another example of a lobster file and the prompt I need to execute it

gentle vaporBOT
#

Yep. Here’s a clean workflow-file example you can save as a real .lobster YAML file.

Save this on the gateway machine as:

/home/admin/examples/simple-llm-workflow.lobster

File contents:

name: simple-llm-workflow
steps:
  - id: ask_llm
    command: >-
      openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this lead. Return JSON only with company, fit, and reason.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"reason":{"type":"string"}},"required":["company","fit","reason"],"additionalProperties":false}}'
#

Then from Telegram, send this exact prompt:

Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.
Do not run `lobster run`.

Use this exact tool payload:

{
  "action": "run",
  "pipeline": "/home/admin/examples/simple-llm-workflow.lobster",
  "timeoutMs": 30000,
  "maxStdoutBytes": 512000
}
#
If this fails, tell me the exact lobster tool error. Do not try to work around it with shell or the standalone Lobster CLI.

If that still says file workflows are unsupported, then your installed Lobster plugin likely only supports inline pipelines. In that case, send this Telegram prompt instead:

Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.
Do not run `lobster run`.

Use this exact tool payload:

{
  "action": "run",
  "pipeline": "openclaw.invoke --tool llm-task --action json --args-json '{\"prompt\":\"Classify this lead. Return JSON only with company, fit, and reason.\",\"thinking\":\"low\",\"input\":{\"company\":\"Acme Dental\",\"notes\":\"Multi-location dental practice looking for help with missed-call followup and appointment reminders.\"},\"schema\":{\"type\":\"object\",\"properties\":{\"company\":{\"type\":\"string\"},\"fit\":{\"type\":\"string\",\"enum\":[\"high\",\"medium\",\"low\"]},\"reason\":{\"type\":\"string\"}},\"required\":[\"company\",\"fit\",\"reason\"],\"additionalProperties\":false}}'",
#
  "timeoutMs": 30000,
  "maxStdoutBytes": 512000
}

The first one tests file execution. The second is the same workflow as an inline pipeline, which is the fallback if your plugin build doesn’t support .lobster files by path yet.

distant stump
#

CAn you give me a multistep file

gentle vaporBOT
#

Yep — here’s a simple multi-step .lobster workflow file that does:

  1. classify a lead with llm-task
  2. draft an outreach message using the classification
  3. require approval before continuing
  4. print the approved draft

Save this on the gateway machine as:

/home/admin/examples/multistep-lead-workflow.lobster

File contents:

#
name: multistep-lead-workflow

steps:
  - id: classify_lead
    command: >-
      openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"integer","minimum":1,"maximum":5},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'

  - id: draft_outreach
    command: >-
      openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Using the lead classification, draft a short friendly outreach message. Return JSON only with subject and body.","thinking":"low","input":{"classification":$classify_lead.json},"schema":{"type":"object","properties":{"subject":{"type":"string"},"body":{"type":"string"}},"required":["subject","body"],"additionalProperties":false}}'

  - id: approve_draft
    command: approve --preview-from-stdin --limit 5 --prompt 'Approve this outreach draft?'
    stdin: $draft_outreach.json
    approval: required
#

  - id: final_output
    command: exec --stdin json --shell 'cat'
    stdin: $draft_outreach.json
    condition: $approve_draft.approved

Then from Telegram, send:

Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.
Do not run `lobster run`.

Use this exact tool payload:
#

{
  "action": "run",
  "pipeline": "/home/admin/examples/multistep-lead-workflow.lobster",
  "timeoutMs": 60000,
  "maxStdoutBytes": 512000
}

If this fails, tell me the exact lobster tool error. Do not try to work around it with shell or the standalone Lobster CLI.

If the $classify_lead.json interpolation fails in your plugin build, tell me the exact error — that’ll mean this Lobster version wants step outputs passed differently, and I’ll rewrite it in the compatible shape.

distant stump
#

I get this error
The lobster tool returned this exact error:

workflow command failed (127): /usr/local/bin/openclaw.invoke: 1: 404:: not found

The pipeline path /home/admin/.openclaw/workspace-dba-scout/t.lobster resolved to something that invoked openclaw.invoke, which returned a 404. This suggests the file either doesn't exist at that path or isn't a valid Lobster pipeline definition.

gentle vaporBOT
#

Yep — that error means the file did load, but the workflow step tried to execute openclaw.invoke as a command and hit a broken/missing invoke shim:

/usr/local/bin/openclaw.invoke: 1: 404:: not found

So don’t debug the path yet — the path is being found. The failing bit is openclaw.invoke inside the workflow file.

Here’s a multi-step Lobster file that avoids openclaw.invoke entirely, so it should test file workflows cleanly.

Save as:

/home/admin/.openclaw/workspace-dba-scout/multistep-test.lobster

File contents:

#
name: multistep-test

steps:
  - id: lead
    command: >-
      node -e 'console.log(JSON.stringify({company:"Acme Dental", industry:"Dental", notes:"Multi-location practice wants missed-call followup and appointment reminders."}))'

  - id: score
    command: >-
      node -e 'let s=""; process.stdin.on("data", c => s += c); process.stdin.on("end", () => { const lead = JSON.parse(s); const result = { company: lead.company, fit: "high", priority: 5, reason: "Multi-location dental practice with clear followup/reminder pain." }; console.log(JSON.stringify(result)); })'
    stdin: $lead.stdout

  - id: draft
    command: >-
      node -e 'let s=""; process.stdin.on("data", c => s += c); process.stdin.on("end", () => { const score = JSON.parse(s); const draft = { subject: `Quick idea for ${score.company}`, body: `Hi — noticed ${score.company} may benefit from faster missed-call followup and appointment reminders. Worth a quick chat?`, score }; console.log(JSON.stringify(draft)); })'
#
    stdin: $score.stdout

  - id: review
    command: cat
    stdin: $draft.stdout
    approval: required

  - id: final
    command: cat
    stdin: $draft.stdout
    condition: $review.approved

Then send this from Telegram:

#
Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.
Do not run `lobster run`.

Use this exact tool payload:

{
  "action": "run",
  "pipeline": "/home/admin/.openclaw/workspace-dba-scout/multistep-test.lobster",
  "timeoutMs": 60000,
  "maxStdoutBytes": 512000
}

If this fails, tell me the exact lobster tool error. Do not try to work around it with shell or the standalone Lobster CLI.
#

If this works, your .lobster file execution is fine and the remaining issue is specifically openclaw.invoke in workflow-file steps. For now, use openclaw.invoke only in inline Lobster pipelines, or update/report the plugin issue so the workflow-file invoke shim works correctly.

distant stump
#

actually /usr/local/bin/openclaw.invoke appears to be corrupt, how do I fix that?

gentle vaporBOT
#

Yep — if /usr/local/bin/openclaw.invoke literally contains 404: then it was probably created from a failed download/install, not a valid executable.

First confirm:

command -v openclaw.invoke
file /usr/local/bin/openclaw.invoke
head -5 /usr/local/bin/openclaw.invoke

If the first line shows 404: or HTML, move it aside and reinstall/update Lobster:

sudo mv /usr/local/bin/openclaw.invoke /usr/local/bin/openclaw.invoke.broken

openclaw plugins update lobster
#
openclaw plugins doctor
openclaw gateway restart

Then check again:

command -v openclaw.invoke
head -5 "$(command -v openclaw.invoke)"

If openclaw plugins update lobster doesn’t recreate it, do a clean plugin reinstall:

openclaw plugins uninstall lobster
#
openclaw plugins install @openclaw/lobster
openclaw plugins enable lobster
openclaw gateway restart

One extra gotcha: if command -v openclaw.invoke returns multiple paths depending on shell/PATH, make sure the gateway service sees the fixed one. After restart, rerun the workflow and watch logs:

openclaw logs --follow

Don’t curl a replacement manually unless the Lobster docs/plugin explicitly tell you to — that’s how these 404: shim files usually happen. 🦞

distant stump
#

I've updated lobster but /usr/local/bin/openclaw.invoke is no longer there

gentle vaporBOT
#

That’s actually expected after moving/removing the corrupt shim: now you need to reinstall the standalone Lobster CLI/shims, not just the OpenClaw plugin.

The OpenClaw lobster plugin makes the lobster tool available to agents. But when a .lobster workflow file has a step like:

command: openclaw.invoke --tool llm-task ...

that step runs through the system shell, so openclaw.invoke must exist as a real executable in the gateway machine’s PATH.

Try this on the gateway box:

pnpm add -g @openclaw/lobster

command -v lobster
#
command -v openclaw.invoke
command -v clawd.invoke

If openclaw.invoke now appears somewhere like a pnpm global bin dir, test it:

openclaw.invoke --help

Then restart the gateway:

openclaw gateway restart
#

If command -v openclaw.invoke works in your shell, but the workflow still says openclaw.invoke: not found, your gateway service probably doesn’t have the pnpm global bin dir in its PATH. In that case, make a stable symlink:

sudo ln -sf "$(command -v openclaw.invoke)" /usr/local/bin/openclaw.invoke
sudo ln -sf "$(command -v clawd.invoke)" /usr/local/bin/clawd.invoke 2>/dev/null || true
openclaw gateway restart

Then rerun the workflow.

Key distinction:

  • openclaw plugins install @openclaw/lobster = agent tool plugin
  • pnpm add -g @openclaw/lobster = CLI + openclaw.invoke shim for workflow shell steps

You likely need both for .lobster files that call openclaw.invoke.

distant stump
#

i don't have pnpm

gentle vaporBOT
#

No problem — install pnpm first, then install the Lobster CLI/shims.

On the gateway box:

corepack enable
corepack prepare pnpm@latest --activate
pnpm --version

Then:

pnpm add -g @openclaw/lobster
command -v openclaw.invoke
openclaw.invoke --help
#
openclaw gateway restart

If pnpm add -g complains about no global bin directory, run:

pnpm setup
source ~/.bashrc
pnpm add -g @openclaw/lobster

If corepack isn’t available on your system, paste that error — don’t switch to Bun. We’ll get pnpm installed cleanly for your Node setup.

distant stump
#

Can i use npm instead?

gentle vaporBOT
#

Yes — npm is fine here.

On the gateway box:

npm install -g @openclaw/lobster

command -v lobster
command -v openclaw.invoke
openclaw.invoke --help
openclaw gateway restart

If npm install -g fails with permissions, use one of these depending on how Node is installed:

#
sudo npm install -g @openclaw/lobster

or, if you use nvm, don’t use sudo — switch to your Node version and run:

npm install -g @openclaw/lobster

If install succeeds but openclaw.invoke is still not found by the workflow, check where npm put global binaries:

npm config get prefix
ls "$(npm config get prefix)/bin" | grep invoke
#

Then either add that bin dir to the gateway service PATH, or make a stable symlink:

sudo ln -sf "$(command -v openclaw.invoke)" /usr/local/bin/openclaw.invoke
openclaw gateway restart

So yes: npm install -g @openclaw/lobster is the npm equivalent.

distant stump
#

it says it is here but I can't find openclaw.invoke in /home/admin/.npm-global

gentle vaporBOT
#

Ah, that explains it. The npm package with the CLI shims is currently the legacy-named package:

npm install -g @clawdbot/lobster

That package exposes:

lobster
openclaw.invoke
clawd.invoke

After installing, check:

#
npm bin -g 2>/dev/null || npm prefix -g
find /home/admin/.npm-global -name 'openclaw.invoke*' -o -name 'lobster*'
command -v openclaw.invoke
openclaw.invoke --help

If openclaw.invoke exists under something like:

/home/admin/.npm-global/bin/openclaw.invoke

but the gateway workflow can’t see it, symlink it into /usr/local/bin:

#
sudo ln -sf /home/admin/.npm-global/bin/openclaw.invoke /usr/local/bin/openclaw.invoke
sudo ln -sf /home/admin/.npm-global/bin/clawd.invoke /usr/local/bin/clawd.invoke
sudo ln -sf /home/admin/.npm-global/bin/lobster /usr/local/bin/lobster
openclaw gateway restart

Small naming mess: @openclaw/lobster is the plugin package name in newer docs, but the standalone CLI/shim package on npm that has openclaw.invoke is @clawdbot/lobster right now.

distant stump
#

That has installed it, i get this message for openclaw.invoke -- help
Error: openclaw.invoke requires --url or OPENCLAW_URL

gentle vaporBOT
#

Great — that means the shim is installed correctly now. It just needs to know which OpenClaw Gateway to call.

Set these env vars for the gateway process/workflow environment:

export OPENCLAW_URL=http://127.0.0.1:18789
# If your gateway requires a token:
export OPENCLAW_TOKEN='YOUR_GATEWAY_TOKEN'

Quick manual test:

OPENCLAW_URL=http://127.0.0.1:18789 openclaw.invoke --help

If auth is enabled:

#
OPENCLAW_URL=http://127.0.0.1:18789 OPENCLAW_TOKEN='YOUR_GATEWAY_TOKEN' openclaw.invoke --help

For the .lobster file, you can bake those vars into the workflow so shell steps inherit them:

name: openclaw-invoke-test

env:
  OPENCLAW_URL: http://127.0.0.1:18789
  # Better: don’t hardcode tokens in files if you can avoid it.
  # OPENCLAW_TOKEN: your-token-here

steps:
  - id: greeting
#
    run: >-
      openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Return JSON with greeting=hello","schema":{"type":"object","properties":{"greeting":{"type":"string"}},"required":["greeting"],"additionalProperties":false}}'

If a token is required, best practice is to set OPENCLAW_TOKEN in the service/user environment rather than committing it into the .lobster file.

To find the URL/token source on the machine, these usually help:

openclaw gateway status
openclaw dashboard

openclaw dashboard often prints a URL containing the token; don’t paste that publicly.

distant stump
#

Now I get this message
Error: openclaw.invoke requires --tool and --action

gentle vaporBOT
#

That one is actually good news: openclaw.invoke is now running, and it’s past the URL/token problem. It’s just being called without the required args.

openclaw.invoke --help apparently doesn’t behave like a normal help command in this build — it still validates that --tool and --action are present.

Test it with a real call instead:

OPENCLAW_URL=http://127.0.0.1:18789 \
OPENCLAW_TOKEN='YOUR_GATEWAY_TOKEN_IF_NEEDED' \
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'

And in your .lobster file, make sure the step has both --tool and --action, like this:

name: openclaw-invoke-test
#

env:
  OPENCLAW_URL: http://127.0.0.1:18789
  # OPENCLAW_TOKEN: your-token-if-required

steps:
  - id: test_llm
    run: >-
      openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'

Then trigger it from Telegram/OpenClaw with:

Call the OpenClaw tool named `lobster` directly.
#
Do not use shell, exec, terminal, node, or the standalone lobster CLI.

Use this exact tool payload:

{
  "action": "run",
  "pipeline": "/home/admin/.openclaw/workspace-dba-scout/openclaw-invoke-test.lobster",
  "timeoutMs": 60000,
  "maxStdoutBytes": 512000
}

If you got that error from the workflow, not from your manual --help test, paste the exact run: line from the .lobster file — it probably lost the --tool / --action flags due to quoting or line wrapping.

distant stump
#

I get the message
Error: openclaw.invoke failed (401): {"error":{"message":"Unauthorized","type":"unauthorized"}}

gentle vaporBOT
#

Good, that’s the last missing piece: the shim is reaching the Gateway, but it doesn’t have Gateway auth.

openclaw.invoke calls the Gateway HTTP /tools/invoke endpoint, so it needs the same Gateway token/password auth.

If your gateway uses token auth, set:

export OPENCLAW_URL=http://127.0.0.1:18789
export OPENCLAW_TOKEN='your-gateway-token-here'

If it uses password auth, set:

export OPENCLAW_URL=http://127.0.0.1:18789
export OPENCLAW_TOKEN='your-gateway-password-here'
#

Yes, the shim expects OPENCLAW_TOKEN even when the Gateway auth mode is password — it sends it as Authorization: Bearer ....

To find what auth mode/value you’re using, run on the gateway box:

openclaw gateway status
openclaw config get gateway.auth.mode
openclaw config get gateway.auth.token
openclaw config get gateway.auth.password

Don’t paste the token/password publicly.

Then test with a real invoke:

#
OPENCLAW_URL=http://127.0.0.1:18789 \
OPENCLAW_TOKEN='your-token-or-password' \
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'

For the workflow file, either export those vars in the gateway service environment, or add only the URL to the file and keep the token in the environment:

env:
  OPENCLAW_URL: http://127.0.0.1:18789
  # Do not hardcode OPENCLAW_TOKEN here unless this file is private and locked down.

If you hardcode the token in the .lobster file, treat that file like a secret.

distant stump
#

Where can I find my openclaw token

gentle vaporBOT
#

On the gateway machine, check it locally — don’t paste the value here.

Try:

openclaw config get gateway.auth.mode
openclaw config get gateway.auth.token
openclaw config get gateway.auth.password

If gateway.auth.mode is token, use gateway.auth.token as:

export OPENCLAW_TOKEN='that-token-value'

If auth mode is password, use the password value instead:

#
export OPENCLAW_TOKEN='that-password-value'

You can also run:

openclaw dashboard

That often prints a local dashboard URL containing the gateway token in the #token=... part. Treat that whole URL as secret.

For your Lobster/openclaw.invoke case, you want:

export OPENCLAW_URL=http://127.0.0.1:18789
distant stump
#

the token is being redacted

gentle vaporBOT
#

Yep, openclaw config get redacts secrets on purpose. To retrieve it for local use, read the raw config file directly on the gateway box — don’t paste the result here.

Try:

CONFIG="$(openclaw config file)"
echo "$CONFIG"
node -e 'const fs=require("fs"); const p=process.argv[1]; const c=fs.readFileSync(p,"utf8"); const m=c.match(/token\s*[:=]\s*["'"'`]([^"'"'`]+)["'"'`]/); console.log(m ? m[1] : "No plaintext token found in config")' "$CONFIG"

If that prints a token, use it like:

export OPENCLAW_URL=http://127.0.0.1:18789
export OPENCLAW_TOKEN='PASTE_TOKEN_HERE'
#

If it says no plaintext token found, your token may be coming from an env var / SecretRef. Check these locally:

printenv OPENCLAW_GATEWAY_TOKEN
printenv OPENCLAW_TOKEN
printenv OPENCLAW_GATEWAY_PASSWORD

If OpenClaw runs as a systemd user service, also check the service environment:

systemctl --user show openclaw-gateway --property=Environment

If you still can’t recover it, easiest fix is to rotate/set a new gateway token:

#
openclaw config set gateway.auth.mode token
openclaw config set gateway.auth.token "$(openssl rand -hex 32)"
openclaw gateway restart
openclaw config get gateway.auth.token

That last command may still redact, so read it from the config file right after setting it, or save it as you set it:

TOKEN="$(openssl rand -hex 32)"
openclaw config set gateway.auth.mode token
openclaw config set gateway.auth.token "$TOKEN"
printf '%s
' "$TOKEN" > ~/.openclaw-gateway-token-for-lobster
chmod 600 ~/.openclaw-gateway-token-for-lobster
#
openclaw gateway restart

Then for Lobster:

export OPENCLAW_TOKEN="$(cat ~/.openclaw-gateway-token-for-lobster)"
distant stump
#

ok i ahve the token and have exported it

gentle vaporBOT
#

Perfect. Now test the shim with a real call:

openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'

If that works, rerun the .lobster workflow from Telegram with the file-path prompt:

Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.

Use this exact tool payload:

{
  "action": "run",
#
  "pipeline": "/home/admin/.openclaw/workspace-dba-scout/t.lobster",
  "timeoutMs": 60000,
  "maxStdoutBytes": 512000
}

If the manual openclaw.invoke test works but the workflow still gets 401, then the Gateway service running the Lobster workflow does not inherit your shell export. In that case add the vars to the workflow file temporarily:

env:
  OPENCLAW_URL: http://127.0.0.1:18789
  OPENCLAW_TOKEN: your-token-here

Longer-term, put OPENCLAW_TOKEN into the gateway service environment instead of hardcoding it in the workflow file.

distant stump
#

I'm trying to copy openclaw.invoke to /usr/local/bin but I get permission denied

gentle vaporBOT
#

That’s normal — /usr/local/bin is root-owned. Use sudo, and prefer a symlink instead of copying so it keeps pointing at the installed shim after updates:

sudo ln -sf "$(command -v openclaw.invoke)" /usr/local/bin/openclaw.invoke
sudo ln -sf "$(command -v clawd.invoke)" /usr/local/bin/clawd.invoke

Then verify:

/usr/local/bin/openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'

If you don’t have sudo access, don’t use /usr/local/bin. Instead make sure the directory containing openclaw.invoke is in the Gateway service’s PATH. For example, if it’s in /home/admin/.npm-global/bin, the workflow needs that path available when the gateway runs.

distant stump
#

I managed to run the prompt but I got this error
tools: lobster failed stack:
Error: workflow command failed (1): openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"integer","minimum":1,"maximum":5},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'
at throwOnErrorEnvelope (/home/admin/.openclaw/npm/node_modules/@openclaw/lobster/dist/index.js:175:9)
at /home/admin/.openclaw/npm/node_modules/@openclaw/lobster/dist/index.js:276:20

gentle vaporBOT
#

Nice — that means the workflow file is running now. This stack is just Lobster saying “the openclaw.invoke subprocess exited 1”; it’s hiding the actual openclaw.invoke error.

Most likely causes now are:

  1. the workflow process does not inherit OPENCLAW_URL / OPENCLAW_TOKEN
  2. llm-task is not enabled/allowed over /tools/invoke
  3. the llm-task call itself is failing model/auth

First, run the exact command manually on the gateway box, with env inline:

OPENCLAW_URL=http://127.0.0.1:18789 \
OPENCLAW_TOKEN='YOUR_TOKEN' \
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"integer","minimum":1,"maximum":5},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'

If that works manually, add the env vars to the workflow file for testing:

#
name: multistep-lead-workflow

env:
  OPENCLAW_URL: http://127.0.0.1:18789
  OPENCLAW_TOKEN: YOUR_TOKEN

steps:
  - id: classify_lead
    run: >-
      openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"integer","minimum":1,"maximum":5},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'

Treat that file as secret if it contains the token. Longer-term, put OPENCLAW_TOKEN into the gateway service environment instead.

If the manual command fails too, paste only the non-secret error text. If it says 404, llm-task isn’t exposed/allowed. If it says 401, token/env is wrong. If it says model/auth, then the llm-task plugin can be reached but its model provider config is failing.

distant stump
#

I get the message

Error: openclaw.invoke failed (500): {"ok":false,"error":{"type":"tool_error","message":"tool execution failed"}}

gentle vaporBOT
#

That 500 means the bridge/auth is working now, but the llm-task tool itself is failing. The Gateway is sanitizing the error, so the useful detail will be in the logs.

Run this in one terminal:

openclaw logs --follow

Then in another terminal rerun the exact openclaw.invoke ... command. Look for the real llm-task error right after it runs.

Most common cause here: llm-task does not automatically inherit your lead-scout agent model. Configure it explicitly, or pass provider/model in the call.

Try this direct test, adjusting provider/model to your working LM Studio config:

OPENCLAW_URL=http://127.0.0.1:18789 \
#
OPENCLAW_TOKEN='YOUR_TOKEN' \
openclaw.invoke --tool llm-task --action json --args-json '{"provider":"lmstudio","model":"qwen/qwen3.6-35b-a3b","prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'

Or set it in config:

{
  plugins: {
    entries: {
      "llm-task": {
        enabled: true,
        config: {
          defaultProvider: "lmstudio",
          defaultModel: "qwen/qwen3.6-35b-a3b",
#
          timeoutMs: 30000
        }
      }
    }
  }
}

Then restart:

openclaw gateway restart

If the log says tool not found / 404, llm-task still isn’t allowed. If it says model/auth/provider error, paste that sanitized log line and we can fix the provider config next.

distant stump
#

I see this is the the logs
tool execution failed: Error: LLM JSON did not match schema: /priority must be integer

gentle vaporBOT
#

Great, that’s a real error now — the whole Lobster/OpenClaw bridge is working. The model returned priority as something like "5" instead of integer 5, and llm-task rejected it because schema validation is strict.

Easiest fix: make priority a string enum instead of an integer. Local models are often sloppy with JSON number types.

Change this part:

"priority":{"type":"integer","minimum":1,"maximum":5}

to:

"priority":{"type":"string","enum":["1","2","3","4","5"]}

Or keep integer but make the prompt stricter:

#
priority must be a JSON integer number from 1 to 5, not a string. Example: "priority": 5

I’d use the string enum for reliability. Here’s the safer run: line:

run: >-
  openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'

If you really need it as an integer later, convert it in the next deterministic step with Node/jq instead of trusting the model to get the type right.

distant stump
#

so can you give me the full command to run again

gentle vaporBOT
#

Yep — run this on the gateway box. Replace YOUR_TOKEN if you haven’t already exported it.

If you already exported OPENCLAW_URL and OPENCLAW_TOKEN:

openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'

Or with env inline:

OPENCLAW_URL=http://127.0.0.1:18789 \
OPENCLAW_TOKEN='YOUR_TOKEN' \
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'

If this works, paste that same --args-json change into your .lobster file’s run: line.

distant stump
#

I get this as a response
[
{
"content": [
{
"type": "text",
"text": "{\n "company": "Acme Dental",\n "fit": "high",\n "priority": "4",\n "reason": "Multi-location practice indicates established revenue and clear need for automation (missed-call followup, appointment reminders). Vertical-specific pain points with measurable ROI potential."\n}"
}
],
"details": {
"json": {
"company": "Acme Dental",
"fit": "high",
"priority": "4",
"reason": "Multi-location practice indicates established revenue and clear need for automation (missed-call followup, appointment reminders). Vertical-specific pain points with measurable ROI potential."
},
"provider": "lmstudio",
"model": "qwen/qwen3.6-35b-a3b"
}
}
]

gentle vaporBOT
#

Perfect — that means openclaw.invoke → llm-task → LM Studio is working now ✅

Now update your .lobster file to use the same working schema (priority as a string), then run the file again from Telegram/OpenClaw.

Use this run: line in the workflow:

run: >-
  openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'

Then trigger the file:

Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.
#

Use this exact tool payload:

{
  "action": "run",
  "pipeline": "/home/admin/.openclaw/workspace-dba-scout/t.lobster",
  "timeoutMs": 60000,
  "maxStdoutBytes": 512000
}

If that works, you’re fully through the setup gauntlet: plugin installed, invoke shim installed, auth configured, and schema fixed. 🦞

distant stump
#

can you give me the full contents of t.lobster

gentle vaporBOT
#

Yep — replace /home/admin/.openclaw/workspace-dba-scout/t.lobster with this full file:

name: t

env:
  OPENCLAW_URL: http://127.0.0.1:18789
  # Keep OPENCLAW_TOKEN exported in the gateway/service environment.
  # Avoid hardcoding it here unless this file is private and locked down.

steps:
  - id: classify_lead
    run: >-
      openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'

  - id: normalize_result
#
    run: >-
      node -e 'let s=""; process.stdin.on("data", c => s += c); process.stdin.on("end", () => { const raw = JSON.parse(s); const json = Array.isArray(raw) ? raw[0].details.json : raw.details.json; console.log(JSON.stringify({ company: json.company, fit: json.fit, priority: Number(json.priority), reason: json.reason }, null, 2)); })'
    stdin: $classify_lead.stdout

  - id: draft_outreach
    run: >-
      node -e 'let s=""; process.stdin.on("data", c => s += c); process.stdin.on("end", () => { const lead = JSON.parse(s); const draft = { subject: `Quick idea for ${lead.company}`, body: `Hi — noticed ${lead.company} may benefit from faster missed-call followup and appointment reminders. Based on the lead notes, this looks like a ${lead.fit}-fit opportunity with priority ${lead.priority}. Worth a quick chat?`, lead }; console.log(JSON.stringify(draft, null, 2)); })'
    stdin: $normalize_result.stdout

  - id: review_draft
    run: cat
    stdin: $draft_outreach.stdout
    approval: required

  - id: final_output
#
    run: cat
    stdin: $draft_outreach.stdout
    condition: $review_draft.approved

Then trigger it again with:

Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.

Use this exact tool payload:

{
  "action": "run",
#
  "pipeline": "/home/admin/.openclaw/workspace-dba-scout/t.lobster",
  "timeoutMs": 60000,
  "maxStdoutBytes": 512000
}

If you get 401, the workflow still isn’t inheriting OPENCLAW_TOKEN; temporarily add it under env: to confirm, then move it into the service env properly.

distant stump
#

which env file should I put these in?

gentle vaporBOT
#

Put it in the gateway’s global env file:

nano ~/.openclaw/.env

Add:

OPENCLAW_URL=http://127.0.0.1:18789
OPENCLAW_TOKEN=your-token-here

Then restart the gateway:

#
openclaw gateway restart

That’s the right place for a long-running gateway/service. OpenClaw reads ~/.openclaw/.env as the global fallback env file, and workflow shell steps should then inherit it.

Two notes:

  • Don’t put this in the workspace .env (~/.openclaw/workspace-dba-scout/.env). OpenClaw blocks OPENCLAW_* vars from untrusted workspace .env files for safety.
  • Lock it down:
chmod 600 ~/.openclaw/.env

Then rerun the workflow.

distant stump
#

I ran the workflow but got this error
The lobster tool failed with this exact error:

Workflow step normalize_result requires run, command, pipeline, approval, or input

This suggests the pipeline file at /home/admin/.openclaw/workspace-dba-scout/t.lobster has a step named normalize_result that's missing a required action field. The pipeline itself may be malformed or incomplete. Want me to take a look at the file to diagnose further?

gentle vaporBOT
#

Yep — that usually means YAML indentation/paste got mangled around normalize_result, or this Lobster build is happier with command: than run:.

Replace the whole file with this version using command: everywhere:

name: t

env:
  OPENCLAW_URL: http://127.0.0.1:18789

steps:
  - id: classify_lead
    command: >-
      openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'

  - id: normalize_result
#
    command: >-
      node -e 'let s=""; process.stdin.on("data", c => s += c); process.stdin.on("end", () => { const raw = JSON.parse(s); const json = Array.isArray(raw) ? raw[0].details.json : raw.details.json; console.log(JSON.stringify({ company: json.company, fit: json.fit, priority: Number(json.priority), reason: json.reason }, null, 2)); })'
    stdin: $classify_lead.stdout

  - id: draft_outreach
    command: >-
      node -e 'let s=""; process.stdin.on("data", c => s += c); process.stdin.on("end", () => { const lead = JSON.parse(s); const draft = { subject: "Quick idea for " + lead.company, body: "Hi — noticed " + lead.company + " may benefit from faster missed-call followup and appointment reminders. Based on the lead notes, this looks like a " + lead.fit + "-fit opportunity with priority " + lead.priority + ". Worth a quick chat?", lead }; console.log(JSON.stringify(draft, null, 2)); })'
    stdin: $normalize_result.stdout

  - id: review_draft
    command: cat
    stdin: $draft_outreach.stdout
    approval: required

  - id: final_output
#
    command: cat
    stdin: $draft_outreach.stdout
    condition: $review_draft.approved

Two things to check carefully:

  • command: must be indented exactly under - id: normalize_result
  • stdin: must line up with command:, not be nested under it

Then rerun the same Telegram prompt. If it still fails, paste just the normalize_result block from your actual file.

distant stump
#

I get this error

Here's the exact error from the lobster tool:

workflow command failed (1): openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'

The pipeline at /home/admin/.openclaw/workspace-dba-scout/t.lobster exited with status code 1. It's trying to invoke an llm-task to classify a sales lead ("Acme Dental") but the underlying openclaw.invoke call is failing — likely the llm-task tool call itself errored out (possibly a model/auth issue or the task timed out). Want me to look at the pipeline file to debug further?

gentle vaporBOT
#

That error is still Lobster hiding the real openclaw.invoke stderr. Since the exact same invoke worked manually, the most likely issue is: the workflow process still doesn’t have OPENCLAW_TOKEN.

Two fixes/checks:

  1. In ~/.openclaw/.env, set both names:
OPENCLAW_URL=http://127.0.0.1:18789
OPENCLAW_TOKEN=your-token-here
OPENCLAW_GATEWAY_TOKEN=your-token-here

Then:

chmod 600 ~/.openclaw/.env
#
openclaw gateway restart
  1. Temporarily replace the first step with this debug wrapper so we can see the actual error without leaking the token:
  - id: classify_lead
    command: >-
      sh -lc 'echo "OPENCLAW_URL=${OPENCLAW_URL:-missing}" >&2; if [ -z "$OPENCLAW_TOKEN" ]; then echo "OPENCLAW_TOKEN=missing" >&2; else echo "OPENCLAW_TOKEN=set" >&2; fi; openclaw.invoke --tool llm-task --action json --args-json '\''{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'\'''

Then run the workflow while tailing logs:

openclaw logs --follow
#

If logs show OPENCLAW_TOKEN=missing, the gateway didn’t load the env file. If it shows OPENCLAW_TOKEN=set but still fails, the next log line should show the real openclaw.invoke error.

distant stump
#

This is the error from openclaw logs
09:47:59
debug
tools: lobster failed stack:
Error: workflow command failed (1): openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'
at throwOnErrorEnvelope (/home/admin/.openclaw/npm/node_modules/@openclaw/lobster/dist/index.js:175:9)
at /home/admin/.openclaw/npm/node_modules/@openclaw/lobster/dist/index.js:276:20
09:47:59
error
[tools] lobster failed: workflow command failed (1): openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}' raw_params={"action":"run","pipeline":"/home/admin/.openclaw/workspace-dba-scout/t.lobster","timeoutMs":60000,"maxStdoutBytes":512000}

gentle vaporBOT
#

That log is still only Lobster’s wrapper error — it isn’t showing the actual openclaw.invoke stderr. Let’s make the workflow print the inner error directly.

Temporarily replace t.lobster with this debug-only version:

name: t-debug

env:
  OPENCLAW_URL: http://127.0.0.1:18789

steps:
  - id: debug_invoke
    command: >-
      sh -lc 'echo "OPENCLAW_URL=${OPENCLAW_URL:-missing}"; if [ -z "$OPENCLAW_TOKEN" ]; then echo "OPENCLAW_TOKEN=missing"; else echo "OPENCLAW_TOKEN=set"; fi; openclaw.invoke --tool llm-task --action json --args-json '\''{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'\'' 2>&1; echo "exit_code=$?"'

Important: this intentionally does not fail the workflow; it prints the real inner error/result instead.

#

Run the same Telegram prompt again. The output should say one of:

  • OPENCLAW_TOKEN=missing → gateway service isn’t inheriting your token env
  • 401 Unauthorized → token value isn’t reaching/valid
  • 500 tool execution failed → then check logs for the llm-task schema/model error
  • JSON result → invoke is working inside Lobster, and we can restore the normal multi-step file

If it says token missing, easiest confirmation is to add this under env: temporarily:

  OPENCLAW_TOKEN: your-token-here

Treat that file as secret if you do that.

distant stump
#

I ran it and got this

Same result as before:

• Lobster tool: ok: true, status: ok (the runtime itself succeeded)
• Pipeline exit code: 1 (the command inside failed)
• Output: OPENCLAW_URL=http://127.0.0.1:18789, OPENCLAW_TOKEN=***, exit_code=1

The openclaw.invoke command inside the pipeline is failing with exit code 1. The token is set (masked in output), so it's not a missing-token issue. The failure is likely from the llm-task tool call itself — possibly the model isn't available, auth is wrong, or the tool invocation is failing for another reason.

gentle vaporBOT
#

Good debug result: token is present, but we still don’t have the actual openclaw.invoke stderr. Let’s force it into files and print it back.

Replace t.lobster temporarily with this:

name: t-debug

env:
  OPENCLAW_URL: http://127.0.0.1:18789

steps:
  - id: debug_invoke
    command: >-
      sh -lc 'rm -f /tmp/oc-invoke.out /tmp/oc-invoke.err; echo "OPENCLAW_URL=${OPENCLAW_URL:-missing}"; if [ -z "$OPENCLAW_TOKEN" ]; then echo "OPENCLAW_TOKEN=missing"; else echo "OPENCLAW_TOKEN=set length=${#OPENCLAW_TOKEN}"; fi; command -v openclaw.invoke; openclaw.invoke --tool llm-task --action json --args-json '\''{"prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'\'' >/tmp/oc-invoke.out 2>/tmp/oc-invoke.err; code=$?; echo "exit_code=$code"; echo "--- stdout ---"; cat /tmp/oc-invoke.out 2>/dev/null || true; echo "--- stderr ---"; cat /tmp/oc-invoke.err 2>/dev/null || true; exit 0'

Run the same Telegram prompt again. This should show the real error under --- stderr ---.

#

Two likely outcomes:

  • 401 Unauthorized even though token is set → the token in the workflow env is not the same token your gateway expects. Re-copy it into ~/.openclaw/.env, restart gateway, retry.
  • 500 tool execution failed → openclaw.invoke is reaching the gateway and auth is fine; then tail logs immediately after this run for the actual llm-task error.

Also: since the same openclaw.invoke worked manually, compare the token length from this workflow output with your shell:

echo ${#OPENCLAW_TOKEN}

If the lengths differ, the gateway workflow is using an older/different token from ~/.openclaw/.env.

distant stump
#

ame result:

• Lobster tool: ok: true, status: ok
• Pipeline exit code: 1
• Output: OPENCLAW_URL=http://127.0.0.1:18789, OPENCLAW_TOKEN=set length=48, /usr/local/bin/openclaw.invoke, exit_code=1
• Stdout/stderr: empty

The openclaw.invoke command is failing silently — no error output at all. The token is set (48 chars) and the URL is correct, but the command produces no output and exits with code 1.

gentle vaporBOT
#

Aha — silent exit code 1 with empty stdout/stderr points to the openclaw.invoke shim itself failing before it can print anything.

The shim is not the real invoker; it internally runs the lobster binary. So inside the workflow environment, /usr/local/bin/openclaw.invoke is found, but lobster probably is not in PATH.

Fix by symlinking lobster too:

command -v lobster
ls -l /usr/local/bin/openclaw.invoke

sudo ln -sf "$(command -v lobster)" /usr/local/bin/lobster
sudo ln -sf "$(command -v openclaw.invoke)" /usr/local/bin/openclaw.invoke
sudo ln -sf "$(command -v clawd.invoke)" /usr/local/bin/clawd.invoke

/usr/local/bin/lobster --help | head
/usr/local/bin/openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'
#

openclaw gateway restart

Then run the workflow again.

If you want to confirm before changing anything, make the debug workflow run this:

command: >-
  sh -lc 'echo PATH=$PATH; command -v openclaw.invoke || true; command -v lobster || true; /usr/local/bin/openclaw.invoke --tool llm-task --action json --args-json '\''{"prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'\'' 2>&1; echo exit_code=$?'

If command -v lobster is blank, that’s the bug.

distant stump
#

ok, finally everything is working as expected

gentle vaporBOT
#

Yesss, excellent — that was a proper gauntlet. 🦞

Final working checklist for future readers:

  • install/enable the OpenClaw lobster plugin
  • install the standalone Lobster CLI/shims (@clawdbot/lobster currently provides openclaw.invoke)
  • ensure openclaw.invoke, clawd.invoke, and lobster are all on the Gateway service PATH, or symlink them into /usr/local/bin
  • set OPENCLAW_URL + OPENCLAW_TOKEN in ~/.openclaw/.env
  • use a schema the model reliably satisfies

If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow indexes the solution for the next person.