Skip to main content

MCP tools

arcave mcp exposes ten tools: four for savepoints and six for sessions. Each savepoint tool takes the compose project it acts on as an argument, so one server addresses every project on the machine.

Every tool runs the workflow the CLI runs, under the same rules: the project is stopped and started again, the project lock is claimed, and a rollback of a running project that fails replays its safety snapshot. What an agent takes, you list; what you take, an agent rolls back to.

Which session a call works in​

Each savepoint tool takes an optional session, by name or id, for that call only. Without it, the call works in the session the server was pinned to with --session or ARCAVE_SESSION, else in the current session (.arcave/current_session, shared with your own shell), else in baseline. See arcave mcp.

savepoint_create​

Captures a savepoint. The services are stopped for the capture and started again afterwards.

ArgumentRequiredDescription
projectyesThe compose project, as docker compose ls names it.
sessionnoThe session to work in for this call only.
namenoA short name to refer to the savepoint by. Ids are assigned by arcave.
descriptionnoWhat this savepoint is being taken before.
wait_timeoutnoHow long to wait for services to become healthy on restart, e.g. 2m or 90s. Omit for the project's own bound.

Returns the savepoint record — the shape Output describes, stats, writable_layers, images, spec and not_covered included.

structured content
{
"id": "019e843e-1650-7000-8000-000000000000",
"name": "before-migration",
"description": "before the v2 schema",
"created_at": "2026-06-01T19:41:12.123456789Z",
"stats": [ … ],
"writable_layers": [ … ],
"images": [ … ],
"spec": { "format": "compose-yaml" },
"not_covered": { "services_without_volumes": ["worker"] }
}

not_covered is what the savepoint does not hold — skipped mounts with a reason code, services without a captured volume, containers killed at the stop deadline, replica gaps, unresolvable images, and layers or images a capture label left out. The tool's description tells an agent to report it before relying on the savepoint.

A failure of the form savepoint 019e843e-1650-7000-8000-000000000000 committed; services failed to start: … means the savepoint exists and is safe to roll back to; only the restart failed. The tool's own description tells an agent this, so it reports the id rather than taking another savepoint.

savepoint_list​

Reads the store. Stops nothing, and takes no lock.

ArgumentRequiredDescription
projectyesThe compose project.
sessionnoThe session to work in for this call only.
include_safety_snapshotsnoAlso list the safety snapshots a rollback commits of the live state before it overwrites it. Hidden by default.
sortnodesc (the default) lists the newest first, asc the oldest. Any other value is refused.

Returns an object, because MCP structured output must be one — the array the CLI prints is the savepoints field:

structured content
{
"savepoints": [
{ "id": "019e843e-1650-7000-8000-000000000000", "name": "before-migration", … }
]
}

An empty store answers {"savepoints": []}, never null.

savepoint_remove​

Deletes savepoints and the data they hold. Permanent.

ArgumentRequiredDescription
projectyesThe compose project.
sessionnoThe session to work in for this call only.
idsnoSavepoint ids to delete. Cannot be combined with the retention fields.
retain_recentnoKeep this many newest savepoints and delete the rest.
retain_fornoKeep savepoints younger than this duration, e.g. 24h or 7d.
before_datenoDelete savepoints created before this RFC 3339 timestamp, e.g. 2026-06-01T00:00:00Z.
dry_runnoReport what would be deleted, and delete nothing.

Either ids or the retention fields — not both, and not neither. The refusals carry the same wording the CLI uses: cannot combine savepoint ids with retain-recent/retain-for/before-date, and specify savepoint ids, or at least one of retain-recent, retain-for or before-date.

structured content
{
"dry_run": true,
"removed": [
{ "id": "019e843e-1650-7000-8000-000000000000", "name": "before-migration", … }
]
}

rollback​

Returns the environment to a savepoint. Destructive: every volume it covers is overwritten with the savepoint's data, bind mounts included, and a volume a service reaches through subpath: goes back whole. When the project is running, arcave takes a safety snapshot of the live state first and replays it by itself if the rollback fails. A project with no containers is built from the savepoint's spec instead, with no safety snapshot, and rollback.leftover_volumes from the config decides about the named volumes it still owns — see Rolling back a project that is not running.

ArgumentRequiredDescription
projectyesThe compose project.
sessionnoThe session to work in for this call only.
refyesThe savepoint to return to: its id, its name, or the literal latest.
wait_timeoutnoHow long to wait for services to become healthy on restart. Omit for the project's own bound.

