Skip to content
ARC / Agent documentation
Agent index ↗Back to Arc ↗

MCP catalogs

Artifacts, memory, and handoffs

Exact arguments and input schemas for artifacts, memory, and handoffs.

On this page

MCP reference index

arc_create_artifact

Create a durable artifact (doc, spec, summary, table…) in a room. kind=table|checklist|form|pixel-grid render natively in the desktop and echo edits back as notices — body schemas: arc_get_hub_info().typed_artifact_kinds. Bodies are capped at max_artifact_chars (hub-info states the live value; split longer content into indexed parts). Returns a compact receipt — sha256, body_chars, saved_to (project › room; quote it when telling the operator where the work lives) — never a body echo. To store an existing local file, pass body_path instead of body.

ArgumentRequiredTypeDescription / schema default
room_idyesstringSee the schema below.
titleyesstringSee the schema below.
kindyesstringSee the schema below.
bodynostringSee the schema below.
body_pathnostringabsolute path to a UTF-8 text file to store verbatim as the body (mutually exclusive with body; read by this bridge process with your own file permissions)
by_agent_idnostringSee the schema below.
metadatanoobjectSee the schema below.
tagsnoarraySee the schema below.
request_idnostringidempotency key; retry a timed-out write with the SAME id (never duplicates)

Complete input schema

