HELLO WORLD
In this tutorial, we will install swamp, initialize a repository, then use Claude Code to create models, extend swamp with new functionality, and run a workflow.
What we will build
We are going to set up a swamp project, ask Claude Code to create a model called
hello-world, run it, then add a random weather report and wire everything into
a workflow.
Install swamp
Open your terminal and run:
$ curl -fsSL https://swamp.club/install.sh | shOnce it finishes, verify the installation:
$ swamp versionYou should see output like:
info version swamp "20260206.200442.0-sha...."If the command is not found, restart your shell or add ~/.local/bin to your
PATH.
Initialize a repository
Create a new directory and initialize it as a swamp repo:
$ mkdir my-swamp-project
$ cd my-swamp-project
$ swamp repo initYou will see the swamp banner:
███████╗██╗ ██╗ █████╗ ███╗ ███╗██████╗
██╔════╝██║ ██║██╔══██╗████╗ ████║██╔══██╗
███████╗██║ █╗ ██║███████║██╔████╔██║██████╔╝
╚════██║██║███╗██║██╔══██║██║╚██╔╝██║██╔═══╝
███████║╚███╔███╔╝██║ ██║██║ ╚═╝ ██║██║
╚══════╝ ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝
╔═══════════════════════════════════════════╗
║ WELCOME TO THE CLUB ║
║ for hackers, by hackers ║
╚═══════════════════════════════════════════╝
info repo·init Initialized swamp repository at "..." (tool: "claude")Notice what swamp created:
$ ls -a
. .. .claude CLAUDE.md .gitignore models .swamp .swamp.yaml vaults workflowsNotice the .claude/ directory and CLAUDE.md file — these are what let Claude
Code work with swamp automatically. The .swamp/ directory is where all
versioned data will be stored.
Create a model with Claude Code
Note
You will need an AI Agent to work with Swamp. This tutorial assumes you will use Claude Code, but you can use any agent you like.
Open Claude Code in your project directory in a new terminal. Since we ran
swamp repo init, Claude Code already has the swamp skills loaded. Ask it:
Create a model called hello-world that echoes "Hello from the swamp!"Claude Code will create the model. You will see it create a file under
models/command/shell/ with the echo command configured.
Run the model
Back in your terminal, run the model:
$ swamp model method run hello-world executeYou will see output like:
info model·method·run·hello-world·execute Found model "hello-world" ("command/shell")
info model·method·run·hello-world·execute Evaluating expressions
info model·method·run·hello-world·execute Executing method "execute"
info model·method·run·hello-world·execute Hello from the swamp!
info model·method·run·hello-world·execute Data saved to ".swamp/data/..."
info model·method·run·hello-world·execute Data saved to ".swamp/data/..."
info model·method·run·hello-world·execute Running report: "@swamp/method-summary"
── Report: @swamp/method-summary ──────────────────────────────────────
# hello-world (command/shell) → execute: succeeded
execute on hello-world (command/shell) succeeded, producing 1 resource
(result), 1 file (log).
## Data Output
┌────────┬──────────┬───────────────────────────────────────────────┐
│ Name │ Kind │ Retrieval Command │
├────────┼──────────┼───────────────────────────────────────────────┤
│ result │ resource │ swamp data get hello-world result --version 1 │
├────────┼──────────┼───────────────────────────────────────────────┤
│ log │ file │ swamp data get hello-world log --version 1 │
└────────┴──────────┴───────────────────────────────────────────────┘
───────────────────────────────────────────────────────────────────────
info model·method·run·hello-world·execute Method "execute" completed
on "hello-world"Notice the Hello from the swamp! line in the output, and the method summary
report listing the data that was saved.
Query the stored data
Now query the data that swamp stored:
$ swamp data query 'modelName == "hello-world"'You will see output like:
┌────────┬─────────────┬──────────┬──────────┬─────────┬──────┐
│ name │ modelName │ specName │ dataType │ version │ size │
├────────┼─────────────┼──────────┼──────────┼─────────┼──────┤
│ log │ hello-world │ log │ file │ 1 │ 30B │
├────────┼─────────────┼──────────┼──────────┼─────────┼──────┤
│ result │ hello-world │ result │ resource │ 1 │ 155B │
└────────┴─────────────┴──────────┴──────────┴─────────┴──────┘
2 resultsNotice the two data artifacts — result and log — matching what the method
summary reported.
Now query just the stdout from the result:
$ swamp data query \
'modelName == "hello-world" && specName == "result"' \
--select 'attributes.stdout'You will see output like:
Hello from the swamp!Compose a workflow
Now we will add a weather report and wire everything into a workflow. Ask Claude Code:
Create a new extension model type named @tutorial/random-status
that randomly returns one of a list of statuses. The extension
should store the selected status in a resource named "output"
with a "status" property. Then create a model called
weather-report that uses it to return one of: murky, misty,
gloomy, stinky and humid. Then create a model called
morning-message that takes the hello-world stdout and the
weather-report status as inputs and echoes "{hello world} The
weather is {status} - best to stay inside." Create a workflow
called swamp-morning with two jobs: a "gather" job that runs
hello-world and weather-report, and a "combine" job that
depends on gather and runs morning-message.Notice that we asked for functionality that does not exist yet — random weather
selection. Claude Code will create the extension, the models, and the workflow.
You will see new files appear under extensions/, models/, and workflows/.
Run the workflow
Back in your terminal:
$ swamp workflow run swamp-morningYou will see output like:
gather ✓2 steps
│ [hello-world → execute]
│ Hello from the swamp!
...
│ [weather-report → run]
...
combine ✓morning-message → execute
│ Hello from the swamp! The weather is gloomy - best to stay inside.
...
── @swamp/workflow-summary ─────────────────────────────────
# swamp-morning: succeeded
3 succeeded · 0 failed · 0 skipped
## Job: gather (succeeded)
┌────────────────┬───────────────────────┬───────────┐
│ Step │ Model │ Status │
├────────────────┼───────────────────────┼───────────┤
│ weather-report │ weather-report → run │ succeeded │
├────────────────┼───────────────────────┼───────────┤
│ hello-world │ hello-world → execute │ succeeded │
└────────────────┴───────────────────────┴───────────┘
## Job: combine (succeeded)
┌─────────────────┬───────────────────────────┬───────────┐
│ Step │ Model │ Status │
├─────────────────┼───────────────────────────┼───────────┤
│ morning-message │ morning-message → execute │ succeeded │
└─────────────────┴───────────────────────────┴───────────┘Notice that gather ran hello-world and weather-report in parallel, then
combine ran after both succeeded. The weather status will be different each
time you run the workflow.
Query the final result
$ swamp data query \
'modelName == "morning-message" && specName == "result"' \
--select 'attributes.stdout'You will see output like:
Hello from the swamp! The weather is misty - best to stay inside.You have installed swamp, created models with Claude Code, composed them into a
workflow with dependencies, and queried the stored results. Every execution is
versioned data in .swamp/.