Skip to content

How to run a capsule on your Claude subscription

A capsule normally reaches a model over HTTPS with an API key you declare in its manifest. Under transport: process it instead drives a harness CLI you are already logged into — the claude binary on your machine — so the work is billed to that login rather than to a key. Murmur still owns the task, the tools, the trace and the A2A door; the harness owns the model calls and the conversation.

What is a process driver?

A process driver is a WASM artifact declared with runtime: driver that knows how to drive one harness CLI: which executable to run, which arguments to pass, how to read its output, and what its exit codes mean. Murmur's runtime holds none of that — it resolves a binary, moves bytes, and records what the driver says happened.

A process driver is granted nothing: no environment, no files, no network, and no Murmur host interface. murmur-driver-claude-code is the driver for the Claude CLI.

The relevant manifest options are:

Option Controls
inference.transport Whether the capsule calls a provider API or drives a harness subprocess
inference.driver.artifact The process driver artifact that knows this harness
inference.command The executable to run instead of the one the driver names
inference.max_turns How many model steps one task may take
inference.system_prompt_file The instructions the agent runs under
capabilities.env.allow Every environment variable the harness process may see
lifecycle.conversation Whether tasks in one context continue the same harness session

What this transport costs you

Read this before you choose it. Four things are true here that are not true of transport: http.

Cost What it means
The harness process is not contained Unlike a WASM artifact, the claude process runs on the host with the host network and your real home directory. Murmur controls the environment it starts with and the tools it is offered, not what the process can reach once running.
The capsule depends on your machine It runs on your login and on whichever claude version is installed. The manifest pins neither, so the same manifest on two machines is not the same capsule.
Spend is invisible to Murmur The harness reaches its provider with its own credentials, so no request passes through Murmur. inference.max_session_tokens is a manifest error here, spend.machine_tokens_per_day does not cover this capsule, and every token count in the trace is reported as zero.
Your own configuration does not load The driver launches the harness with --setting-sources "", so your CLAUDE.md, your settings and your hooks are not read. The agent's instructions come from the manifest alone.

A capsule that ran on a subscription and reported zero tokens spent nothing that Murmur can tell you about. If you need token accounting or a spend ceiling, use transport: http.


Step 1 — log in to the Claude CLI

The capsule authenticates as you. Install the CLI and log in once:

claude login
claude --version

The version it prints is the version your capsule runs on — the manifest pins neither it nor your login.

The capsule reads that login out of ~/.claude under the HOME it is given, which is why HOME is one of the variables the driver requires. An API key cannot reach the harness through the manifest at all: capabilities.env.allow refuses every credential-shaped name with E-CAP-016, ANTHROPIC_API_KEY among them.

A run whose harness session reports an API key anyway prints warning[W-SEC-031] and keeps going, because that spend is billed to a key Murmur neither counts nor limits. On a subscription login it does not appear.

Step 2 — create murmur.yaml

Create a murmur.yaml file. inference.driver.artifact is required under this transport, and every variable the driver's describe() requires must appear in capabilities.env.allow:

name: my-capsule
version: "0.1.0"

artifacts:
  - name: murmur-driver-claude-code
    version: "1.0.0"
    runtime: driver
  - name: murmur-tool-editor
    version: "1.0.0"
    runtime: tool

capabilities:
  env:
    allow:
      - HOME
      - PATH

inference:
  transport: process
  max_turns: 100
  system_prompt_file: ./instructions.md
  driver:
    artifact: murmur-driver-claude-code

lifecycle:
  conversation: threaded

Declare no endpoint, no api_key and no capabilities.network: the harness reaches its provider itself. Leave inference.model out to run on whatever model your subscription defaults to.

Create an instructions.md file next to it with the agent's instructions. That file is the whole of what the agent is told about its job.

Step 3 — install the artifacts

mur install
??? info "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`:

    ```yaml
    registry:
      default: official
      sources:
        - name: official
          type: github
          repo: <owner>/<repo>
          token: "${GITHUB_TOKEN}"
    ```

    Then install by artifact name and version:

    ```bash
    mur install <artifact-name@version>
    ```

    **Option B — pass a full GitHub reference** and skip configuration entirely:

    ```bash
    mur install github:<username>/<repo>@<tag>
    ```

    See [Installing artifacts](../reference/installing-artifacts.md) to learn more.

The driver is resolved like any other artifact. mur run then checks it three times before the harness starts, and refuses the launch on the first failure:

Check Refused with
The artifact exports the process driver interface E-RUN-029
It loads, and its describe() returns usable variable names E-RUN-032
Every variable describe() requires is declared in capabilities.env.allow E-CAP-019

Step 4 — run a task

Create a task.md file with the work you want done, then run the capsule:

mur run --task task.md
mur run --task task.md
murmur: url localhost:52222
session: ses_019ed2af53da75c2aefee84ee10c34af
status:  ok

The harness writes its answer to out/result.txt in the session workdir, exactly as transport: http does.

Step 5 — give the agent tools

The harness's own built-in tools are stripped. Murmur stands up a loopback tool server for the run, hands the driver its address and the capsule's tool names, and the driver points the harness at it — so the model is offered the capsule's tools and nothing else, and Murmur executes every call it makes.

