Quickstart
This walkthrough takes you from an empty directory to a running, inspectable agent capsule using nothing but a manifest. You declare what the capsule depends on and is allowed to do, install those dependencies, hand it a task, run it, and read back exactly what it did. Everything the capsule can reach is declared up front — nothing else is permitted.
The relevant manifest options are:
| Option | Controls |
|---|---|
| artifacts[].runtime | Whether a declared artifact is a driver, tool, hook, or skill |
| capabilities.network.allow | Which hosts the capsule may reach |
| inference.driver.artifact | Which driver artifact performs the model calls |
| inference.model | Which model the driver calls |
Step 1 — declare the capsule in murmur.yaml
Create a murmur.yaml file. A minimal agent capsule declares its identity, one driver artifact, the API host it is allowed to reach, and how inference is configured:
name: my-agent
version: "0.1.0"
artifacts:
- name: murmur-driver-anthropic
version: "1.0.0"
runtime: driver
capabilities:
network:
allow:
- https://api.anthropic.com
inference:
transport: http
endpoint: https://api.anthropic.com
model: claude-sonnet-5
api_key: ${ANTHROPIC_API_KEY}
driver:
artifact: murmur-driver-anthropic
name: my-agent
version: "0.1.0"
artifacts:
- name: murmur-driver-openai
version: "1.0.0"
runtime: driver
capabilities:
network:
allow:
- https://api.openai.com
inference:
transport: http
endpoint: https://api.openai.com
model: o3-mini-high
api_key: ${OPENAI_API_KEY}
driver:
artifact: murmur-driver-openai
name: my-agent
version: "0.1.0"
artifacts:
- name: murmur-driver-deepseek
version: "1.0.0"
runtime: driver
capabilities:
network:
allow:
- https://api.deepseek.com
inference:
transport: http
endpoint: https://api.deepseek.com
model: deepseek-r1
api_key: ${DEEPSEEK_API_KEY}
driver:
artifact: murmur-driver-deepseek
The api_key field reads from the environment at run time. Export your provider key in the shell you will run from:
export ANTHROPIC_API_KEY=sk-ant-...
This manifest is the entire contract. The capsule can call the one host listed under capabilities.network.allow and nothing else — no shell, no filesystem, no other network destinations, because none are declared.
Step 2 — install the declared artifacts
mur install reads murmur.yaml, resolves every artifact declared in it, and fetches them in parallel into the project-local store. Run it once before the first run:
mur install
Different ways to install artifacts
mur install needs to know where to fetch artifacts from. You have two options:
Option A — configure a registry source in ~/.murmur/config.yaml:
registry:
default: official
sources:
- name: official
type: github
repo: <owner>/<repo>
token: "${GITHUB_TOKEN}"
Then install by artifact name and version:
mur install <artifact-name@version>
Option B — pass a full GitHub reference and skip configuration entirely:
mur install github:<username>/<repo>@<tag>
See Installing artifacts to learn more.
mur run verifies that every declared artifact is installed before it starts. Skipping this step makes the next one exit immediately with error[E-RUN-008] and an install hint.
Step 3 — write the task
Create a task.md file describing what the agent should do. With this minimal manifest the capsule has inference only — no tools — so keep the first task to something the model can answer directly:
Explain what makes an infrastructure deployment reproducible, in three bullet points.
Step 4 — run the capsule
Pass the task file with --task. mur run stages the declared artifacts, copies task.md into the capsule's working directory, starts the capsule's local HTTP server, and drives the agent loop to completion:
mur run --task task.md
murmur: url localhost:52222
session: ses_019ed2af53da75c2aefee84ee10c34af
status: ok
The session: value identifies this run. Everything the run produces lands under workdir/<session_id>/: the task input (task.md), the model's final text (out/result.txt), the structured trace (trace.jsonl), and runtime logs (logs/). The session workdir is the single place to look — read the result directly with:
cat workdir/*/out/result.txt
Step 5 — inspect the run
Every session writes a structured trace.jsonl under its workdir. mur trace show reads the most recent one and prints a human-readable summary — turns, token usage, tool calls, and exit status:
mur trace show
Different ways to identify a session
mur trace show locates a session three ways:
No argument — most recent session:
mur trace show
Finds the lexicographically largest ses_* entry in workdir/ — always the most recently created session, because session IDs are UUID v7 (time-ordered).
Short suffix — type the last few characters:
mur trace show 3e4b
Matches any session whose ID ends with the given string. Use 4 or more characters to avoid ambiguity. Matching is case-insensitive. If the suffix matches more than one session, mur lists the candidates and asks you to be more specific.
Full session ID:
mur trace show ses_6801f81dd28b4a9daf434e8324c4793e
Resolves the session directly without scanning workdir/.
Legacy file path:
mur trace show path/to/trace.jsonl
Any argument containing / or ending in .jsonl is treated as a literal file path. Kept for backward compatibility.
Use --workdir <path> if your session directory is not ./workdir.
Other trace exploration commands
mur trace has four subcommands for exploring session output:
mur trace show — print the full trace for a session to the terminal. Accepts a session ID, suffix, or no argument (most recent session).
mur trace steps — show a turn-by-turn summary of what the agent did in a session. Pass --verbose to include a truncated summary of each tool's input.
mur trace diff — compare the traces of two sessions side by side. Useful for spotting behavioural regressions between runs.
mur trace report — generate a structured summary report from a session's trace. Covers token usage, tool calls, latency, and other session-level metrics.
The trace is written by the runtime, not the capsule, so it exists after every session and cannot be suppressed or falsified by the agent. It is the authoritative record of what the run actually did.
Summary
| Step | Command | What it does |
|---|---|---|
| Declare | edit murmur.yaml |
Pins the driver artifact, the allowed host, and the model — the capsule's whole contract |
| Install | mur install |
Fetches every artifact declared in murmur.yaml into the project-local store |
| Run | mur run --task task.md |
Stages the artifacts, feeds in task.md, and drives the agent loop to completion |
| Inspect | mur trace show |
Prints the runtime-written trace for the most recent session |
Pin every artifact to an exact version and the manifest becomes an execution contract you can audit, roll forward, and roll back. From here, grant more capabilities: lock down its capabilities, shape its behavior with a system prompt, or connect two capsules.
Want to use a subscription?
Instead of a driver artifact and an API key, a capsule can drive inference through a provider CLI you are already logged into — the Claude CLI (Anthropic) or the Codex CLI (OpenAI). Set inference.transport: process and point command at the CLI — no driver artifact, no capabilities.network, and no API key.
This is a secondary path for spending a subscription rather than an API key; transport: http remains the primary, fuller-featured way to run a capsule.
Create a manifest
Create a murmur.yaml in an empty directory, using the CLI for the subscription you are logged into:
name: my-capsule
version: "1.0.0"
inference:
transport: process
command: claude
model: claude-opus-4-8 # optional — omit to use your subscription's default
max_turns: 10
name: my-capsule
version: "1.0.0"
inference:
transport: process
command: codex
model: gpt-5.5 # optional — omit to use your subscription's default
max_turns: 10
Run the capsule
In the same directory, run the capsule with a task passed inline:
mur run --task "When I say Ping you say?"
Inspect the capsule's output at workdir/<session_id>/out/result.txt, for example:
> cat workdir/*/out/result.txt
Pong! 🏓
Calling tools
Tool artifacts work under transport: process too — declare them exactly as you would for transport: http, and mur trace show records each tool call. max_turns counts one turn per model step here just as it does on transport: http — roughly one per tool call plus a final turn — so budget it the same way (a too-low limit fails with error[E-RUN-007]: max_turns exceeded).
Observability differs from transport: http
Because the CLI owns the model calls, mur trace show records turns, tool calls, declared tools, and exit status — but not per-turn token usage. When you need full token accounting, use transport: http. System prompts and lifecycle hooks apply on both paths.
Learn more about the murmur.yaml manifest in the Manifest Schema reference.