Skip to main content

REMOTE EXECUTION

In this tutorial, we will mint an enrollment token, start the Swamp orchestrator, connect a worker, and run a workflow step on that worker. By the end you will have a local orchestrator dispatching work to a separate worker process.

What we will build

We will create a model that echoes a message, place it on a worker using the target: field in a workflow step, and watch the orchestrator route the execution to the connected worker.

Before we start

This tutorial assumes:

  • Swamp is installed. If not, run curl -fsSL https://swamp-club.com/install.sh | sh.
  • You have a Swamp repository with at least one vault configured. The hello-world tutorial covers both of these. If you already have a repo with a vault, use that.

Create an enrollment token

Workers authenticate with the orchestrator using enrollment tokens. Tokens are one-time secrets stored in your vault. Open a terminal in your Swamp repo and create one:

$ swamp worker token create build-node --duration 1h

You should see output like:

Token: build-node
Expires: 2026-06-15T11:34:58.961Z
Vault: sandbox-vault (key worker-token-build-node)

  build-node.5c40afd8d0f90c70f521d18861e0ec89a3ddc2f8a3dd49329c6aec87a1f0bc55

This token is shown once and will not be displayed again — store it now.

Copy the full token string (the line starting with build-node.). You will need it when connecting the worker.

Confirm the token exists:

$ swamp worker token list

You should see:

NAME        STATE   EXPIRES                   BOUND MACHINE
build-node  unused  2026-06-15T11:34:58.961Z  -

Notice the unused state and the empty BOUND MACHINE column. The token has not been claimed by a worker yet.

Start the orchestrator

The orchestrator listens for worker connections and dispatches placed steps. In the same terminal, start it:

$ swamp serve

Leave this terminal running. The orchestrator will log connections and step dispatches as they happen.

Connect a worker

Open a second terminal, navigate to the same Swamp repo, and connect a worker using the token you copied earlier:

$ swamp worker connect ws://localhost:9090 --token <token> --cache-dir /tmp/swamp-worker

Replace <token> with the full token string from the creation step.

The --cache-dir flag tells the worker where to store its identity and cached data. Without it, the worker gets a fresh identity each time it starts, which means the orchestrator treats it as a new machine on every restart. Pointing --cache-dir at a stable path lets the worker reconnect with the same identity across restarts.

If the connection succeeds, the worker logs that it has enrolled and is waiting for work. Back in the orchestrator terminal, you should see a log line indicating the worker connected. If you run swamp worker token list again, the token state changes to bound and the BOUND MACHINE column shows the worker's machine identifier.

Create a model

We need a simple model for the worker to execute. Create a command/shell model that echoes a message. Ask Claude Code:

Create a command/shell model called remote-echo that echoes "executed on a worker"

Verify the model works locally before placing it on the worker:

$ swamp model method run remote-echo execute

You should see executed on a worker in the output. The model works. Now we will route it through the orchestrator to the connected worker.

Create a workflow with a placed step

Create a workflow that targets the worker. Ask Claude Code:

Create a workflow called remote-demo with one job called build.
The job has one step called echo-on-worker that runs the
remote-echo model's execute method. The step should have a
target field set to "build-node" so it runs on the worker.

The resulting workflow YAML should look like this:

id: <generated-uuid>
name: remote-demo
description: Run a step on a remote worker
jobs:
  - name: build
    steps:
      - name: echo-on-worker
        target: build-node
        task:
          type: model_method
          modelIdOrName: remote-echo
          methodName: execute
version: 1

Notice the target: build-node field on the step. This tells the orchestrator to dispatch this step to a worker whose enrollment token name matches build-node. Without target, the step would run locally.

Run the workflow

With the orchestrator and worker still running in their terminals, open a third terminal and run the workflow:

$ swamp workflow run remote-demo

Watch the three terminals:

  1. Orchestrator — logs that it received the workflow run, matched the echo-on-worker step to the build-node worker, and dispatched it.
  2. Worker — logs that it received the step, executed the remote-echo model, and returned the result.
  3. Workflow runner — shows the step completing successfully, with output like:
build                                                           ✓echo-on-worker
│ executed on a worker
...
── @swamp/workflow-summary ─────────────────────────────────
# remote-demo: succeeded

1 succeeded · 0 failed · 0 skipped

The step ran on the worker, not locally. The orchestrator routed it based on the target field, the worker executed it, and the result flowed back through the orchestrator to the workflow runner.

Verify the stored data

Confirm the data was saved as usual:

$ swamp data query \
    'modelName == "remote-echo" && specName == "result"' \
    --select 'attributes.stdout'

You should see:

executed on a worker

Data produced by remote workers is stored in the same .swamp/data/ directory as locally executed steps. The workflow runner handles the transfer transparently.

Clean up

Stop the worker with Ctrl-C in its terminal, then stop the orchestrator with Ctrl-C in its terminal.


You have minted an enrollment token, started an orchestrator, connected a worker, placed a workflow step on that worker using target:, and observed the end-to-end execution. To understand how the orchestrator routes steps and how workers negotiate trust, see Remote Execution. For the full list of swamp worker and swamp serve flags, see the Worker Commands reference.