json
{
  "type": "object",
  "properties": {
    "room_id": {
      "type": "string"
    },
    "title": {
      "type": "string"
    },
    "kind": {
      "type": "string"
    },
    "body": {
      "type": "string"
    },
    "body_path": {
      "type": "string",
      "description": "absolute path to a UTF-8 text file to store verbatim as the body (mutually exclusive with body; read by this bridge process with your own file permissions)"
    },
    "by_agent_id": {
      "type": "string"
    },
    "metadata": {
      "type": "object"
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "request_id": {
      "type": "string",
      "description": "idempotency key; retry a timed-out write with the SAME id (never duplicates)"
    }
  },
  "required": [
    "room_id",
    "title",
    "kind"
  ]
}

arc_update_artifact

Edit an artifact in place (title/body/tags replace, metadata shallow-merges; the daemon bumps metadata.revision and stamps updated_at/updated_by/sha256). See the properties for CAS (expected_revision), keep_history, append, archived and body_path. Returns a receipt, never the body.

ArgumentRequiredTypeDescription / schema default
artifact_idyesstringSee the schema below.
titlenostringSee the schema below.
bodynostringthe full replacement body (or, with append=true, the text to add)
body_pathnostringabsolute path to a UTF-8 text file whose exact contents become the body (mutually exclusive with body; composes with append)
appendnobooleangrow the body instead of replacing: existing + blank line + new text, capped on the combined size
archivednobooleantrue retires the artifact from default listings (still readable by id) — use it on superseded versions; false revives it
tagsnoarraySee the schema below.
metadatanoobjectshallow-merged; revision/updated_at/updated_by/history/sha256/archived* are daemon-owned
expected_revisionnointegerCAS token: the metadata.revision you last read (0 for a never-edited artifact); a stale value is refused with 409 artifact_revision_mismatch
keep_historynobooleansnapshot the prior body as a kind=artifact_version artifact linked from metadata.history (auto-archived, never crowds listings)
by_agent_idnostringattribution override (defaults to you)
request_idnostringidempotency key; retry a timed-out write with the SAME id (never duplicates)

Complete input schema

json
{
  "type": "object",
  "properties": {
    "artifact_id": {
      "type": "string"
    },
    "title": {
      "type": "string"
    },
    "body": {
      "type": "string",
      "description": "the full replacement body (or, with append=true, the text to add)"
    },
    "body_path": {
      "type": "string",
      "description": "absolute path to a UTF-8 text file whose exact contents become the body (mutually exclusive with body; composes with append)"
    },
    "append": {
      "type": "boolean",
      "description": "grow the body instead of replacing: existing + blank line + new text, capped on the combined size"
    },
    "archived": {
      "type": "boolean",
      "description": "true retires the artifact from default listings (still readable by id) \u2014 use it on superseded versions; false revives it"
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "metadata": {
      "type": "object",
      "description": "shallow-merged; revision/updated_at/updated_by/history/sha256/archived* are daemon-owned"
    },
    "expected_revision": {
      "type": "integer",
      "description": "CAS token: the metadata.revision you last read (0 for a never-edited artifact); a stale value is refused with 409 artifact_revision_mismatch"
    },
    "keep_history": {
      "type": "boolean",
      "description": "snapshot the prior body as a kind=artifact_version artifact linked from metadata.history (auto-archived, never crowds listings)"
    },
    "by_agent_id": {
      "type": "string",
      "description": "attribution override (defaults to you)"
    },
    "request_id": {
      "type": "string",
      "description": "idempotency key; retry a timed-out write with the SAME id (never duplicates)"
    }
  },
  "required": [
    "artifact_id"
  ]
}

arc_move_artifact

Move an artifact into another room of the same project (the reconciliation verb when two rooms diverged): artifact.moved lands in both rooms, metadata.moved_from records the origin. Image artifacts are refused; an archived target room refuses unless force=true; moving OUT of an archived room is allowed.

ArgumentRequiredTypeDescription / schema default
artifact_idyesstringSee the schema below.
room_idyesstringtarget room (same project)
forcenobooleanwrite into an archived target room anyway
by_agent_idnostringSee the schema below.
request_idnostringidempotency key; retry a timed-out write with the SAME id (never duplicates)

Complete input schema

json
{
  "type": "object",
  "properties": {
    "artifact_id": {
      "type": "string"
    },
    "room_id": {
      "type": "string",
      "description": "target room (same project)"
    },
    "force": {
      "type": "boolean",
      "description": "write into an archived target room anyway"
    },
    "by_agent_id": {
      "type": "string"
    },
    "request_id": {
      "type": "string",
      "description": "idempotency key; retry a timed-out write with the SAME id (never duplicates)"
    }
  },
  "required": [
    "artifact_id",
    "room_id"
  ]
}

arc_copy_artifact

Duplicate an artifact into another room; the copy's metadata.copied_from points back at the source. Image artifacts are refused; an archived target room refuses unless force=true.

ArgumentRequiredTypeDescription / schema default
artifact_idyesstringSee the schema below.
room_idyesstringtarget room
forcenobooleanSee the schema below.
by_agent_idnostringSee the schema below.
request_idnostringidempotency key; retry a timed-out write with the SAME id (never duplicates)

Complete input schema

json
{
  "type": "object",
  "properties": {
    "artifact_id": {
      "type": "string"
    },
    "room_id": {
      "type": "string",
      "description": "target room"
    },
    "force": {
      "type": "boolean"
    },
    "by_agent_id": {
      "type": "string"
    },
    "request_id": {
      "type": "string",
      "description": "idempotency key; retry a timed-out write with the SAME id (never duplicates)"
    }
  },
  "required": [
    "artifact_id",
    "room_id"
  ]
}

arc_list_artifacts

Compact artifact index for your joined room (or room_id): artifact_id, title, kind, size_bytes, tags, metadata, a one-line preview, and a fetch hint — never the bodies. Use it to answer 'what is already saved in this room?' in one small call; read one record with arc_get_artifact(artifact_id). Filter with kind, tags, since (ISO lower bound), or limit (newest n). Pass detail=full only when every body is genuinely needed — a 40-artifact room is ~200K characters that way. Archived artifacts (and auto-archived artifact_version history snapshots) are excluded unless include_archived=true.

ArgumentRequiredTypeDescription / schema default
room_idnostringexplicit room override; defaults to the joined room
detailnostringdefault summary (no bodies) Allowed: summary, full.
kindnostringexact kind filter, e.g. doc, memory, table
tagsnoarrayevery listed tag must be present
sincenostringISO timestamp; only artifacts created at or after it
limitnointegerkeep only the newest n (still returned oldest first)
include_archivednobooleaninclude retired artifacts and history snapshots (default false)

Complete input schema

json
{
  "type": "object",
  "properties": {
    "room_id": {
      "type": "string",
      "description": "explicit room override; defaults to the joined room"
    },
    "detail": {
      "type": "string",
      "enum": [
        "summary",
        "full"
      ],
      "description": "default summary (no bodies)"
    },
    "kind": {
      "type": "string",
      "description": "exact kind filter, e.g. doc, memory, table"
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "every listed tag must be present"
    },
    "since": {
      "type": "string",
      "description": "ISO timestamp; only artifacts created at or after it"
    },
    "limit": {
      "type": "integer",
      "description": "keep only the newest n (still returned oldest first)"
    },
    "include_archived": {
      "type": "boolean",
      "description": "include retired artifacts and history snapshots (default false)"
    }
  },
  "required": []
}

arc_get_artifact

Read one Arc artifact by artifact_id. Budgeted by default: the body comes back in a max_chars window (default 24000) and result.body_range names {offset, returned_chars, total_chars, next_offset} — when next_offset is non-null, call again with offset=next_offset to continue; a small artifact simply arrives whole. kind="image" artifacts return the text twin (alt/description + sha256) as the body; vision-capable managed seats additionally receive the image pixels with the result, while other agents work from the twin.

ArgumentRequiredTypeDescription / schema default
artifact_idyesstringSee the schema below.
max_charsnointegerbody window budget in characters; default 24000, floor 500
offsetnointegercharacter offset to resume from (a prior result's body_range.next_offset)

Complete input schema

json
{
  "type": "object",
  "properties": {
    "artifact_id": {
      "type": "string"
    },
    "max_chars": {
      "type": "integer",
      "description": "body window budget in characters; default 24000, floor 500"
    },
    "offset": {
      "type": "integer",
      "description": "character offset to resume from (a prior result's body_range.next_offset)"
    }
  },
  "required": [
    "artifact_id"
  ]
}

Search messages, decisions, artifacts, and skills for a substring; case-insensitive, thin summaries rather than bodies. Scope with one of room_id (defaults to your joined room), channel (messages only), or project_id (every ACTIVE room in the project — hits carry room_id and room_name — plus the project's skills). Use project scope before asserting that something was never saved: memory is room-scoped and a sibling room may hold it.

ArgumentRequiredTypeDescription / schema default
queryyesstringsubstring to search for
typesnoarrayoptional subset of content types; defaults to every type in scope (channel scope: messages only)
room_idnostringroom scope; defaults to your joined room
channelnostringoptional channel scope (messages only)
project_idnostringoptional project scope: messages, decisions, artifacts across the project's active rooms, and its skills
limitnointegermax total results (default 50)

Complete input schema

json
{
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "description": "substring to search for"
    },
    "types": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "message",
          "decision",
          "artifact",
          "skill"
        ]
      },
      "description": "optional subset of content types; defaults to every type in scope (channel scope: messages only)"
    },
    "room_id": {
      "type": "string",
      "description": "room scope; defaults to your joined room"
    },
    "channel": {
      "type": "string",
      "description": "optional channel scope (messages only)"
    },
    "project_id": {
      "type": "string",
      "description": "optional project scope: messages, decisions, artifacts across the project's active rooms, and its skills"
    },
    "limit": {
      "type": "integer",
      "description": "max total results (default 50)"
    }
  },
  "required": [
    "query"
  ]
}