Returns what the CLI prints — see Output:

structured content
{
"rolled_back_to": { "id": "019e843e-1650-7000-8000-000000000000", … },
"restored": [
{ "object_id": "volume-named-myapp_pgdata", "type": "named", … }
],
"writable_layers": [
{ "service": "app", "replica": 1, "container_name": "myapp-app-1", "image_id": "sha256:aaaa…",
"tag": "arcave/myapp-app-1-myapp-latest:sp-019e843e-1650-7000-8000-000000000000" }
]
}

writable_layers is omitted when the savepoint held no layer.

session_list​

Lists the arcave project's sessions. Read-only, and takes no lock.

ArgumentRequiredDescription
allnoAlso list the session directories without a record: forks still cloning, failed, or left incomplete.
sortnodesc (the default) lists the newest first, asc the oldest.
structured content
{
"sessions": [
{ "id": "019a0c2f-4a6d-7e4b-9a2c-1d5e8b7a4c31", "name": "agent-work", "created_at": "2026-10-10T12:00:00Z",
"from": { "session": "00000000-0000-0000-0000-000000000001" },
"status": "ready", "current": true, "savepoint_count": 1, "compose_projects": ["myapp"], "size_bytes": 734003396 },
{ "id": "00000000-0000-0000-0000-000000000001", "name": "baseline",
"status": "ready", "current": false, "savepoint_count": 2, "compose_projects": ["myapp"], "size_bytes": 734003200 }
]
}

current marks the session a call given no session works in — the pinned session on a pinned server. The entries are those of session list.

session_create​

Creates a session: empty, or with from a copy of another session — every compose project and savepoint it holds. A fork touches no container: to run the forked state, call session_set (or pass session) and then rollback to one of its savepoints. It costs the source's size_bytes, and holds the project lock for its whole copy.

ArgumentRequiredDescription
namenoA name for the session, unique within the arcave project.
fromnoThe session to copy, by name or id. Omit for an empty session.

Returns the session record:

structured content
{ "id": "019a0c2f-4a6d-7e4b-9a2c-1d5e8b7a4c31", "name": "agent-work", "created_at": "2026-10-10T12:00:00Z",
"from": { "session": "00000000-0000-0000-0000-000000000001" } }

session_delete​

Deletes a session and every savepoint it holds, permanently. A compose project running from it is left as it is. baseline cannot be deleted.

ArgumentRequiredDescription
sessionyesThe session to delete, by name or id; a directory without a record by id only.
forcenoAlso delete the current session — clearing the pointer, so calls work in baseline — the session the server is pinned to, or a directory whose fork still looks alive.
structured content
{ "session": "019a0c2f-4a6d-7e4b-9a2c-1d5e8b7a4c31", "deleted": true, "freed_bytes": 734003396 }

session_current​

Takes no arguments. Returns the record of the session a call given no session works in: the pinned session, else the current session, else baseline. Read-only. It fails when the current session no longer exists; session_unset or session_set repairs that.

session_set​

Makes a session the current one: every later call given no session works in it — and so do your own arcave commands in the project directory, which share the pointer. Returns the session's record.

ArgumentRequiredDescription
sessionyesThe session to make current, by name or id.

session_unset​

Takes no arguments. Clears the current session, so calls given no session work in baseline again, and returns baseline's record. It is also the way out when the current session no longer exists.

session_set and session_unset are refused on a pinned server:

this server is pinned to session "019a0c2f-4a6d-7e4b-9a2c-1d5e8b7a4c31" by --session or ARCAVE_SESSION, which outranks the current session: pass session on each call, or restart the server without the pin

Where the tools differ from the CLI​

  • Lists come wrapped in an object. savepoint_list answers {"savepoints": […]} and session_list {"sessions": […]}, where the CLI prints the bare array.
  • A lock error says what to wait for. A call refused because another run holds the project lock reads another arcave command is already running in this project: a session fork holds the lock for its whole copy, as does a savepoint or rollback for its run; retry when it finishes.
  • Errors keep the CLI's flag names. An unparseable before_date is reported as invalid --before-date "2026-06-01": …, and retain_for as invalid --retain-for ….

wait_timeout takes a unit-bearing duration in both tools that accept it. A bare number is refused:

wait_timeout "120": want a unit-bearing value like 2m, 90s or 1h30m

Next step​

Requirements — what has to be true of the machine before any of this runs.

Tools and expertise for reproducible, production-like environments.
Copyright © 2026 Greenmask, Inc.