# openclaw/lobster: a typed workflow shell for OpenClaw agents

> Lobster is an MIT-licensed TypeScript workflow runtime that turns skills and CLI tools into typed, local-first pipelines with approval gates. It fits teams already running OpenClaw who want deterministic, resumable steps instead of re-planning every call.

**openclaw/lobster** — Lobster is a Openclaw-native workflow shell: a typed, local-first macro engine that turns skills/tools into composable pipelines and safe automations-and lets Openclaw call those workflows in one step.

- Repository: https://github.com/openclaw/lobster
- Website: https://docs.openclaw.ai/tools/lobster
- Stars: 1,266 · Forks: 289
- Language: TypeScript
- License: MIT
- Published: 2026-08-08 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/openclaw-lobster

## What Lobster is for, and who it is not for

An agent that re-plans a multi-step job on every invocation spends tokens on reasoning it already did. Lobster's stated goal is to let OpenClaw, or any other agent, call a workflow as a single step, so the plan is written once and executed deterministically. The README frames this as saving tokens while improving determinism and resumability.

The intended user is someone who already has an agent host and a set of CLI tools or skills, and wants those tools composed into named workflows rather than re-derived each time. The README's own example is a GitHub PR monitor: the same command returns a structured object with a changed flag, a list of changed fields, and a snapshot. That is a shape a program can branch on, which is the point.

It is not a general automation platform. The goals section is explicit that Lobster must not own OAuth or tokens, so it adds no new auth surface. If your problem is credential management or scheduling across many machines, this is the wrong layer. It also assumes a working Node and pnpm toolchain, since the quick start is a pnpm project.

## Typed pipelines instead of text pipes

The first goal in the README is typed pipelines (objects and arrays), not text pipes. Unix pipes move bytes and leave parsing to the consumer. Lobster stages move structured values, so a downstream step can reference a field rather than grep a line. The renderers json and table exist because the terminal still needs a text view, not because the pipeline is text.

Data flows between steps through stdin bindings. In a workflow file you write stdin: $step.stdout or stdin: $step.json to pass a previous step's output forward. The distinction matters: one gives you the raw stream, the other the parsed value. Conditional execution uses when: or condition: expressions, and the graph command later reads those same references to draw data-flow edges.

Shaping commands are deliberately small: where, pick and head. where '0>=0' in the quick start is a filter expression evaluated against the pipeline value. There is no general-purpose programming language here, and that is a design choice rather than a gap: the workflow file is meant to read like a small script, with run: or command: for shell and CLI steps and pipeline: for native stages.

## Installing Lobster and running a first pipeline

The README gives install steps from the repository folder. pnpm install pulls dependencies, and the test script runs tsc before executing tests against dist/, so a passing test run also confirms the TypeScript build. Note that bin/lobster.js prefers the compiled entrypoint in dist/ when present, which means an unbuilt checkout and a built one can behave differently.

```bash
pnpm install
pnpm test
pnpm lint
node ./bin/lobster.js --help
node ./bin/lobster.js doctor
```

After those, the doctor subcommand is the cheap sanity check before you write anything. The first real pipeline is a one-liner that runs a shell command, filters the result and renders it as JSON:

```bash
node ./bin/lobster.js "exec --json --shell 'echo [1,2,3]' | where '0>=0' | json"
```

You should see the array printed as JSON rather than as a raw string. The exec stage parses the subprocess output because --json was passed, where applies the expression, and json renders. If that works, the toolchain is wired correctly. For anything longer, put the steps in a workflow file and run it with the file flag, passing arguments as JSON:

```bash
lobster run --file path/to/workflow.lobster --args-json '{"tag":"family"}'
```

Before executing a workflow you have not read closely, the graph command prints the structure. It takes the same file and args, and can emit mermaid, dot or ascii:

```bash
lobster graph --file path/to/workflow.lobster --format ascii
```

The ascii form gives a terminal-friendly node and edge list, which is the fastest way to confirm that your stdin references actually connect the steps you think they do.

## Approval gates and the identity constraints behind them

Approval is a first-class step type, not a prompt buried inside a pipeline. The README recommends a dedicated approval: step in the workflow file rather than calling approve inside a nested pipeline when you need a human checkpoint before an LLM call. The jacket-advice example shows the pattern: fetch weather, gate on confirm, then run the LLM step with when: $confirm.approved.

Identity constraints are the part worth reading twice. approval.required_approver (or requiredApprover) demands an exact approver id. approval.require_different_approver (or requireDifferentApprover) requires the approver id to differ from the initiator, and approval.initiated_by (or initiatedBy) sets that initiator. Two environment variables feed these checks: LOBSTER_APPROVAL_INITIATED_BY supplies a default initiator at run time, and LOBSTER_APPROVAL_APPROVED_BY is used at resume time.

The camelCase aliases exist alongside snake_case keys, which suggests the file format was extended after the YAML keys were already in use. Pick one spelling per file; mixing them in the same workflow invites confusion during review. The approve command also has an --emit mode described as being for OpenClaw integration, which is how a non-TTY host drives the gate.

## requestInput, resume semantics, and the idempotency tax

The most consequential mechanism in the documentation is ctx.requestInput({ prompt, responseSchema, defaults, subject, suspendedState }). A pipeline command calls it to pause, in tool mode, in workflows, or in the SDK, and resumes the same command after a structured response arrives. Response validation happens against the suspended request metadata before the submitted response is handed back to the command.