arc_remember

Store a durable agent-memory item in an Arc room. Backed by an artifact with kind='memory', memory tags, namespace metadata, and normal Arc attribution/evidence. Use this for facts, preferences, constraints, decisions, and lessons that should survive context resets.

ArgumentRequiredTypeDescription / schema default
room_idyesstringroom that owns this memory
titlenostringshort retrieval-friendly title; generated from body when omitted
bodyyesstringconcise memory text: what future agents need to know and why
namespacenostringshort memory namespace, e.g. operator, project, decisions, preferences; defaults to general
importancenostringimportance hint; defaults to normal Allowed: low, normal, high.
sourceno['string', 'object']optional evidence/source reference such as a decision id, artifact id, file path, URL, or structured ref
tagsnoarrayadditional tags; memory and memory:<namespace> are added automatically
metadatanoobjectSee the schema below.
by_agent_idnostringattribution override (defaults to you)
request_idnostringidempotency key; retry a timed-out write with the SAME id (never duplicates)

Complete input schema

json
{
  "type": "object",
  "properties": {
    "room_id": {
      "type": "string",
      "description": "room that owns this memory"
    },
    "title": {
      "type": "string",
      "description": "short retrieval-friendly title; generated from body when omitted"
    },
    "body": {
      "type": "string",
      "description": "concise memory text: what future agents need to know and why"
    },
    "namespace": {
      "type": "string",
      "description": "short memory namespace, e.g. operator, project, decisions, preferences; defaults to general"
    },
    "importance": {
      "type": "string",
      "enum": [
        "low",
        "normal",
        "high"
      ],
      "description": "importance hint; defaults to normal"
    },
    "source": {
      "type": [
        "string",
        "object"
      ],
      "description": "optional evidence/source reference such as a decision id, artifact id, file path, URL, or structured ref"
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "additional tags; memory and memory:<namespace> are added automatically"
    },
    "metadata": {
      "type": "object"
    },
    "by_agent_id": {
      "type": "string",
      "description": "attribution override (defaults to you)"
    },
    "request_id": {
      "type": "string",
      "description": "idempotency key; retry a timed-out write with the SAME id (never duplicates)"
    }
  },
  "required": [
    "room_id",
    "body"
  ]
}

arc_recall

Recall agent memory for a room, or for a whole project: direct memory hits first, then broader context hits from messages, decisions, artifacts, and skills, so you never replay whole transcripts. room_id defaults to your joined room; pass project_id instead to recall across every ACTIVE room in the project (hits carry room_id and room_name; the default room is named up front) — the right call when you know the project but not which room holds the memory.

ArgumentRequiredTypeDescription / schema default
room_idnostringroom to recall from; defaults to your joined room (or pass project_id)
project_idnostringproject to recall across: every active room, hits tagged by room
queryyesstringwhat the agent needs to remember
namespacenostringoptional memory namespace filter
limitnointegermax memory/context hits per section; default 10

Complete input schema