Two kinds of entry reach the model this way:

Declared as Reaches the model as
A runtime: tool artifact, such as murmur-tool-editor One tool per artifact, under its own name
A binary in capabilities.shell.allow One tool per binary, running in the capsule workdir

runtime: driver and runtime: hook artifacts are not offered to the model, on this transport as on the other.

Watch what the harness actually called:

mur trace show
??? info "Different ways to identify a session"
    `mur trace show` with no argument reads the most recent session:

    ```bash
    mur trace show
    ```

    To name another one, pass an ordinal counting back from the newest (`@2`), the last 4 or more
    characters of its ID (`3e4b`), the full ID, or a path to its `trace.jsonl`:

    ```bash
    mur trace show @2
    mur trace show 3e4b
    mur trace show ses_6801f81dd28b4a9daf434e8324c4793e
    mur trace show path/to/trace.jsonl
    ```

    Use `--workdir <path>` if your session directories are not under `./workdir`. Every command
    that names a session takes the same addresses — see
    [Session addresses](../reference/cli.md#session-addresses).
??? info "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.

    **`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, or with no arguments the two most recent. 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 session's harness_start record names the driver, the harness, the absolute path of the binary spawned, the version it reported, and the capsule tool names the bridge offered. It records no argument values: a driver is free to put the tool server's bearer token in one.

Step 6 — continue a conversation

lifecycle.conversation: threaded maps each A2A context to one harness session. The first task in a context starts a session; every later task in that context resumes it, and the harness — not Murmur — carries the history. Murmur writes no conversation.jsonl here.

The mapping lives in a harness-session.json file under ~/.murmur/conversations/. mur run --resume continues from it. If the harness has lost that conversation, the next task fails with E-RUN-036 and the file is left exactly as it was, rather than answering from nothing.

Because the harness holds the history, --resume-mode compact has nothing to compact and refuses with E-RUN-037. context.max_tokens and inference.compaction parse but do nothing: the harness manages its own context.

Step 7 — know the two fixed limits

Two timeouts bound a run, and neither is a manifest setting.

Limit Value What it bounds
Inactivity 600 seconds How long a run may go with neither a line of harness output nor a tool call before the harness is killed with E-RUN-035. Any output and any tool call start the window again, so a harness that is working is never interrupted for taking a long time.
Interrupt grace 10 seconds How long a harness that was asked to stop has to end on its own before it is killed.

A full manifest

A coding capsule with tool artifacts, a hook and a shell allowlist on this transport:

name: my-coding-capsule
version: "1.0.0"

artifacts:
  - name: murmur-driver-claude-code
    runtime: driver
    version: "1.0.0"
  - name: murmur-tool-editor
    runtime: tool
    version: "1.0.0"
  - name: murmur-tool-code-graph
    runtime: tool
    version: "1.0.0"
  - name: murmur-hook-diff-summary
    runtime: hook
    version: "1.0.0"
    capabilities:
      filesystem:
        scope: "."
  - name: murmur-tool-corpus
    runtime: tool
    version: "1.0.0"
    capabilities:
      state: {}
    config:
      config_version: 1
      read_recent: { default: 10, max: 50 }
      search: { default_k: 5, max_k: 25 }
      prefix_map: { session-note: snt }
      types:
        note:
          schema_version: 1
          schema:
            type: object
            required: [text]
            properties:
              text: { type: string }
              tags: { type: array, items: { type: string } }
            additionalProperties: false

capabilities:
  env:
    allow:
      - HOME
      - PATH
  shell:
    allow:
      - bash
      - git
      - cat
      - ls
      - head
      - tail
      - wc
      - grep
      - find
      - sed
      - diff
      - cp
      - mv
      - rm
      - mkdir
      - python3
    interpreter_runtime:
      - binary: python3
        dirs:
          - path: /usr/lib/python3.12
            list_dir: true
          - path: /usr/lib/python3.12/lib-dynload
            list_dir: false

inference:
  transport: process
  max_turns: 100
  system_prompt_file: ./instructions.md
  driver:
    artifact: murmur-driver-claude-code

lifecycle:
  task_acceptance: queue
  queue_depth: 8
  after_task: sleep
  shell_grace_secs: 600
  conversation: threaded

It declares no compaction hook and no context.max_tokens: both are inert under this transport, and a manifest that named them would promise a mechanism that never runs.


Summary

Manifest setting Effect
inference.transport: process Drives a harness CLI as a subprocess instead of calling a provider API
inference.driver.artifact Required — names the process driver for that harness
inference.command Overrides the executable the driver's describe() names
capabilities.env.allow The whole environment the harness sees; every variable the driver requires must appear, or the launch is refused with E-CAP-019
capabilities.shell.allow Each binary becomes one tool the model may call through Murmur
lifecycle.conversation: threaded Each A2A context resumes one harness session; the harness holds the history
inference.max_session_tokens A manifest error — Murmur sees no spend on this transport
context.max_tokens, inference.compaction Parse but do nothing; the harness manages its own context
Inactivity limit, 600 seconds Fixed; a silent harness is killed with E-RUN-035
Interrupt grace, 10 seconds Fixed; a harness asked to stop is killed after it
Token counts in the trace Always zero; the subprocess protocol does not carry them