Here is the constraint that should decide whether you adopt Lobster. Commands are re-run on resume, so they must be idempotent until requestInput returns. A step that appends to a file, charges a card or posts a comment before pausing will do it again. The documentation states this plainly, and it is not a bug you can configure away.

There is a second asymmetry. Array-backed command input is snapshotted with bounds for replay, but lazy stream input is not buffered and requires a compact JSON suspendedState supplied by the command. On resume, the command must call ctx.requestInput.getSuspendedState() before reading lazy input to restore its own continuation state. A workflow that reads a large stream and then pauses is therefore harder to make correct than one that works on a bounded array. Resume tokens on the CLI and tool path store only a state key; SDK same-command resumes store the command frame in the configured SDK state directory, so where that state lives is a deployment decision.

## Calling models, and where Lobster stops

Model work goes through llm.invoke from a native pipeline: step. Provider resolution follows a fixed order: the --provider flag, then LOBSTER_LLM_PROVIDER, then auto-detection from the environment. Three providers are built in. openclaw reads OPENCLAW_URL and OPENCLAW_TOKEN, pi reads LOBSTER_PI_LLM_ADAPTER_URL and is typically supplied by the Pi extension, and http reads LOBSTER_LLM_ADAPTER_URL.

```bash
llm.invoke --provider openclaw --prompt 'Summarize this diff'
```

The README notes that a host embedding Lobster can supply its own adapters through ctx.llmAdapter, which is the extension point for anything outside those three. That is a narrow provider list, and it is consistent with the no-new-auth-surface goal: Lobster does not want to hold credentials, so it borrows the host's.

Compare this with a general workflow orchestrator such as Temporal or n8n. Those own scheduling, retries across processes, and their own credential stores. Lobster runs locally, keeps no auth of its own, and expects an agent host to be the thing that decides when to call it. The trade is deliberate, and it means Lobster is a poor fit if what you actually need is durable distributed execution with a queue behind it. Per-step retry, timeout_ms and on_error cover transient failures within a run; they do not make the run itself durable across a machine restart.

## Licence, maintenance and what an upgrade costs

The project is MIT-licensed, and the package.json declares license: MIT with bin entries for lobster, clawd.invoke and openclaw.invoke. MIT permits commercial use and modification with the copyright notice retained; it offers no patent grant and no warranty. That is a statement about the licence text, not legal advice for your situation.

The published package is @clawdbot/lobster while the repository is openclaw/lobster, so the npm name and the repo name do not match. Exports are split into "." and "./sdk" pointing at the same SDK entry, plus "./core" and "./recipes/github". Anything you import from ./core or ./recipes/github is a deeper surface than the SDK entry, and deeper surfaces tend to move faster.

The most recent push was on 2026-06-11, which is more than three months before today, and the latest release tag is v2026.6.11 from the same date. Package.json carries version 2026.9.13. Treat the cadence as steady but not continuous: releases are dated 2026-04-06, 2026-05-22 and 2026-06-11, roughly monthly, and the README still lists OpenClaw integration as a next step to ship as an optional plugin tool. The upgrade cost is mostly in workflow files rather than in the library: a workflow that mixes approval key spellings, or that depends on lazy stream input surviving a resume, is the one that will need attention. Run pnpm test after upgrading, since it typechecks before executing, and re-run lobster graph on your files to confirm the edges still line up.

## Conclusion

Adopt Lobster if you already run OpenClaw or another agent host and want the same multi-step job to produce the same shape of output twice, with a human checkpoint before anything irreversible. Skip it if your automation is a single shell command, or if you cannot accept that commands re-run on resume and must therefore be idempotent. Verify first that the provider your workflow needs is among the built-in ones (openclaw, pi, http) or that your host can inject its own adapter through ctx.llmAdapter, and check whether the workflow you plan to port relies on lazy stream input, which is not buffered for replay.

## FAQ

### How do I install openclaw/lobster?

From the repository folder, run pnpm install, then pnpm test and pnpm lint to confirm the build. The README also suggests node ./bin/lobster.js --help and node ./bin/lobster.js doctor as the first checks.

### Does openclaw/lobster store OAuth tokens or credentials?

No. One of the stated goals is that Lobster must not own OAuth or tokens and adds no new auth surface. Model calls borrow the host's credentials, for example openclaw reads OPENCLAW_URL and OPENCLAW_TOKEN.

### What happens to a Lobster command after it pauses for input?

Commands are re-run on resume, so they must be idempotent until ctx.requestInput returns. Array-backed input is snapshotted with bounds for replay, while lazy stream input is not buffered and requires a compact JSON suspendedState supplied by the command.

### Which LLM providers can a Lobster workflow call?

Three are built in: openclaw, pi and http. Resolution order is the --provider flag, then LOBSTER_LLM_PROVIDER, then auto-detection from the environment, and a host embedding Lobster can supply its own adapters through ctx.llmAdapter.

## Sources

- [Official documentation](https://docs.openclaw.ai/tools/lobster)
- [Official README](https://github.com/openclaw/lobster#readme)
- [Project repository](https://github.com/openclaw/lobster)
- [Release notes](https://github.com/openclaw/lobster/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/openclaw-lobster