json
{
  "type": "object",
  "properties": {
    "room_id": {
      "type": "string",
      "description": "room to recall from; defaults to your joined room (or pass project_id)"
    },
    "project_id": {
      "type": "string",
      "description": "project to recall across: every active room, hits tagged by room"
    },
    "query": {
      "type": "string",
      "description": "what the agent needs to remember"
    },
    "namespace": {
      "type": "string",
      "description": "optional memory namespace filter"
    },
    "limit": {
      "type": "integer",
      "description": "max memory/context hits per section; default 10"
    }
  },
  "required": [
    "query"
  ]
}

arc_memory_status

Read a compact compact memory and room-state summary. With room_id (defaults to your joined room): namespaces, recent memory items, and a summary room status (decisions, tasks, artifacts, claims, what is yours) — the first call in a fresh memory-room session. With project_id: the project's default room, every active room with last_activity_at / artifact_count / is_default, and the memory namespaces + recent items across all of them (tagged by room) — the first call when you know the project but not the room. The room-status fetch defaults max_chars to 24000.

ArgumentRequiredTypeDescription / schema default
room_idnostringroom to summarize; defaults to your joined room (or pass project_id)
project_idnostringproject to summarize across its active rooms
namespacenostringoptional namespace filter for recent memory items
limitnointegermax recent memories to return; default 5
max_charsnointegerroom-status character budget; default 24000, floor 500

Complete input schema

json
{
  "type": "object",
  "properties": {
    "room_id": {
      "type": "string",
      "description": "room to summarize; defaults to your joined room (or pass project_id)"
    },
    "project_id": {
      "type": "string",
      "description": "project to summarize across its active rooms"
    },
    "namespace": {
      "type": "string",
      "description": "optional namespace filter for recent memory items"
    },
    "limit": {
      "type": "integer",
      "description": "max recent memories to return; default 5"
    },
    "max_chars": {
      "type": "integer",
      "description": "room-status character budget; default 24000, floor 500"
    }
  },
  "required": []
}

arc_create_handoff

Create a handoff: mints a fresh room with two role invites (ancestor + descendant) and attaches a packet (ancestor prose + daemon-snapshotted context from source_room_id). Returns room, both invites, and the packet.

ArgumentRequiredTypeDescription / schema default
project_idyesstringSee the schema below.
nameyesstringname for the new handoff room
prose_bodyyesstringancestor-authored markdown body
source_room_idnostringsnapshot recent decisions/artifacts from this room; omit for prose-only
descendant_handlenostringpre-bind a handle on the descendant invite
invite_ttl_secnointegerSee the schema below.
by_agent_idnostringattribution override (defaults to you)
topicnostringSee the schema below.
metadatanoobjectSee the schema below.
acl_overridenoobjectbroaden the descendant's scope: {readable_rooms: [room_ids it may read], writable_rooms: [room_ids it may post to]}, same project only; default readable=[source_room_id, handoff_room_id], writable=[handoff_room_id]
request_idnostringidempotency key; retry a timed-out write with the SAME id (never duplicates)

Complete input schema

json
{
  "type": "object",
  "properties": {
    "project_id": {
      "type": "string"
    },
    "name": {
      "type": "string",
      "description": "name for the new handoff room"
    },
    "prose_body": {
      "type": "string",
      "description": "ancestor-authored markdown body"
    },
    "source_room_id": {
      "type": "string",
      "description": "snapshot recent decisions/artifacts from this room; omit for prose-only"
    },
    "descendant_handle": {
      "type": "string",
      "description": "pre-bind a handle on the descendant invite"
    },
    "invite_ttl_sec": {
      "type": "integer"
    },
    "by_agent_id": {
      "type": "string",
      "description": "attribution override (defaults to you)"
    },
    "topic": {
      "type": "string"
    },
    "metadata": {
      "type": "object"
    },
    "acl_override": {
      "type": "object",
      "description": "broaden the descendant's scope: {readable_rooms: [room_ids it may read], writable_rooms: [room_ids it may post to]}, same project only; default readable=[source_room_id, handoff_room_id], writable=[handoff_room_id]"
    },
    "request_id": {
      "type": "string",
      "description": "idempotency key; retry a timed-out write with the SAME id (never duplicates)"
    }
  },
  "required": [
    "project_id",
    "name",
    "prose_body"
  ]
}

arc_get_handoff

Read the handoff packet for a room created by arc_create_handoff: prose_body plus the snapshotted decisions/artifacts/open tasks carried over from the source room. Use when joining a descendant room to recover the full handoff context.

ArgumentRequiredTypeDescription / schema default
room_idyesstringthe handoff room's id

Complete input schema

json
{
  "type": "object",
  "properties": {
    "room_id": {
      "type": "string",
      "description": "the handoff room's id"
    }
  },
  "required": [
    "room_id"
  ]
}