perseus-vault

v2.23.1

Persistent, encrypted, deterministic memory for AI agents. Local-first and MCP-native.

Connect

Add to your MCP client configuration:

{ "mcpServers": { "perseus-vault": { "command": "perseus-vault", "args": [ "serve", "--db", "~/.perseus-vault/data/perseus-vault.db" ] } } }
Protocol MCP 2025-06-18Transport stdioCapabilities tools

Tools

Remember Entity

destructive
TOOLperseus_vault_remember

Store or update an entity by (category, key). Idempotent — call as often as you want, same key returns an update. NEAR-DUPLICATE MERGING (#531): a NEW key whose body is >=70% trigram-similar to an existing entity in the same category+workspace does NOT create a new entity — the write is folded into the existing one (result: action='deduped', deduped=true, merged_into=). Right for conversational memory; wrong for bulk ingest of templated records, which are similar by construction and will silently collapse to a handful of rows. For bulk ingest pass skip_dedup=true (or use perseus_vault_ingest_file), and check the returned action. Prefer recall_when triggers (retrieve when relevant) over always_on=true (inject unconditionally): the recall-first perseus_vault_context hard-caps the always-on set and warns when it overflows, so reserve always_on for genuinely identity-critical facts. Optional certainty (0.0-1.0) is used by perseus_vault_conflicts for typed-entity conflict detection. Pass derived_from (ids or {category,key} pairs of the memories you recalled) to auto-mark those sources useful — cited memories rank higher and decay slower. Use this for saving facts, decisions, architecture notes, and conventions. Optional hints (#919): 1-3 prospective query phrasings that should retrieve this entity (vocabulary-gap recall) — indexed into FTS5 alongside the body, default-off (PERSEUS_VAULT_HINTS_ENABLED=1 to enable), replaced wholesale on update. When encryption is enabled, body_json is encrypted at rest with AES-256-GCM.

Body

application/json
actor_kindstringassistant

Actor basis for the write (for example assistant, user, connector, or system). Missing admission stays reviewable.

admissionobject

Hash-only admission envelope. The server emits one stable outcome_class: save, drop, block, or pending_approval. Authoritative admission requires a validated source_event_id and matching workspace; missing or unverified evidence is retained as proposed/requires_review and is not serveable. DROP/BLOCK decisions return hash-only evidence without persisting the candidate.

Show child attributes
actor_identitystring
actor_kindstring
authorization_scopestring
contradicts_authoritativeboolean
ingestion_channelstring
instruction_bearingboolean
record_digeststring
recorded_at_unix_msinteger
source_event_idstring
source_identitystring
source_truststringuntrustedtrustedauthoritative
task_relevance_bpsinteger
valid_from_unix_msinteger
validatedboolean
workspace_hashstring
agent_idstring

Agent identity (v1.2.0). Tracks which agent wrote this entity. Used for agent attribution and context filtering.

allow_rejectedbooleanfalse

#849: deliberate trusted override of a rejected-value tombstone. Journaled as an audited override; never set automatically.

body_jsonstringrequired

JSON object with the entity body — store content, summary, and any custom fields here

categorystringrequired

Entity category: 'decision', 'architecture', 'convention', 'insight', or custom

derived_fromArray<string | object>

#487: the memories this write was built on (max 64). Each cited source is automatically marked useful — usefulness_count bumped, last_useful/last_accessed refreshed — so memories that actually inform later writes rank higher in recall and decay slower. Cite the entities you recalled before composing this write. Unknown citations are reported in the result, not fatal; self-citations are ignored.

Show child attributes
One of

Entity id of a cited source, e.g. 'mem-a1b2c3d4e5f6' (as returned by recall/remember)

string
categorystringrequired
keystringrequired
evidenceobject

Write-time audit envelope for captures and decisions. capture_mode distinguishes snapshot, hash_only, pointer_only, not_requested, capture_failed, and legacy_unknown; a missing value is never interpreted implicitly.

Show child attributes
capture_modestringsnapshothash_onlypointer_onlynot_requestedcapture_failedlegacy_unknownrequired
captured_at_unix_msintegerrequired
content_sha256string

64-hex SHA-256 of the resolved value or source bytes

replayablebooleanrequired
resolved_valueany

Resolved source value retained at write time when capture_mode=snapshot

source_refstring
source_systemstring
external_refsArray<object>

#728: optional first-class pointers to external systems of record (max 32). Stored inside body_json under the reserved 'external_refs' key; filter recall with ref_type/ref_value.

Show child attributes
ref_typestringrequired
ref_valuestringrequired
relationshipstringaboutderived_frommentionsapplies_tosupersedes
source_systemstring
hintsArray<string>

#919: optional 1-3 prospective query hints — natural-language phrasings that should retrieve this entity, indexed into FTS5 alongside the body (vocabulary-gap recall). Default-off: hints are rejected unless the server runs with PERSEUS_VAULT_HINTS_ENABLED=1. Hints replace any previously stored hints on update (omit to clear).

importancenumber0.5

Initial importance 0.0–1.0 — sets the starting decay score

interference_boundnumber[0, 1]

#874: per-write interference bound override — may only TIGHTEN the configured bound (PERSEUS_VAULT_INTERFERENCE_BOUND); a looser bound is refused fail-closed. Writes whose activation overlap with existing memory exceeds the bound are quarantined (default) or refused.

interference_modestringautorefusequarantineauto

#874: per-write interference-gate mode override. auto (default) uses the operator-configured mode (PERSEUS_VAULT_INTERFERENCE_MODE); refuse/quarantine tighten it per-write. Per-write 'off' is refused fail-closed — only the operator can disable the gate.

keystringrequired

Unique key within the category, e.g. 'use-postgres-16' or 'deployment-strategy'

originobject

#729: optional memory-origin/provenance metadata (spec: docs/specs/memory-provenance-and-external-refs.md). Stored inside body_json under the reserved 'origin' key — surfaced by recall/get_entity via body expansion. All fields optional; unknown values are left absent, never guessed.

Show child attributes
capture_methodstring
memory_kindstringassertedextractedinferredimportedobserved
observed_at_unix_msinteger
source_systemstring
skip_dedupbooleanfalse

Opt out of near-duplicate merging for this write (#531). Set true for bulk/API ingest of templated records so every acknowledged write actually creates its key; leave false for conversational memory.

sparse_updatebooleanfalse

#874: sparse update mode — touches only the activated subset of state (body slot, activated links), never disturbs neighbors: no salience inflation on re-assert, caller links admitted only when their target is activated by the new body, no near-duplicate absorption on insert.

statusstringactivedraftdeprecatedexpiredproposedquarantinedredactedactive

Closed lifecycle status vocabulary; proposed/quarantined are never publicly serveable

tagsArray<string>

Tags for categorization and cross-referencing

topic_pathstring

Hierarchical topic path, e.g. 'architecture/database/postgres'

typestringinsight

Entity type: 'insight', 'architecture', 'decision', 'reference', 'convention'

valid_from_unix_msinteger

Application-time period start (#363): when the fact became TRUE IN THE WORLD, independent of when it was recorded. Set in the past for retroactive facts ('this was true last week, we just learned it') without rewriting transaction history. Default: transaction time (now). Query with perseus_vault_valid_at / perseus_vault_bitemporal / recall's valid_at filter.

valid_to_unix_msinteger

Application-time period end (#363, exclusive): when the fact STOPPED being true in the world. Omit for 'still true' (unbounded). Must be greater than valid_from_unix_ms.

workspace_hashstring

Workspace scope identifier (v1.2.0). Empty = global. Entities with a workspace_hash are invisible to recall queries scoped to a different workspace.

Returns

actionstring

'created' for new entities, 'updated' for existing ones

admissionobject

Hash-covered, content-minimized admission evidence.

categorystring

Entity category

derived_fromobject

Present when derived_from citations were passed: {reinforced: n, not_found: [labels]}

dispositionstring

Existing detailed disposition, such as quarantined; use outcome_class for stable aggregation.

idstring

Entity ID, e.g. 'mem-a1b2c3d4e5f6'

keystring

Entity key

outcome_classstringsavedropblockpending_approval

Stable four-way admission result. SAVE is durably active; DROP and BLOCK are non-persisting terminal decisions; PENDING_APPROVAL is retained but non-serveable until review.

proposedboolean

True when the write lacks authoritative admission and must remain reviewable.

provenanceobject

Hash-only admission/provenance state; raw prompts, bodies, credentials, and tool arguments are excluded.

requires_reviewboolean

Whether the stored write must be reviewed before promotion or authoritative use.

Remember Entity
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_remember",
    "arguments": {
        "actor_kind": "assistant",
        "admission": {
          "actor_identity": "string",
          "actor_kind": "string",
          "authorization_scope": "string",
          "contradicts_authoritative": true,
          "ingestion_channel": "string",
          "instruction_bearing": true,
          "record_digest": "string",
          "recorded_at_unix_ms": 0,
          "source_event_id": "string",
          "source_identity": "string",
          "source_trust": "untrusted",
          "task_relevance_bps": 0,
          "valid_from_unix_ms": 0,
          "validated": true,
          "workspace_hash": "string"
        },
        "agent_id": "",
        "allow_rejected": false,
        "body_json": "string",
        "category": "string",
        "derived_from": [
          "string"
        ],
        "evidence": {
          "capture_mode": "snapshot",
          "captured_at_unix_ms": 0,
          "content_sha256": "string",
          "replayable": true,
          "source_ref": "string",
          "source_system": "string"
        },
        "external_refs": [
          {
            "ref_type": "string",
            "ref_value": "string",
            "relationship": "about",
            "source_system": "string"
          }
        ],
        "hints": [
          "string"
        ],
        "importance": 0.5,
        "interference_bound": 0,
        "interference_mode": "auto",
        "key": "string",
        "origin": {
          "capture_method": "string",
          "memory_kind": "asserted",
          "observed_at_unix_ms": 0,
          "source_system": "string"
        },
        "skip_dedup": false,
        "sparse_update": false,
        "status": "active",
        "tags": [
          "string"
        ],
        "topic_path": "",
        "type": "insight",
        "valid_from_unix_ms": 0,
        "valid_to_unix_ms": 0,
        "workspace_hash": ""
      }
  }
}
const result = await client.callTool("perseus_vault_remember", {
  "actor_kind": "assistant",
  "admission": {
    "actor_identity": "string",
    "actor_kind": "string",
    "authorization_scope": "string",
    "contradicts_authoritative": true,
    "ingestion_channel": "string",
    "instruction_bearing": true,
    "record_digest": "string",
    "recorded_at_unix_ms": 0,
    "source_event_id": "string",
    "source_identity": "string",
    "source_trust": "untrusted",
    "task_relevance_bps": 0,
    "valid_from_unix_ms": 0,
    "validated": true,
    "workspace_hash": "string"
  },
  "agent_id": "",
  "allow_rejected": false,
  "body_json": "string",
  "category": "string",
  "derived_from": [
    "string"
  ],
  "evidence": {
    "capture_mode": "snapshot",
    "captured_at_unix_ms": 0,
    "content_sha256": "string",
    "replayable": true,
    "source_ref": "string",
    "source_system": "string"
  },
  "external_refs": [
    {
      "ref_type": "string",
      "ref_value": "string",
      "relationship": "about",
      "source_system": "string"
    }
  ],
  "hints": [
    "string"
  ],
  "importance": 0.5,
  "interference_bound": 0,
  "interference_mode": "auto",
  "key": "string",
  "origin": {
    "capture_method": "string",
    "memory_kind": "asserted",
    "observed_at_unix_ms": 0,
    "source_system": "string"
  },
  "skip_dedup": false,
  "sparse_update": false,
  "status": "active",
  "tags": [
    "string"
  ],
  "topic_path": "",
  "type": "insight",
  "valid_from_unix_ms": 0,
  "valid_to_unix_ms": 0,
  "workspace_hash": ""
});
result = await session.call_tool("perseus_vault_remember", arguments={
  "actor_kind": "assistant",
  "admission": {
    "actor_identity": "string",
    "actor_kind": "string",
    "authorization_scope": "string",
    "contradicts_authoritative": true,
    "ingestion_channel": "string",
    "instruction_bearing": true,
    "record_digest": "string",
    "recorded_at_unix_ms": 0,
    "source_event_id": "string",
    "source_identity": "string",
    "source_trust": "untrusted",
    "task_relevance_bps": 0,
    "valid_from_unix_ms": 0,
    "validated": true,
    "workspace_hash": "string"
  },
  "agent_id": "",
  "allow_rejected": false,
  "body_json": "string",
  "category": "string",
  "derived_from": [
    "string"
  ],
  "evidence": {
    "capture_mode": "snapshot",
    "captured_at_unix_ms": 0,
    "content_sha256": "string",
    "replayable": true,
    "source_ref": "string",
    "source_system": "string"
  },
  "external_refs": [
    {
      "ref_type": "string",
      "ref_value": "string",
      "relationship": "about",
      "source_system": "string"
    }
  ],
  "hints": [
    "string"
  ],
  "importance": 0.5,
  "interference_bound": 0,
  "interference_mode": "auto",
  "key": "string",
  "origin": {
    "capture_method": "string",
    "memory_kind": "asserted",
    "observed_at_unix_ms": 0,
    "source_system": "string"
  },
  "skip_dedup": false,
  "sparse_update": false,
  "status": "active",
  "tags": [
    "string"
  ],
  "topic_path": "",
  "type": "insight",
  "valid_from_unix_ms": 0,
  "valid_to_unix_ms": 0,
  "workspace_hash": ""
})
Request Body
{
  "actor_kind": "assistant",
  "admission": {
    "actor_identity": "string",
    "actor_kind": "string",
    "authorization_scope": "string",
    "contradicts_authoritative": true,
    "ingestion_channel": "string",
    "instruction_bearing": true,
    "record_digest": "string",
    "recorded_at_unix_ms": 0,
    "source_event_id": "string",
    "source_identity": "string",
    "source_trust": "untrusted",
    "task_relevance_bps": 0,
    "valid_from_unix_ms": 0,
    "validated": true,
    "workspace_hash": "string"
  },
  "agent_id": "",
  "allow_rejected": false,
  "body_json": "string",
  "category": "string",
  "derived_from": [
    "string"
  ],
  "evidence": {
    "capture_mode": "snapshot",
    "captured_at_unix_ms": 0,
    "content_sha256": "string",
    "replayable": true,
    "source_ref": "string",
    "source_system": "string"
  },
  "external_refs": [
    {
      "ref_type": "string",
      "ref_value": "string",
      "relationship": "about",
      "source_system": "string"
    }
  ],
  "hints": [
    "string"
  ],
  "importance": 0.5,
  "interference_bound": 0,
  "interference_mode": "auto",
  "key": "string",
  "origin": {
    "capture_method": "string",
    "memory_kind": "asserted",
    "observed_at_unix_ms": 0,
    "source_system": "string"
  },
  "skip_dedup": false,
  "sparse_update": false,
  "status": "active",
  "tags": [
    "string"
  ],
  "topic_path": "",
  "type": "insight",
  "valid_from_unix_ms": 0,
  "valid_to_unix_ms": 0,
  "workspace_hash": ""
}
Response
{
  "action": "string",
  "admission": {},
  "category": "string",
  "derived_from": {},
  "disposition": "string",
  "id": "string",
  "key": "string",
  "outcome_class": "save",
  "proposed": true,
  "provenance": {},
  "requires_review": true
}

Write Gate

read-only
TOOLperseus_vault_write_gate

#939 zero-token write gate: deterministic keep/supersede/forget BEFORE LLM enrichment. Read-only precheck over (category, key, body) that decides store / duplicate / supersede / forget / adjudicate from content-hash + stored-signature near-duplicate scans and an importance floor — ZERO LLM tokens. Only 'adjudicate' (a near-duplicate that may be a contradiction) should escalate to the LLM or operator review. Call this before the enrichment pass to cut per-write Ollama load.

Parameters

body_jsonstringrequiredargument

Serialized body of the candidate write.

categorystringrequiredargument

Entity category of the candidate write.

keystringrequiredargument

Entity key of the candidate write.

workspace_hashstringargument

Optional workspace scope for the scans.

Returns

Returns MCP content array (text, image, or embedded resource).

Write Gate
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_write_gate",
    "arguments": {
        "body_json": "string",
        "category": "string",
        "key": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_write_gate", {
  "body_json": "string",
  "category": "string",
  "key": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_write_gate", arguments={
  "body_json": "string",
  "category": "string",
  "key": "string",
  "workspace_hash": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Provider Source Event

destructive
TOOLperseus_vault_provider_source_event

Apply a versioned provider-native source event. Preserves stable provider identity, revision and content digests, timestamps, thread or parent lineage, visibility and workspace scope, and governed deletion tombstones. The envelope never accepts or stores raw provider bodies or payloads. Replaying the same provider/external_id/revision is idempotent.

Parameters

authorstringargument
canonical_uristringargument
capture_methodstringargument
content_sha256stringargument
entity_idstringargument
event_typestringupsertcommentreplyattachmentdeleterequiredargument
expected_revisionstringargument
external_idstringrequiredargument
kindstringrequiredargument
observed_at_unix_msinteger>= 0argument
parent_idstringargument
providerstringrequiredargument
provider_created_at_unix_msinteger>= 0argument
provider_event_idstringargument
provider_updated_at_unix_msinteger>= 0argument
requesting_agent_idstringargument

Transport-stamped identity; caller-supplied values are overwritten.

retention_policystringargument
revisionstringrequiredargument
schema_versionintegerrequiredargument
source_span_refstringargument
thread_idstringargument
visibilitystringprivateworkspacepublicargument
workspace_hashstringargument

Returns

entity_archivedboolean
event_idstring
event_typestring
outcomestringappliedidempotentrevision_racedeleted
previous_revisionstring
receipt_digeststring
schema_versioninteger
sourceobject
Provider Source Event
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_provider_source_event",
    "arguments": {
        "author": "string",
        "canonical_uri": "string",
        "capture_method": "string",
        "content_sha256": "string",
        "entity_id": "string",
        "event_type": "upsert",
        "expected_revision": "string",
        "external_id": "string",
        "kind": "string",
        "observed_at_unix_ms": 0,
        "parent_id": "string",
        "provider": "string",
        "provider_created_at_unix_ms": 0,
        "provider_event_id": "string",
        "provider_updated_at_unix_ms": 0,
        "requesting_agent_id": "string",
        "retention_policy": "string",
        "revision": "string",
        "schema_version": 1,
        "source_span_ref": "string",
        "thread_id": "string",
        "visibility": "private",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_provider_source_event", {
  "author": "string",
  "canonical_uri": "string",
  "capture_method": "string",
  "content_sha256": "string",
  "entity_id": "string",
  "event_type": "upsert",
  "expected_revision": "string",
  "external_id": "string",
  "kind": "string",
  "observed_at_unix_ms": 0,
  "parent_id": "string",
  "provider": "string",
  "provider_created_at_unix_ms": 0,
  "provider_event_id": "string",
  "provider_updated_at_unix_ms": 0,
  "requesting_agent_id": "string",
  "retention_policy": "string",
  "revision": "string",
  "schema_version": 1,
  "source_span_ref": "string",
  "thread_id": "string",
  "visibility": "private",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_provider_source_event", arguments={
  "author": "string",
  "canonical_uri": "string",
  "capture_method": "string",
  "content_sha256": "string",
  "entity_id": "string",
  "event_type": "upsert",
  "expected_revision": "string",
  "external_id": "string",
  "kind": "string",
  "observed_at_unix_ms": 0,
  "parent_id": "string",
  "provider": "string",
  "provider_created_at_unix_ms": 0,
  "provider_event_id": "string",
  "provider_updated_at_unix_ms": 0,
  "requesting_agent_id": "string",
  "retention_policy": "string",
  "revision": "string",
  "schema_version": 1,
  "source_span_ref": "string",
  "thread_id": "string",
  "visibility": "private",
  "workspace_hash": "string"
})
Response
{
  "entity_archived": true,
  "event_id": "string",
  "event_type": "string",
  "outcome": "applied",
  "previous_revision": "string",
  "receipt_digest": "string",
  "schema_version": 0,
  "source": {}
}

Declared Graph Manifest

destructive
TOOLperseus_vault_declared_graph_manifest

Apply a versioned, source-keyed declared graph manifest. Stable node and edge IDs are scoped by workspace and canonical identity; replace revisions supersede prior active topology, while delete revisions create tombstones and preserve history. Declared edges remain sourced or supported until explicitly attested. No LLM extraction is performed.

Body

application/json
content_sha256stringrequired
edgesArray<object>
Show child attributes
contextstring
directionstringforwardreverserequired
fromstringrequired
originstringrequired
predicatestringrequired
source_span_refstring
support_statestringsourcedsupportedrequired
tostringrequired
valid_from_unix_msinteger>= 0
valid_to_unix_msinteger>= 0
nodesArray<object>
Show child attributes
canonical_idstringrequired
external_refstring
namespacestringrequired
node_typestringrequired
operationstringupsertdeleterequired
policystringrequired
requesting_agent_idstring

Transport-stamped identity; caller-supplied values are overwritten.

revisionstringrequired
schema_versionintegerrequired
source_keystringrequired
source_span_refstring
valid_from_unix_msinteger>= 0
valid_to_unix_msinteger>= 0
workspace_hashstringrequired

Returns

edge_idsArray<string>required
edgesArray<object>required
manifest_idstringrequired
node_idsArray<string>required
outcomestringappliedidempotentrequired
schema_versionintegerrequired
source_idstringrequired
Declared Graph Manifest
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_declared_graph_manifest",
    "arguments": {
        "content_sha256": "string",
        "edges": [
          {
            "context": "string",
            "direction": "forward",
            "from": "string",
            "origin": "declared",
            "predicate": "string",
            "source_span_ref": "string",
            "support_state": "sourced",
            "to": "string",
            "valid_from_unix_ms": 0,
            "valid_to_unix_ms": 0
          }
        ],
        "nodes": [
          {
            "canonical_id": "string",
            "external_ref": "string",
            "namespace": "string",
            "node_type": "string"
          }
        ],
        "operation": "upsert",
        "policy": "replace",
        "requesting_agent_id": "string",
        "revision": "string",
        "schema_version": 1,
        "source_key": "string",
        "source_span_ref": "string",
        "valid_from_unix_ms": 0,
        "valid_to_unix_ms": 0,
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_declared_graph_manifest", {
  "content_sha256": "string",
  "edges": [
    {
      "context": "string",
      "direction": "forward",
      "from": "string",
      "origin": "declared",
      "predicate": "string",
      "source_span_ref": "string",
      "support_state": "sourced",
      "to": "string",
      "valid_from_unix_ms": 0,
      "valid_to_unix_ms": 0
    }
  ],
  "nodes": [
    {
      "canonical_id": "string",
      "external_ref": "string",
      "namespace": "string",
      "node_type": "string"
    }
  ],
  "operation": "upsert",
  "policy": "replace",
  "requesting_agent_id": "string",
  "revision": "string",
  "schema_version": 1,
  "source_key": "string",
  "source_span_ref": "string",
  "valid_from_unix_ms": 0,
  "valid_to_unix_ms": 0,
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_declared_graph_manifest", arguments={
  "content_sha256": "string",
  "edges": [
    {
      "context": "string",
      "direction": "forward",
      "from": "string",
      "origin": "declared",
      "predicate": "string",
      "source_span_ref": "string",
      "support_state": "sourced",
      "to": "string",
      "valid_from_unix_ms": 0,
      "valid_to_unix_ms": 0
    }
  ],
  "nodes": [
    {
      "canonical_id": "string",
      "external_ref": "string",
      "namespace": "string",
      "node_type": "string"
    }
  ],
  "operation": "upsert",
  "policy": "replace",
  "requesting_agent_id": "string",
  "revision": "string",
  "schema_version": 1,
  "source_key": "string",
  "source_span_ref": "string",
  "valid_from_unix_ms": 0,
  "valid_to_unix_ms": 0,
  "workspace_hash": "string"
})
Request Body
{
  "content_sha256": "string",
  "edges": [
    {
      "context": "string",
      "direction": "forward",
      "from": "string",
      "origin": "declared",
      "predicate": "string",
      "source_span_ref": "string",
      "support_state": "sourced",
      "to": "string",
      "valid_from_unix_ms": 0,
      "valid_to_unix_ms": 0
    }
  ],
  "nodes": [
    {
      "canonical_id": "string",
      "external_ref": "string",
      "namespace": "string",
      "node_type": "string"
    }
  ],
  "operation": "upsert",
  "policy": "replace",
  "requesting_agent_id": "string",
  "revision": "string",
  "schema_version": 1,
  "source_key": "string",
  "source_span_ref": "string",
  "valid_from_unix_ms": 0,
  "valid_to_unix_ms": 0,
  "workspace_hash": "string"
}
Response
{
  "edge_ids": [
    "string"
  ],
  "edges": [
    {}
  ],
  "manifest_id": "string",
  "node_ids": [
    "string"
  ],
  "outcome": "applied",
  "schema_version": 0,
  "source_id": "string"
}

Attest Declared Graph Edges

destructive
TOOLperseus_vault_declared_graph_attest

Explicitly attest selected active declared edges under an authority reference. Sourced or supported edges cannot become attested through ingestion alone; the selected edge IDs, manifest revision, attestor, and bounded reference are recorded and replay is idempotent.

Parameters

attestation_refstringrequiredargument
attested_bystringrequiredargument
edge_idsArray<string>requiredargument
requesting_agent_idstringargument

Transport-stamped identity; caller-supplied values are overwritten.

revisionstringrequiredargument
schema_versionintegerrequiredargument
source_keystringrequiredargument
workspace_hashstringrequiredargument

Returns

edge_idsArray<string>required
manifest_idstringrequired
outcomestringappliedidempotentrequired
receipt_digeststringrequired
schema_versionintegerrequired
Attest Declared Graph Edges
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_declared_graph_attest",
    "arguments": {
        "attestation_ref": "string",
        "attested_by": "string",
        "edge_ids": [
          "string"
        ],
        "requesting_agent_id": "string",
        "revision": "string",
        "schema_version": 1,
        "source_key": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_declared_graph_attest", {
  "attestation_ref": "string",
  "attested_by": "string",
  "edge_ids": [
    "string"
  ],
  "requesting_agent_id": "string",
  "revision": "string",
  "schema_version": 1,
  "source_key": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_declared_graph_attest", arguments={
  "attestation_ref": "string",
  "attested_by": "string",
  "edge_ids": [
    "string"
  ],
  "requesting_agent_id": "string",
  "revision": "string",
  "schema_version": 1,
  "source_key": "string",
  "workspace_hash": "string"
})
Response
{
  "edge_ids": [
    "string"
  ],
  "manifest_id": "string",
  "outcome": "applied",
  "receipt_digest": "string",
  "schema_version": 0
}

Query Declared Graph

read-only
TOOLperseus_vault_declared_graph_query

Read a bounded workspace-scoped projection of declared graph nodes and edges. Active-only output is the default; include_history exposes superseded and tombstoned revisions. Every edge carries source revision, digest/span, scope, origin, validity, and explicit attestation state. This is separate from ordinary recall and does not add graph traversal cost to normal queries.

Parameters

include_historybooleanfalseargument
limitinteger[1, 500]100argument
requesting_agent_idstringargument

Transport-stamped identity; caller-supplied values are overwritten.

source_keystringargument
workspace_hashstringrequiredargument

Returns

edgesArray<object>required
nodesArray<object>required
schema_versionintegerrequired
source_keystring
truncatedbooleanrequired
workspace_hashstringrequired
Query Declared Graph
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_declared_graph_query",
    "arguments": {
        "include_history": false,
        "limit": 100,
        "requesting_agent_id": "string",
        "source_key": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_declared_graph_query", {
  "include_history": false,
  "limit": 100,
  "requesting_agent_id": "string",
  "source_key": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_declared_graph_query", arguments={
  "include_history": false,
  "limit": 100,
  "requesting_agent_id": "string",
  "source_key": "string",
  "workspace_hash": "string"
})
Response
{
  "edges": [
    {}
  ],
  "nodes": [
    {}
  ],
  "schema_version": 0,
  "source_key": "string",
  "truncated": true,
  "workspace_hash": "string"
}

Recall Entities

read-only
TOOLperseus_vault_recall

Search entities with FTS5 keyword search. Words are OR'd together. Returns entities sorted by relevance with expanded content/summary fields at top level. Use this to find previously stored facts, decisions, or architecture notes. When encryption is enabled, body_json is decrypted transparently.

Body

application/json
agent_idstring

Agent identity filter (v1.2.0). When set, only entities with a matching agent_id are returned. Omit for no agent filtering.

as_of_unix_msinteger

#472 Temporal RAG: transaction-time instant (unix ms). Reconstruct semantic recall AS BELIEVED at this past instant — each hit's body is the version that was live at as_of_unix_ms; corrections recorded later do not leak in. Combine with valid_at for the full bi-temporal cell. Hits are stamped with is_live_version / recorded_at_unix_ms / valid_from_unix_ms / valid_to_unix_ms. Omit for today's live view. (v1: candidate generation is over the live index, so a fact fully deleted since that instant will not surface.)

categorystring

Filter by category, e.g. 'decision' or 'architecture'

content_weightnumber[0, 1]0

Additive boost for content witness — rewards entities whose body text literally contains query terms. Damped by body length. Never penalizes.

deadline_msinteger

#864: bounded recall. When set, the recall is timed; if it exceeds this many ms the response outcome.status is 'timeout' so callers know the result set may be incomplete. Results are still returned in full.

depth_budgetstringlowmidhigh

Fused mode only: depth budget -> default token caps 1024 / 4096 / 16384 when max_tokens is unset.

diversity_halvingnumber[0, 1]1

Per-keyword diversity quota factor (1.0=disabled). Each distinct matched keyword gets ceil(N x halving^n) slots — first keyword N, second N/2, etc.

epistemic_statestringcandidateverifiedcorroboratedrejecteddefensively_recalled

#880: epistemic trust-axis filter. When set, only entities in the requested trust state are returned — 'candidate' surfaces useful-but-unverified records, 'verified'/'corroborated' restrict to established fact, 'rejected' shows reviewed-and-refused records. Omit for no trust filtering (default).

evidence_lanesArray<string>derivedverbatim

#1135: opt-in governed answer-facing evidence lanes. Omit for the legacy byte-compatible recall response; choose derived, verbatim, or both under the shared max_tokens budget. Duplicate lane names are canonicalized.

expansionobject

Configuration for FTS5 query expansion using Porter stemming

Show child attributes
enabledbooleanfalse

Enable stemming-based query expansion

n_variantsinteger1

Number of stemmed token variants to generate

graph_utility_thresholdnumber

Fused mode only (#869): graph utility gate threshold in [0,1]. The graph strategy engages only when the query's classified graph utility is >= this value. Omit = 0.5 (documented default). 0.0 disables the gate; 1.0 effectively never engages. The routing decision is always observable in fused_trace.graph_route (reason, selected, skipped_reason, gate counts).

include_archivedbooleanfalse

Include archived (soft-deleted) entities in results

include_confidencebooleanfalse

Add a normalized confidence score (0.0-1.0) to each result, rolled up from rank, trust (verified/certainty), and decay. Presentation-only; does not change ranking.

include_conflict_flagsbooleanfalse

#917: add deterministic contradiction/superseded/stale flags containing only entity IDs, validity ranges, and hash-linked claim-card evidence refs. Suppressed values disclose existence only; no body value is rendered.

include_conflict_flags_markdownbooleanfalse

#917: independently add an ID/hash/validity-only markdown conflict block. Does not implicitly enable structured conflict_flags.

include_declared_graphbooleanfalse

#1142: attach a bounded workspace-scoped hash-only declared graph projection. Requires workspace_hash and a transport-stamped requester; ordinary recall does not query the graph.

include_outcomebooleanfalse

#864/#873/#887: always attach the explicit 'outcome' block (status, backend health, abstention, reason). By default it is attached only when recall was degraded/partial/timeout/empty/unavailable/stale, so nominal responses stay byte-identical.

include_provider_sourcebooleanfalse

#1141: include only sanitized provider identity, revision, digest, scope, and thread lineage; raw provider bodies and payloads are never returned.

include_selection_decisionsbooleanfalse

#1140: fused mode only. Attach a bounded, hash-only per-candidate selection projection with source-arm ranks, eligibility/disposition reason codes, token-estimator state, unavailable-arm state, and a replay fingerprint. Omit to preserve the legacy response shape.

layerstring

Filter by memory layer (world, episodic, semantic).

limitinteger10

Maximum number of results to return (max 1000)

max_tokensinteger0

Fused mode only: token-budget truncation (estimated tokens = chars/4 per body). 0 = derive from depth_budget (mid = 4096).

min_decaynumber0

Minimum decay score threshold 0.0–1.0 — higher values return fresher results

modestringfts5densehybridfusedfts5

Search mode: 'fts5' (keyword), 'dense' (vector), 'hybrid' (fused via RRF), or 'fused' (TEMPR-style multi-strategy: fts5 + dense + graph + temporal with weighted RRF, token-budget truncation, and a full fused_trace, #883)

offsetinteger0

Number of results to skip for pagination

preview_capinteger

If set, truncate body_json at N chars and append drill-down footer. Use perseus_vault_get_entity to read full body.

profilestringdefaultvalidity

#860: validity-aware recall profile. 'validity' re-ranks fused results by a deterministic validity multiplier (freshness decay, scope match, provenance class, supersession, expiry proximity) and annotates every item with its validity info; 'default'/omitted keeps relevance-only ordering. On non-fused modes the profile only enables item annotation. The weights, grade distribution, and context-invalid count are observable in fused_trace.validity.

querystringrequired

Search query — words are OR'd together for broad recall. An EMPTY string ("") is the match-all / enumeration path: it drops the keyword predicate and returns every entity in scope (respecting category/type/limit/offset), so it is the way to 'list all' a category. Wildcards are NOT globs: "" is a literal FTS5 term and matches nothing — pass "" to enumerate, not "".

query_time_unix_msinteger

Fused mode only: anchor instant for the temporal strategy (unix ms; default now). Accepts a number or numeric string.

recency_half_life_secsnumber>= 0

Time-aware ranking for mode='hybrid' (default off). When set, each fused result's score is multiplied by 0.5^(age / this), where age is seconds since the memory was created — so a memory this many seconds old keeps half its weight and recent context outranks older but similar hits. Omit for relevance-only ranking.

ref_typestring

#728: post-filter hits to entities whose body external_refs carry this ref_type (exact match, e.g. 'repo', 'pull_request', 'jira_key').

ref_valuestring

#728: post-filter hits to entities whose body external_refs carry this ref_value. Matches exactly or as a hierarchical '/' prefix ('github:Org' matches 'github:Org/repo').

reinforcebooleanfalse

Opt-in reinforcement for mode='dense'/'hybrid': bump retrieval_count/last_accessed/decay on the returned hits so semantically-used memories resist decay and promote through layers. Default false keeps semantic recall side-effect-free and byte-deterministic over a frozen DB. No effect on mode='fts5', which already reinforces.

requesting_agent_idstring

Transport-stamped requester identity used for private/fleet visibility enforcement.

rerankbooleanfalse

Fused mode only: optional rerank stage over the fused pool (rank-calibrated dense + BM25 agreement signals; default off, latency-preserving).

retrieval_profilestringpersonalagentshared

#784 serving posture. personal returns preference/personal classes; agent returns convention/correction/keystone classes; shared (default) returns non-personal memory in the requested workspace. Applied after visibility filtering.

scope_weightnumber[0, 1]

#485: scope as a ranking multiplier instead of a hard filter. Requires workspace_hash. Widens the workspace filter to also include GLOBAL (workspace_hash='') memories, weighted by this factor in the ranking (hybrid/dense scores multiplied; keyword mode returns current-scope hits first) — current-workspace memories outrank equally-relevant global ones, but a strong global memory still surfaces. Never exposes other workspaces' memories. Omit for the strict filter (unchanged default).

strategiesArray<string>fts5densegraphtemporal

Fused mode only: strategies to engage (2-4). Omit = all four. Unknown names are rejected.

strategy_weightsobject

Fused mode only: per-strategy RRF weight multipliers (default 1.0 each). Arms that find nothing contribute nothing.

topic_pathstring

Filter by topic path prefix, e.g. 'architecture/'

trust_weightnumber[0, 1]0.15

Additive boost for provenance/trust (default 0.15, on by default) — verified sources rank above unverified AI drafts on the same topic. Verified entities get the full boost; unverified ones are scaled by certainty. Set 0 to disable. Never penalizes.

typestring

Filter by entity type, e.g. 'insight' or 'reference'

valid_atinteger

Valid-time instant (#363/#472, unix ms): reconstruct recall to the world-version whose application-time period [valid_from, valid_to) contains this instant — 'what was true at time T', per current (or as_of) knowledge. Rebuilds the point-in-time body from history (not just a live-row narrow) and returns hits stamped with is_live_version / recorded_at_unix_ms / valid_from/to. Combine with as_of_unix_ms for the full bi-temporal cell.

valid_from_unix_msinteger

Valid-time period filter start (#363, unix ms). Pair with valid_to_unix_ms and valid_op; ignored when valid_at is set. Omit for unbounded start.

valid_opstringoverlapscontainsoverlaps

SQL:2011 period predicate for the valid-time period filter (#363): 'overlaps' (fact's valid period shares at least one instant with the queried period) or 'contains' (fact's valid period contains the whole queried period).

valid_to_unix_msinteger

Valid-time period filter end (#363, unix ms, exclusive). Omit for unbounded end.

validity_annotatebooleanfalse

#860: annotate delivered items with their validity info (grade, freshness, scope match, provenance class, superseded, expiring/expired, multiplier, signals); context-invalid items are additionally flagged 'context_invalid': true. Implied by profile='validity'.

workspace_hashstring

Workspace scope filter (v1.2.0). When set, only entities with a matching workspace_hash are returned. Omit for no workspace filtering.

Returns

abstain_hintboolean

#917: true only when a high-confidence direct contradiction is present in the delivered set

conflict_flagsArray<object>

#917: optional deterministic contradiction/supersession/staleness flags; IDs, validity ranges, and hash-linked evidence refs only

conflict_flags_markdownstring

#917: optional ID/hash/validity-only markdown rendering of conflict flags

declared_graphobject

#1142: optional bounded declared graph projection; nodes/edges carry hash-only source, span, scope, origin, validity, and support state.

evidenceobject

#1135: optional governed derived/verbatim evidence projection with shared budget, exclusions, source groups, and hash-only receipt. Present only when evidence_lanes is supplied.

fused_traceobject

#883: fused serving trace. When include_selection_decisions=true it contains selection_decisions: a bounded hash-only projection of candidate eligibility, dispositions, arm states, token estimates, delivered order, and replay fingerprint.

itemsArray<object>

Matching entities with expanded body_json fields at top level

totalinteger

Number of results returned

variantsinteger

Number of query variants used when expansion is enabled

Recall Entities
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_recall",
    "arguments": {
        "agent_id": "string",
        "as_of_unix_ms": 0,
        "category": "string",
        "content_weight": 0,
        "deadline_ms": 0,
        "depth_budget": "low",
        "diversity_halving": 1,
        "epistemic_state": "candidate",
        "evidence_lanes": [
          "derived"
        ],
        "expansion": {
          "enabled": false,
          "n_variants": 1
        },
        "graph_utility_threshold": 0,
        "include_archived": false,
        "include_confidence": false,
        "include_conflict_flags": false,
        "include_conflict_flags_markdown": false,
        "include_declared_graph": false,
        "include_outcome": false,
        "include_provider_source": false,
        "include_selection_decisions": false,
        "layer": "string",
        "limit": 10,
        "max_tokens": 0,
        "min_decay": 0,
        "mode": "fts5",
        "offset": 0,
        "preview_cap": 0,
        "profile": "default",
        "query": "string",
        "query_time_unix_ms": 0,
        "recency_half_life_secs": 0,
        "ref_type": "string",
        "ref_value": "string",
        "reinforce": false,
        "requesting_agent_id": "string",
        "rerank": false,
        "retrieval_profile": "personal",
        "scope_weight": 0,
        "strategies": [
          "fts5"
        ],
        "strategy_weights": {},
        "topic_path": "string",
        "trust_weight": 0.15,
        "type": "string",
        "valid_at": 0,
        "valid_from_unix_ms": 0,
        "valid_op": "overlaps",
        "valid_to_unix_ms": 0,
        "validity_annotate": false,
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_recall", {
  "agent_id": "string",
  "as_of_unix_ms": 0,
  "category": "string",
  "content_weight": 0,
  "deadline_ms": 0,
  "depth_budget": "low",
  "diversity_halving": 1,
  "epistemic_state": "candidate",
  "evidence_lanes": [
    "derived"
  ],
  "expansion": {
    "enabled": false,
    "n_variants": 1
  },
  "graph_utility_threshold": 0,
  "include_archived": false,
  "include_confidence": false,
  "include_conflict_flags": false,
  "include_conflict_flags_markdown": false,
  "include_declared_graph": false,
  "include_outcome": false,
  "include_provider_source": false,
  "include_selection_decisions": false,
  "layer": "string",
  "limit": 10,
  "max_tokens": 0,
  "min_decay": 0,
  "mode": "fts5",
  "offset": 0,
  "preview_cap": 0,
  "profile": "default",
  "query": "string",
  "query_time_unix_ms": 0,
  "recency_half_life_secs": 0,
  "ref_type": "string",
  "ref_value": "string",
  "reinforce": false,
  "requesting_agent_id": "string",
  "rerank": false,
  "retrieval_profile": "personal",
  "scope_weight": 0,
  "strategies": [
    "fts5"
  ],
  "strategy_weights": {},
  "topic_path": "string",
  "trust_weight": 0.15,
  "type": "string",
  "valid_at": 0,
  "valid_from_unix_ms": 0,
  "valid_op": "overlaps",
  "valid_to_unix_ms": 0,
  "validity_annotate": false,
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_recall", arguments={
  "agent_id": "string",
  "as_of_unix_ms": 0,
  "category": "string",
  "content_weight": 0,
  "deadline_ms": 0,
  "depth_budget": "low",
  "diversity_halving": 1,
  "epistemic_state": "candidate",
  "evidence_lanes": [
    "derived"
  ],
  "expansion": {
    "enabled": false,
    "n_variants": 1
  },
  "graph_utility_threshold": 0,
  "include_archived": false,
  "include_confidence": false,
  "include_conflict_flags": false,
  "include_conflict_flags_markdown": false,
  "include_declared_graph": false,
  "include_outcome": false,
  "include_provider_source": false,
  "include_selection_decisions": false,
  "layer": "string",
  "limit": 10,
  "max_tokens": 0,
  "min_decay": 0,
  "mode": "fts5",
  "offset": 0,
  "preview_cap": 0,
  "profile": "default",
  "query": "string",
  "query_time_unix_ms": 0,
  "recency_half_life_secs": 0,
  "ref_type": "string",
  "ref_value": "string",
  "reinforce": false,
  "requesting_agent_id": "string",
  "rerank": false,
  "retrieval_profile": "personal",
  "scope_weight": 0,
  "strategies": [
    "fts5"
  ],
  "strategy_weights": {},
  "topic_path": "string",
  "trust_weight": 0.15,
  "type": "string",
  "valid_at": 0,
  "valid_from_unix_ms": 0,
  "valid_op": "overlaps",
  "valid_to_unix_ms": 0,
  "validity_annotate": false,
  "workspace_hash": "string"
})
Request Body
{
  "agent_id": "string",
  "as_of_unix_ms": 0,
  "category": "string",
  "content_weight": 0,
  "deadline_ms": 0,
  "depth_budget": "low",
  "diversity_halving": 1,
  "epistemic_state": "candidate",
  "evidence_lanes": [
    "derived"
  ],
  "expansion": {
    "enabled": false,
    "n_variants": 1
  },
  "graph_utility_threshold": 0,
  "include_archived": false,
  "include_confidence": false,
  "include_conflict_flags": false,
  "include_conflict_flags_markdown": false,
  "include_declared_graph": false,
  "include_outcome": false,
  "include_provider_source": false,
  "include_selection_decisions": false,
  "layer": "string",
  "limit": 10,
  "max_tokens": 0,
  "min_decay": 0,
  "mode": "fts5",
  "offset": 0,
  "preview_cap": 0,
  "profile": "default",
  "query": "string",
  "query_time_unix_ms": 0,
  "recency_half_life_secs": 0,
  "ref_type": "string",
  "ref_value": "string",
  "reinforce": false,
  "requesting_agent_id": "string",
  "rerank": false,
  "retrieval_profile": "personal",
  "scope_weight": 0,
  "strategies": [
    "fts5"
  ],
  "strategy_weights": {},
  "topic_path": "string",
  "trust_weight": 0.15,
  "type": "string",
  "valid_at": 0,
  "valid_from_unix_ms": 0,
  "valid_op": "overlaps",
  "valid_to_unix_ms": 0,
  "validity_annotate": false,
  "workspace_hash": "string"
}
Response
{
  "abstain_hint": true,
  "conflict_flags": [
    {}
  ],
  "conflict_flags_markdown": "string",
  "declared_graph": {},
  "evidence": {},
  "fused_trace": {},
  "items": [
    {}
  ],
  "total": 0,
  "variants": 0
}

Handoff Pack

read-only
TOOLperseus_vault_handoff_pack

Budgeted handoff pack: lifecycle-filtered (expired/superseded excluded), provenance-tagged context for cross-session handoffs under a hard token budget, with exclusion visibility and a deterministic pack digest. Candidates from FTS5 recall; greedy-with-backfill packing; never exceeds budget_tokens. Optional planning-boundary enrichment (#1039): include_intent_trail adds recent journal events tied to the pack, include_next_work adds journal forward plans plus recall_when anticipation matches, include_conflicts adds pack-scoped contradiction flags.

Parameters

budget_tokensintegerargument

Hard pack budget in tokens (chars/4), 100..100000, default 2000

include_conflictsbooleanargument

Add pack-scoped contradiction flags from the conflict detector (default false)

include_expiredbooleanargument

Include expired checkable claims (default false)

include_intent_trailbooleanargument

Add intent_trail: recent journal events tied to the packed entities (default false)

include_next_workbooleanargument

Add next_work: journal forward plans + recall_when anticipation matches for the scope (default false)

max_excludedintegerargument

Max excluded items listed with reasons, 0..200, default 20

max_trailintegerargument

Max intent-trail events to return, 1..20, default 5

querystringrequiredargument

Handoff topic query (required, non-empty)

workspace_hashstringargument

Workspace scope hash. When set, the pack and its enrichment are scoped to that workspace.

Returns

Returns MCP content array (text, image, or embedded resource).

Handoff Pack
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_handoff_pack",
    "arguments": {
        "budget_tokens": 0,
        "include_conflicts": true,
        "include_expired": true,
        "include_intent_trail": true,
        "include_next_work": true,
        "max_excluded": 0,
        "max_trail": 0,
        "query": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_handoff_pack", {
  "budget_tokens": 0,
  "include_conflicts": true,
  "include_expired": true,
  "include_intent_trail": true,
  "include_next_work": true,
  "max_excluded": 0,
  "max_trail": 0,
  "query": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_handoff_pack", arguments={
  "budget_tokens": 0,
  "include_conflicts": true,
  "include_expired": true,
  "include_intent_trail": true,
  "include_next_work": true,
  "max_excluded": 0,
  "max_trail": 0,
  "query": "string",
  "workspace_hash": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Delegation Brief

read-only
TOOLperseus_vault_delegation_brief

Deterministic markdown delegation brief generated at the planning boundary (#1039): goal + scope + binding context (superseded items excluded and listed as do-not-resurrect) + intent trail + next work + output contract. Hand a subagent the brief instead of the parent chat session; the brief is self-contained for the delegated task.

Parameters

budget_tokensintegerargument

Hard brief budget in tokens (chars/4), 200..100000, default 4000

goalstringrequiredargument

One-sentence goal of the delegated task (required, non-empty)

include_expiredbooleanargument

Include expired checkable claims in binding context (default false)

output_contractstringargument

Exact output the delegate must produce (files, commands, report shape). Omitted = return a plan with explicit open questions.

querystringrequiredargument

Scope anchor query for the delegation (required, non-empty)

workspace_hashstringargument

Workspace scope hash. When set, the brief is built only from that workspace.

Returns

Returns MCP content array (text, image, or embedded resource).

Delegation Brief
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_delegation_brief",
    "arguments": {
        "budget_tokens": 0,
        "goal": "string",
        "include_expired": true,
        "output_contract": "string",
        "query": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_delegation_brief", {
  "budget_tokens": 0,
  "goal": "string",
  "include_expired": true,
  "output_contract": "string",
  "query": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_delegation_brief", arguments={
  "budget_tokens": 0,
  "goal": "string",
  "include_expired": true,
  "output_contract": "string",
  "query": "string",
  "workspace_hash": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Intention Program

TOOLperseus_vault_intention

Prospective memory: typed intention programs (Latch borrow) with immutable revisions, compound triggers/inhibitors, time windows, approval flags, atomic exactly-once claims (JSON1 compare-and-set), and purpose-based forgetting. Ops: create|update (new immutable revision), evaluate (waiting|ready|blocked|expired + reasons), claim (exactly-once), complete|fail (one-shot auto-forgets), list.

Parameters

claimed_bystringargument

Claimer identity for the claim op

namestringargument

Intention name (required for all ops except list)

notestringargument

Outcome note for complete/fail

opstringcreateupdateevaluateclaimcompletefaillistrequiredargument

Operation

programobjectargument

Instruction: {when:{triggers:[{query}]}, unless:{inhibitors:[{query}]}, window:{after_unix_ms?,before_unix_ms?}, action:{kind,params}, approval:'required'|'auto'}

purposestringone_shotrecurringargument

one_shot auto-forgets on completion (default one_shot)

Returns

Returns MCP content array (text, image, or embedded resource).

Intention Program
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_intention",
    "arguments": {
        "claimed_by": "string",
        "name": "string",
        "note": "string",
        "op": "create",
        "program": {},
        "purpose": "one_shot"
      }
  }
}
const result = await client.callTool("perseus_vault_intention", {
  "claimed_by": "string",
  "name": "string",
  "note": "string",
  "op": "create",
  "program": {},
  "purpose": "one_shot"
});
result = await session.call_tool("perseus_vault_intention", arguments={
  "claimed_by": "string",
  "name": "string",
  "note": "string",
  "op": "create",
  "program": {},
  "purpose": "one_shot"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Proof Frame

read-only
TOOLperseus_vault_proof_frame

Proof frame: bounded, hash-cited evidence pack for external consumers (Qorx Zero borrow). Memory stays on-device; the consumer gets only a capped frame (top-N records + per-record source hashes + frame digest). Empty frame -> refusal, never invention. zeroize:true permanently blanks framed entities' bodies after framing (privacy end-state).

Parameters

max_charsintegerargument

Max frame chars, 200..20000, default 1600

max_recordsintegerargument

Max records in the frame, 1..20, default 5

querystringrequiredargument

Evidence question (required, non-empty)

workspace_hashstringargument

Workspace scope hash

zeroizebooleanargument

Blank framed entities' bodies after framing (default false)

Returns

Returns MCP content array (text, image, or embedded resource).

Proof Frame
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_proof_frame",
    "arguments": {
        "max_chars": 0,
        "max_records": 0,
        "query": "string",
        "workspace_hash": "string",
        "zeroize": true
      }
  }
}
const result = await client.callTool("perseus_vault_proof_frame", {
  "max_chars": 0,
  "max_records": 0,
  "query": "string",
  "workspace_hash": "string",
  "zeroize": true
});
result = await session.call_tool("perseus_vault_proof_frame", arguments={
  "max_chars": 0,
  "max_records": 0,
  "query": "string",
  "workspace_hash": "string",
  "zeroize": true
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Recall Entities Batch

read-only
TOOLperseus_vault_recall_batch

Recall entities across a batch of queries, fusing their results server-side using reciprocal rank fusion (RRF) to merge, deduplicate, and surface the most globally relevant memories first.

Body

application/json
queriesArray<object>required
Show child attributes
agent_idstring

Agent identity filter.

as_of_unix_msinteger

Temporal RAG transaction-time.

categorystring

Filter by category, e.g. 'decision' or 'architecture'

content_weightnumber[0, 1]0

Additive boost for content witness — rewards entities whose body text literally contains query terms.

diversity_halvingnumber[0, 1]1

Per-keyword diversity quota factor (1.0=disabled).

include_archivedbooleanfalse

Include archived (soft-deleted) entities in results

include_confidencebooleanfalse

Add a normalized confidence score (0.0-1.0) to each result, rolled up from rank, trust (verified/certainty), and decay. Presentation-only; does not change ranking.

layerstring

Filter by memory layer (world, episodic, semantic).

limitinteger10

Maximum number of results to return (max 1000)

min_decaynumber0

Minimum decay score threshold 0.0–1.0 — higher values return fresher results

modestringfts5densehybridfts5

Search mode: 'fts5' (keyword), 'dense' (vector), or 'hybrid' (fused via RRF)

offsetinteger0

Number of results to skip for pagination

preview_capinteger

If set, truncate body_json at N chars and append drill-down footer.

querystringrequired

Search query — words are OR'd together for broad recall. An EMPTY string ("") is the match-all / enumeration path.

recency_half_life_secsnumber>= 0

Time-aware ranking for mode='hybrid' (default off).

reinforcebooleanfalse

Opt-in reinforcement for mode='dense'/'hybrid': bump retrieval_count/last_accessed/decay on the returned hits so semantically-used memories resist decay.

scope_weightnumber[0, 1]

#485: scope as a ranking multiplier instead of a hard filter.

topic_pathstring

Filter by topic path prefix, e.g. 'architecture/'

trust_weightnumber[0, 1]0.15

Additive boost for provenance/trust (default 0.15, on by default).

typestring

Filter by entity type, e.g. 'insight' or 'reference'

valid_atinteger

Valid-time instant.

valid_from_unix_msinteger

Valid-time period filter start.

valid_opstringoverlapscontainsoverlaps

SQL:2011 period predicate for valid-time period filter.

valid_to_unix_msinteger

Valid-time period filter end.

workspace_hashstring

Workspace scope filter.

requesting_agent_idstring

Transport-stamped requester identity applied to every nested query and fused result.

Returns

itemsArray<object>

Matching entities fused from batch queries with expanded body_json fields at top level

totalinteger

Number of results returned

Recall Entities Batch
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_recall_batch",
    "arguments": {
        "queries": [
          {
            "agent_id": "string",
            "as_of_unix_ms": 0,
            "category": "string",
            "content_weight": 0,
            "diversity_halving": 1,
            "include_archived": false,
            "include_confidence": false,
            "layer": "string",
            "limit": 10,
            "min_decay": 0,
            "mode": "fts5",
            "offset": 0,
            "preview_cap": 0,
            "query": "string",
            "recency_half_life_secs": 0,
            "reinforce": false,
            "scope_weight": 0,
            "topic_path": "string",
            "trust_weight": 0.15,
            "type": "string",
            "valid_at": 0,
            "valid_from_unix_ms": 0,
            "valid_op": "overlaps",
            "valid_to_unix_ms": 0,
            "workspace_hash": "string"
          }
        ],
        "requesting_agent_id": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_recall_batch", {
  "queries": [
    {
      "agent_id": "string",
      "as_of_unix_ms": 0,
      "category": "string",
      "content_weight": 0,
      "diversity_halving": 1,
      "include_archived": false,
      "include_confidence": false,
      "layer": "string",
      "limit": 10,
      "min_decay": 0,
      "mode": "fts5",
      "offset": 0,
      "preview_cap": 0,
      "query": "string",
      "recency_half_life_secs": 0,
      "reinforce": false,
      "scope_weight": 0,
      "topic_path": "string",
      "trust_weight": 0.15,
      "type": "string",
      "valid_at": 0,
      "valid_from_unix_ms": 0,
      "valid_op": "overlaps",
      "valid_to_unix_ms": 0,
      "workspace_hash": "string"
    }
  ],
  "requesting_agent_id": "string"
});
result = await session.call_tool("perseus_vault_recall_batch", arguments={
  "queries": [
    {
      "agent_id": "string",
      "as_of_unix_ms": 0,
      "category": "string",
      "content_weight": 0,
      "diversity_halving": 1,
      "include_archived": false,
      "include_confidence": false,
      "layer": "string",
      "limit": 10,
      "min_decay": 0,
      "mode": "fts5",
      "offset": 0,
      "preview_cap": 0,
      "query": "string",
      "recency_half_life_secs": 0,
      "reinforce": false,
      "scope_weight": 0,
      "topic_path": "string",
      "trust_weight": 0.15,
      "type": "string",
      "valid_at": 0,
      "valid_from_unix_ms": 0,
      "valid_op": "overlaps",
      "valid_to_unix_ms": 0,
      "workspace_hash": "string"
    }
  ],
  "requesting_agent_id": "string"
})
Request Body
{
  "queries": [
    {
      "agent_id": "string",
      "as_of_unix_ms": 0,
      "category": "string",
      "content_weight": 0,
      "diversity_halving": 1,
      "include_archived": false,
      "include_confidence": false,
      "layer": "string",
      "limit": 10,
      "min_decay": 0,
      "mode": "fts5",
      "offset": 0,
      "preview_cap": 0,
      "query": "string",
      "recency_half_life_secs": 0,
      "reinforce": false,
      "scope_weight": 0,
      "topic_path": "string",
      "trust_weight": 0.15,
      "type": "string",
      "valid_at": 0,
      "valid_from_unix_ms": 0,
      "valid_op": "overlaps",
      "valid_to_unix_ms": 0,
      "workspace_hash": "string"
    }
  ],
  "requesting_agent_id": "string"
}
Response
{
  "items": [
    {}
  ],
  "total": 0
}

perseus_vault_recall_layer

read-only
TOOLperseus_vault_recall_layer

Recall entities from a specific biomimetic memory layer (world, episodic, semantic).

Parameters

layerstringworldepisodicsemanticrequiredargument

The memory layer to recall from.

limitinteger10argument

Maximum number of results to return (max 1000).

requesting_agent_idstringargument

Transport-stamped requester identity used for visibility enforcement.

Returns

itemsArray<object>

Matching entities with expanded body_json fields at top level.

totalinteger

Number of results returned.

perseus_vault_recall_layer
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_recall_layer",
    "arguments": {
        "layer": "world",
        "limit": 10,
        "requesting_agent_id": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_recall_layer", {
  "layer": "world",
  "limit": 10,
  "requesting_agent_id": "string"
});
result = await session.call_tool("perseus_vault_recall_layer", arguments={
  "layer": "world",
  "limit": 10,
  "requesting_agent_id": "string"
})
Response
{
  "items": [
    {}
  ],
  "total": 0
}

Scan / Enumerate Entities

read-only
TOOLperseus_vault_scan

Enumerate every entity in a category (or the whole store) deterministically, page by page (#562). This is the first-class 'list all / export / sync / reset' path: pages are keyed by immutable entity id (ascending) with a continuation cursor, so repeated calls walk the full set exactly once — unlike recall(query="") pagination, whose relevance ordering mutates as recalls reinforce entities (pages can skip or repeat rows) and whose offset is capped. Call with no cursor for the first page, then pass back next_cursor until has_more is false. Read-only: scanning does not bump retrieval counts or decay. Note the recall query contract this complements: recall's query="" is match-all enumeration; "*" is a literal FTS5 term (NOT a glob) and matches nothing.

Parameters

categorystringargument

Category to enumerate, e.g. 'decision'. Omit or pass "" to scan every category (no category is excluded — unlike recall, which hides high-volume categories such as 'conversation' unless explicitly requested).

cursorstringargument

Continuation cursor: the next_cursor value from the previous page. Omit for the first page.

include_archivedbooleanfalseargument

Compatibility flag retained for callers that request historical rows; public scans never return archived or terminal bodies. Use dedicated terminal-audit surfaces for hash-only audit markers.

limitinteger100argument

Page size (1–1000).

workspace_hashstringargument

Workspace scope filter. When set, only entities with exactly this workspace_hash are returned ("" targets only global entities). Omit for unscoped.

Returns

has_moreboolean

True when another page exists.

itemsArray<object>

Entities in this page, ordered by id ascending, with expanded body_json fields at top level.

next_cursorstring | null

Pass this as cursor to fetch the next page. Null on the final page.

totalinteger

Number of entities in this page.

Scan / Enumerate Entities
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_scan",
    "arguments": {
        "category": "string",
        "cursor": "string",
        "include_archived": false,
        "limit": 100,
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_scan", {
  "category": "string",
  "cursor": "string",
  "include_archived": false,
  "limit": 100,
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_scan", arguments={
  "category": "string",
  "cursor": "string",
  "include_archived": false,
  "limit": 100,
  "workspace_hash": "string"
})
Response
{
  "has_more": true,
  "items": [
    {}
  ],
  "next_cursor": "string",
  "total": 0
}

Startup-Memory Hygiene Report

read-only
TOOLperseus_vault_hygiene

Read-only hygiene report: surface likely low-signal memories so a startup-memory block stays dense without manual forensics. Scores every active memory by startup 'actionability' (the same signal as recall's startup mode) — concrete anchors like issue/ticket keys, #refs, paths, URLs, named systems, and decision/escalation language score high; vague, date-only titles (e.g. '2026-07-13') and very short bodies score low — and returns the worst offenders (below threshold) with the reasons they were flagged. Keyset-scans in pages; never bumps retrieval counts or decay. Use it to find archive/consolidate candidates before curating startup recall.

Parameters

categorystringargument

Restrict the scan to one category, e.g. 'memories'. Omit to scan every active category.

limitinteger50argument

Maximum flagged rows to return, worst first (1–1000).

scan_limitinteger1000argument

Maximum active memories to scan (1–10000).

thresholdnumber0.35argument

Actionability score (0.0–1.0) below which a memory is flagged low-signal. Lower = stricter (fewer flags).

Returns

flaggedArray<object>

Worst-first: {id, category, key, actionability, reasons[], retrieval_count}. reasons ∈ date_only_title | short_body | no_concrete_entities | low_actionability.

flagged_countinteger

Total memories below the threshold (may exceed the returned rows).

returnedinteger

Number of flagged rows in this response.

scannedinteger

Number of active memories inspected.

thresholdnumber

The actionability threshold applied.

Startup-Memory Hygiene Report
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_hygiene",
    "arguments": {
        "category": "string",
        "limit": 50,
        "scan_limit": 1000,
        "threshold": 0.35
      }
  }
}
const result = await client.callTool("perseus_vault_hygiene", {
  "category": "string",
  "limit": 50,
  "scan_limit": 1000,
  "threshold": 0.35
});
result = await session.call_tool("perseus_vault_hygiene", arguments={
  "category": "string",
  "limit": 50,
  "scan_limit": 1000,
  "threshold": 0.35
})
Response
{
  "flagged": [
    {}
  ],
  "flagged_count": 0,
  "returned": 0,
  "scanned": 0,
  "threshold": 0
}

Promote Memory

destructive
TOOLperseus_vault_promote

Promote a memory across the class ladder (to_category) and/or the scope ladder (to_workspace_hash) per the shared-memory promotion ladder (perseus docs/shared-memory-promotion-ladder.md §4). Creates a new entity that carries a promoted_from provenance record (source category/key/id/scope, reason, timestamp) and links the source to it with relationship='promoted_to'. The source entity is never edited or hidden — raw evidence stays reachable. Uses skip_dedup internally so the promoted copy always creates its own key even when near-identical to the source.

Parameters

from_categorystringrequiredargument

Category of the source entity to promote

from_keystringrequiredargument

Key of the source entity to promote

reasonstringargument

Why this promotion is happening (recorded in promoted_from).

to_categorystringargument

Target class/category. Omit to keep the source category.

to_keystringargument

Target key. Omit to keep the source key.

to_workspace_hashstringargument

Target scope (workspace_hash; empty string = global). Omit to keep the source scope.

Returns

actionstring

'created' or 'updated' for the target entity

from_idstring
promotedboolean
to_idstring
to_workspace_hashstring
Promote Memory
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_promote",
    "arguments": {
        "from_category": "string",
        "from_key": "string",
        "reason": "string",
        "to_category": "string",
        "to_key": "string",
        "to_workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_promote", {
  "from_category": "string",
  "from_key": "string",
  "reason": "string",
  "to_category": "string",
  "to_key": "string",
  "to_workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_promote", arguments={
  "from_category": "string",
  "from_key": "string",
  "reason": "string",
  "to_category": "string",
  "to_key": "string",
  "to_workspace_hash": "string"
})
Response
{
  "action": "string",
  "from_id": "string",
  "promoted": true,
  "to_id": "string",
  "to_workspace_hash": "string"
}

Demote Memory

destructive
TOOLperseus_vault_demote

Demote a governed memory exactly one rung down the durable-memory ladder. Writes a provenance-preserving copy, a demoted_to link, and an append-only demotion journal event.

Parameters

from_categorystringrequiredargument
from_keystringrequiredargument
reasonstringargument
to_categorystringrequiredargument
to_keystringargument

Returns

demotedboolean
to_idstring
Demote Memory
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_demote",
    "arguments": {
        "from_category": "string",
        "from_key": "string",
        "reason": "string",
        "to_category": "string",
        "to_key": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_demote", {
  "from_category": "string",
  "from_key": "string",
  "reason": "string",
  "to_category": "string",
  "to_key": "string"
});
result = await session.call_tool("perseus_vault_demote", arguments={
  "from_category": "string",
  "from_key": "string",
  "reason": "string",
  "to_category": "string",
  "to_key": "string"
})
Response
{
  "demoted": true,
  "to_id": "string"
}

Derived Beliefs Overlay

read-only
TOOLperseus_vault_beliefs

Derived-belief overlay (#717, spec: docs/specs/belief-overlay.md): compute the current effective belief for a topic from the live entity store, with fresh local corrections always outranking stale global beliefs regardless of semantic similarity (precedence tiers are absolute, never blended).

Parameters

limitinteger10argument

Maximum belief candidates to return

topicstringrequiredargument

Topic or question to resolve the current effective belief for

workspace_hashstringargument

Optional workspace scope for the local-correction tier

Returns

Returns MCP content array (text, image, or embedded resource).

Derived Beliefs Overlay
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_beliefs",
    "arguments": {
        "limit": 10,
        "topic": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_beliefs", {
  "limit": 10,
  "topic": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_beliefs", arguments={
  "limit": 10,
  "topic": "string",
  "workspace_hash": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Evidence-Backed Claim Card

read-only
TOOLperseus_vault_claim_card

Evidence-backed claim card (#852, spec: docs/specs/claim-cards.md): a deterministic, versioned projection of one entity's claim, provenance class (source_human/fact_extracted/fact_derived/inference_agent), valid vs recorded time, confidence/support, supersession/contradiction/stale state, evidence references, a sanitized agent_projection hash-bound to the selected evidence and policy, and machine-readable reason codes (serveable / archived / scope_mismatch / revoked_access + flags). Read-only view over existing entities and links — never a second source of truth.

Parameters

agent_idstringargument

Legacy caller field; public authorization uses the transport-stamped requesting_agent_id.

entity_idstringrequiredargument

ID of the entity to project as a claim card

include_agent_projectionbooleantrueargument

Include the sanitized agent_projection block

include_evidencebooleantrueargument

Include evidence references (metadata only; raw bodies never cross)

requesting_agent_idstringargument

Transport-stamped requester identity; required at runtime and never trusted from model input.

workspace_hashstringargument

Caller's workspace scope for visibility enforcement (workspace-scoped entities mismatch → withheld with scope_mismatch)

Returns

Returns MCP content array (text, image, or embedded resource).

Evidence-Backed Claim Card
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_claim_card",
    "arguments": {
        "agent_id": "string",
        "entity_id": "string",
        "include_agent_projection": true,
        "include_evidence": true,
        "requesting_agent_id": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_claim_card", {
  "agent_id": "string",
  "entity_id": "string",
  "include_agent_projection": true,
  "include_evidence": true,
  "requesting_agent_id": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_claim_card", arguments={
  "agent_id": "string",
  "entity_id": "string",
  "include_agent_projection": true,
  "include_evidence": true,
  "requesting_agent_id": "string",
  "workspace_hash": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Semantic Search Entities

read-only
TOOLperseus_vault_semantic_search

Dense-only semantic search: find entities by meaning, ranked purely by embedding similarity (no keyword fallback). On by default via the bundled in-process ONNX model — zero config, zero network. A one-tool shortcut for 'find things like this'. For fused keyword+vector results use perseus_vault_recall.

Parameters

agent_idstringargument

Agent identity filter. When set, only entities with a matching agent_id are returned.

categorystringargument

Filter by category, e.g. 'decision' or 'architecture'

limitinteger10argument

Maximum number of results to return

querystringrequiredargument

Natural-language text to semantically match against stored memories

requesting_agent_idstringargument

Transport-stamped requester identity used for private/fleet visibility enforcement.

workspace_hashstringargument

Workspace scope filter. When set, only entities with a matching workspace_hash are returned.

Returns

itemsArray<object>

Matching entities ranked by dense embedding similarity, with expanded body_json fields at top level

totalinteger

Number of results returned

Semantic Search Entities
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_semantic_search",
    "arguments": {
        "agent_id": "string",
        "category": "string",
        "limit": 10,
        "query": "string",
        "requesting_agent_id": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_semantic_search", {
  "agent_id": "string",
  "category": "string",
  "limit": 10,
  "query": "string",
  "requesting_agent_id": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_semantic_search", arguments={
  "agent_id": "string",
  "category": "string",
  "limit": 10,
  "query": "string",
  "requesting_agent_id": "string",
  "workspace_hash": "string"
})
Response
{
  "items": [
    {}
  ],
  "total": 0
}

Ask Question from Memories

read-only
TOOLperseus_vault_ask

Ask a natural language question and get a grounded answer from stored memories via RAG. Internally recalls top-k entities, assembles context, and queries the configured LLM (Ollama) for an answer with cited sources. Requires --llm-endpoint to be set. LLM request timeout defaults to 30s; set PERSEUS_VAULT_LLM_TIMEOUT_SECS for large/cold models that need longer to load (#528).

Parameters

as_of_unix_msintegerargument

#472 Temporal RAG: answer from the memory context AS IT WAS BELIEVED at this transaction-time instant (unix ms) — the retrieved bodies are reconstructed to the versions live at that instant, so a corrected-later fact does not leak into the past answer. Combine with valid_at_unix_ms for the full bi-temporal cell. Omit for the live view.

querystringrequiredargument

Natural language question to answer from stored memories

top_kinteger5argument

Number of top entities to use as context (max 20)

valid_at_unix_msintegerargument

#472 Temporal RAG: answer from the context that was TRUE IN THE WORLD at this valid-time instant (unix ms), per current (or as_of) knowledge. Omit for the live view.

verify_stale_observationsbooleantrueargument

#884: stale-observation gate. When true (default), observation sources with newer unconsolidated raw facts are verified against those facts before citation — consistent facts are cited with a 'verified against raw facts' note, contradicted observations are refused and reported in refused_sources. Set false to disable the gate.

Returns

answerstring

Grounded answer with cited sources

sourcesArray<object>

Cited source entities used in the answer

Show child attributes
categorystring
keystring
scorenumber
snippetstring
Ask Question from Memories
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_ask",
    "arguments": {
        "as_of_unix_ms": 0,
        "query": "string",
        "top_k": 5,
        "valid_at_unix_ms": 0,
        "verify_stale_observations": true
      }
  }
}
const result = await client.callTool("perseus_vault_ask", {
  "as_of_unix_ms": 0,
  "query": "string",
  "top_k": 5,
  "valid_at_unix_ms": 0,
  "verify_stale_observations": true
});
result = await session.call_tool("perseus_vault_ask", arguments={
  "as_of_unix_ms": 0,
  "query": "string",
  "top_k": 5,
  "valid_at_unix_ms": 0,
  "verify_stale_observations": true
})
Response
{
  "answer": "string",
  "sources": [
    {
      "category": "string",
      "key": "string",
      "score": 0,
      "snippet": "string"
    }
  ]
}

Get Entity by ID

read-only
TOOLperseus_vault_get_entity

Get an entity by ID with its full body_json content. Use after perseus_vault_recall with preview_cap to read the complete body of a truncated result. The drill-down footer embedded in preview-capped results references this tool with the entity ID to use.

Parameters

idstringrequiredargument

Entity ID to retrieve (from recall result id field or preview cap footer)

Returns

always_onboolean
body_jsonstring

Full entity body content

categorystring
certaintynumber
decay_scorenumber
entity_typestring
idstring
keystring
layerstring
retrieval_countinteger
statusstring
Get Entity by ID
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_get_entity",
    "arguments": {
        "id": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_get_entity", {
  "id": "string"
});
result = await session.call_tool("perseus_vault_get_entity", arguments={
  "id": "string"
})
Response
{
  "always_on": true,
  "body_json": "string",
  "category": "string",
  "certainty": 0,
  "decay_score": 0,
  "entity_type": "string",
  "id": "string",
  "key": "string",
  "layer": "string",
  "retrieval_count": 0,
  "status": "string"
}

perseus_vault_history

TOOLperseus_vault_history

List superseded (historical) versions of a fact (category + key), newest first. Each entry was the live fact for an interval before it was overwritten. The companion to perseus_vault_as_of: as_of returns the single version live at one instant; history returns the version trail. Paginated: returns the limit newest versions (default 20) starting at offset; total in the response is the FULL trail size, so total > returned means there are more pages. Returns an empty list if the fact has never been overwritten (its only version is the current live one in recall).

Parameters

categorystringrequiredargument

Entity category

keystringrequiredargument

Entity key within the category

limitinteger20argument

Maximum versions to return (newest first), 0-1000. Defaults to 20. 0 is count-only: returns no version bodies while total still reports the full trail size.

offsetinteger0argument

Number of newest versions to skip, for paging through a long trail.

Returns

Returns MCP content array (text, image, or embedded resource).

perseus_vault_history
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_history",
    "arguments": {
        "category": "string",
        "key": "string",
        "limit": 20,
        "offset": 0
      }
  }
}
const result = await client.callTool("perseus_vault_history", {
  "category": "string",
  "key": "string",
  "limit": 20,
  "offset": 0
});
result = await session.call_tool("perseus_vault_history", arguments={
  "category": "string",
  "key": "string",
  "limit": 20,
  "offset": 0
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Time-Travel Entity Lookup

read-only
TOOLperseus_vault_as_of

Transaction-time time-travel: return the version of a fact (category + key) that Perseus Vault believed at a given past instant. When a fact is overwritten, the prior version is kept in history; this returns whichever version was live at as_of_unix_ms. Use to answer 'what did we believe about X back then?' or to audit how a fact changed. For the orthogonal valid-time axis ('what was actually TRUE in the world at time T') use perseus_vault_valid_at; for both axes at once use perseus_vault_bitemporal. Returns found=false if the fact had not been recorded yet at that time. If the instant falls inside a window compacted by history retention (#398), returns an explicit marker (compacted=true, versions_compacted, digest) instead of the original — now unrecoverable — versions.

Parameters

as_of_unix_msintegerrequiredargument

Transaction-time instant (unix ms) to travel to

categorystringrequiredargument

Entity category

keystringrequiredargument

Entity key within the category

Returns

as_of_unix_msinteger
body_jsonstring

The fact's content as it was at as_of_unix_ms

categorystring
compactedboolean

Present and true when the instant falls inside a retention-compacted window: the result is a tombstone marker, not a real version (#398)

digeststring

Hash-chain digest folded over the evicted versions (#398)

entity_typestring
foundboolean

False if the fact had not been recorded by as_of_unix_ms

idstring
keystring
statusstring
versions_compactedinteger

How many original versions the compacted window rolled up (#398)

Time-Travel Entity Lookup
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_as_of",
    "arguments": {
        "as_of_unix_ms": 0,
        "category": "string",
        "key": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_as_of", {
  "as_of_unix_ms": 0,
  "category": "string",
  "key": "string"
});
result = await session.call_tool("perseus_vault_as_of", arguments={
  "as_of_unix_ms": 0,
  "category": "string",
  "key": "string"
})
Response
{
  "as_of_unix_ms": 0,
  "body_json": "string",
  "category": "string",
  "compacted": true,
  "digest": "string",
  "entity_type": "string",
  "found": true,
  "id": "string",
  "key": "string",
  "status": "string",
  "versions_compacted": 0
}

Valid-Time Lookup (What Was True)

read-only
TOOLperseus_vault_valid_at

Valid-time (application-time) lookup: return the version of a fact (category + key) that — per CURRENT knowledge — was actually true in the world at a given instant. Orthogonal to perseus_vault_as_of: as_of answers 'what did we BELIEVE at time T' (transaction time); valid_at answers 'what WAS TRUE at time T, as we understand it now'. Facts carry a valid period [valid_from, valid_to) settable on perseus_vault_remember; a later-recorded version's claim supersedes earlier claims for the instants it covers. Returns found=false if no version's valid period contains the instant.

Parameters

categorystringrequiredargument

Entity category

keystringrequiredargument

Entity key within the category

valid_at_unix_msintegerrequiredargument

World-instant (unix ms) to evaluate: which version was actually true then

Returns

body_jsonstring

The fact's content as it was true at the instant

categorystring
entity_typestring
foundboolean

False if no version's valid period contains the instant

idstring
is_live_versionboolean

True when the matched version is the current live row (not superseded)

keystring
recorded_at_unix_msinteger

Transaction time the matched version was recorded

statusstring
valid_at_unix_msinteger
valid_from_unix_msinteger

Start of the matched version's valid period

valid_to_unix_msinteger

End of the matched version's valid period (absent = still true)

Valid-Time Lookup (What Was True)
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_valid_at",
    "arguments": {
        "category": "string",
        "key": "string",
        "valid_at_unix_ms": 0
      }
  }
}
const result = await client.callTool("perseus_vault_valid_at", {
  "category": "string",
  "key": "string",
  "valid_at_unix_ms": 0
});
result = await session.call_tool("perseus_vault_valid_at", arguments={
  "category": "string",
  "key": "string",
  "valid_at_unix_ms": 0
})
Response
{
  "body_json": "string",
  "category": "string",
  "entity_type": "string",
  "found": true,
  "id": "string",
  "is_live_version": true,
  "key": "string",
  "recorded_at_unix_ms": 0,
  "status": "string",
  "valid_at_unix_ms": 0,
  "valid_from_unix_ms": 0,
  "valid_to_unix_ms": 0
}

Bi-Temporal Rectangle Query

read-only
TOOLperseus_vault_bitemporal

Full bi-temporal query (SQL:2011 SYSTEM_TIME + APPLICATION_TIME): 'as of transaction time tx_at, which version did we believe was true in the world at valid time valid_at?' Returns the exact cell of the bi-temporal rectangle — the audit-grade 'who knew what, as-of-when' question. Combines both axes: perseus_vault_as_of is this with valid_at pinned to tx_at; perseus_vault_valid_at is this with tx_at pinned to now. Retroactive and proactive updates land in the correct rectangle cell. Returns found=false if nothing recorded by tx_at was valid at valid_at.

Parameters

categorystringrequiredargument

Entity category

keystringrequiredargument

Entity key within the category

tx_at_unix_msintegerrequiredargument

Transaction-time instant (unix ms): reconstruct knowledge as of this moment

valid_at_unix_msintegerrequiredargument

Valid-time instant (unix ms): the world-moment being asked about

Returns

body_jsonstring

The version occupying that bi-temporal rectangle cell

categorystring
entity_typestring
foundboolean

False if nothing recorded by tx_at was valid at valid_at

idstring
invalidated_at_unix_msinteger

Transaction time this version was retired (absent = live)

is_live_versionboolean
keystring
recorded_at_unix_msinteger
statusstring
tx_at_unix_msinteger
valid_at_unix_msinteger
valid_from_unix_msinteger
valid_to_unix_msinteger
Bi-Temporal Rectangle Query
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_bitemporal",
    "arguments": {
        "category": "string",
        "key": "string",
        "tx_at_unix_ms": 0,
        "valid_at_unix_ms": 0
      }
  }
}
const result = await client.callTool("perseus_vault_bitemporal", {
  "category": "string",
  "key": "string",
  "tx_at_unix_ms": 0,
  "valid_at_unix_ms": 0
});
result = await session.call_tool("perseus_vault_bitemporal", arguments={
  "category": "string",
  "key": "string",
  "tx_at_unix_ms": 0,
  "valid_at_unix_ms": 0
})
Response
{
  "body_json": "string",
  "category": "string",
  "entity_type": "string",
  "found": true,
  "id": "string",
  "invalidated_at_unix_ms": 0,
  "is_live_version": true,
  "key": "string",
  "recorded_at_unix_ms": 0,
  "status": "string",
  "tx_at_unix_ms": 0,
  "valid_at_unix_ms": 0,
  "valid_from_unix_ms": 0,
  "valid_to_unix_ms": 0
}

Forget Entity (Soft-Delete)

destructive
TOOLperseus_vault_forget

Soft-delete an entity by setting archived=1. The entity is hidden from queries but recoverable. Use this to clean up stale or incorrect facts without permanent data loss.

Parameters

categorystringrequiredargument

Entity category to archive

keystringrequiredargument

Entity key to archive

reasonstringargument

Reason for archiving, logged for audit trail

Returns

categorystring

Entity category

foundboolean

Whether the entity was found and archived

keystring

Entity key

Forget Entity (Soft-Delete)
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_forget",
    "arguments": {
        "category": "string",
        "key": "string",
        "reason": ""
      }
  }
}
const result = await client.callTool("perseus_vault_forget", {
  "category": "string",
  "key": "string",
  "reason": ""
});
result = await session.call_tool("perseus_vault_forget", arguments={
  "category": "string",
  "key": "string",
  "reason": ""
})
Response
{
  "category": "string",
  "found": true,
  "key": "string"
}

Ingest External Data

destructive
TOOLperseus_vault_ingest

Sync external data connectors (GitHub issues, file watcher) into Perseus Vault. Call with no arguments to run all enabled connectors, or specify a connector name to run only that one. Use dry_run=true to preview without storing. Unchanged content from a previous successful ingest is skipped as zero-work revalidation (provenance-admission containment replay, #1050); use force_reingest=true to bypass.

Parameters

connectorstringargument

Specific connector to run (omit for all enabled)

dry_runbooleanfalseargument

Preview documents without storing them

force_reingestbooleanfalseargument

Bypass the containment replay gate and re-admit every fetched document (#1050)

Returns

containedinteger

Documents skipped as already-covered by a live entity (zero-work revalidation, #1050)

dry_runboolean

Whether this was a dry run

errorsArray<string>

Error messages from connectors that failed

ingestedinteger

Number of documents ingested (or would be ingested in dry run)

Ingest External Data
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_ingest",
    "arguments": {
        "connector": "string",
        "dry_run": false,
        "force_reingest": false
      }
  }
}
const result = await client.callTool("perseus_vault_ingest", {
  "connector": "string",
  "dry_run": false,
  "force_reingest": false
});
result = await session.call_tool("perseus_vault_ingest", arguments={
  "connector": "string",
  "dry_run": false,
  "force_reingest": false
})
Response
{
  "contained": 0,
  "dry_run": true,
  "errors": [
    "string"
  ],
  "ingested": 0
}

Ingest Document File

destructive
TOOLperseus_vault_ingest_file

Ingest a document file into memory by extracting its text LOCALLY (no cloud, no network). Plaintext/markdown/structured-text work in any build; DOCX and PDF require a binary built with --features multimodal (otherwise a clear error is returned). The extracted text is stored as a normal entity (recallable via perseus_vault_recall). category defaults to 'document', key defaults to the file name.

Parameters

categorystringargument

Entity category (default 'document')

keystringargument

Entity key (default: the file name)

pathstringrequiredargument

Path to the document file to ingest

tagsArray<string>argument

Optional tags

Returns

actionstring

created or updated

categorystring
charsinteger

Characters of text extracted

idstring

Stored entity id

keystring
Ingest Document File
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_ingest_file",
    "arguments": {
        "category": "string",
        "key": "string",
        "path": "string",
        "tags": [
          "string"
        ]
      }
  }
}
const result = await client.callTool("perseus_vault_ingest_file", {
  "category": "string",
  "key": "string",
  "path": "string",
  "tags": [
    "string"
  ]
});
result = await session.call_tool("perseus_vault_ingest_file", arguments={
  "category": "string",
  "key": "string",
  "path": "string",
  "tags": [
    "string"
  ]
})
Response
{
  "action": "string",
  "category": "string",
  "chars": 0,
  "id": "string",
  "key": "string"
}

Register Immutable Artifact

destructive
TOOLperseus_vault_artifact_register

Register an immutable artifact by reading a local file, hashing its exact bytes with full SHA-256, and storing a scope-bound metadata binding plus the preserved original bytes. Returns the compact deterministic manifest by default. This first slice accepts only uncompressed source bytes so retrieval anchors stay exact to the original artifact.

Body

application/json
agent_idstring

Owning agent id for visibility checks.

external_refsArray<object>

Optional external source anchors; pointers only, never access grants.

mime_typestring

Optional MIME type override; otherwise inferred from the file extension

originobject

Optional origin/provenance metadata using the existing memory-origin contract.

pathstringrequired

Local file path to register

representationobject

original or derived representation metadata; derived artifacts must point at a full parent SHA-256.

retention_policystring

Optional retention policy from the existing vocabulary.

visibilitystringworkspace

private | fleet | workspace | tenant | public

workspace_hashstring

Workspace scope for the metadata binding. Omit/empty = global.

Returns

artifact_actionstring
binding_actionstring
manifestobject
sha256string
Register Immutable Artifact
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_artifact_register",
    "arguments": {
        "agent_id": "",
        "external_refs": [
          {}
        ],
        "mime_type": "string",
        "origin": {},
        "path": "string",
        "representation": {},
        "retention_policy": "string",
        "visibility": "workspace",
        "workspace_hash": ""
      }
  }
}
const result = await client.callTool("perseus_vault_artifact_register", {
  "agent_id": "",
  "external_refs": [
    {}
  ],
  "mime_type": "string",
  "origin": {},
  "path": "string",
  "representation": {},
  "retention_policy": "string",
  "visibility": "workspace",
  "workspace_hash": ""
});
result = await session.call_tool("perseus_vault_artifact_register", arguments={
  "agent_id": "",
  "external_refs": [
    {}
  ],
  "mime_type": "string",
  "origin": {},
  "path": "string",
  "representation": {},
  "retention_policy": "string",
  "visibility": "workspace",
  "workspace_hash": ""
})
Request Body
{
  "agent_id": "",
  "external_refs": [
    {}
  ],
  "mime_type": "string",
  "origin": {},
  "path": "string",
  "representation": {},
  "retention_policy": "string",
  "visibility": "workspace",
  "workspace_hash": ""
}
Response
{
  "artifact_action": "string",
  "binding_action": "string",
  "manifest": {},
  "sha256": "string"
}

Register Governed Learned Artifact

TOOLperseus_vault_learned_artifact_register

#876 governed distillation: register a learned-memory artifact (trained weights / distilled cartridge) bound to its source entities with hash-only evidence, gated fail-closed on a COMPLETED 'learned_memory' action receipt (no receipt, no registration). Every source (category, key) in the workspace is snapshotted (entity id + normalized body digest + recorded_at) into learned_artifact_sources; physically erasing or purging a source revokes the binding (serve paths refuse revoked artifacts), superseding a source flags it stale (retraining trigger). Returns the artifact sha256, source-bindings count, and receipt-replay evidence.

Body

application/json
action_idstringrequired

Action id of a COMPLETED 'learned_memory' action receipt (intent -> lease -> complete); the gate refuses registration without it.

agent_idstring

Owning agent id for visibility checks.

derivation_versionstring

Optional distillation pipeline version tag.

external_refsArray<object>

Optional external source anchors; pointers only, never access grants.

mime_typestring

Optional MIME type override; otherwise inferred from the file extension

pathstringrequired

Local file path to register (trained artifact / cartridge)

retention_policystring

Optional retention policy from the existing vocabulary.

source_entitiesArray<Array<string>>required

(category, key) pairs the artifact was distilled from; snapshotted hash-only at registration.

visibilitystringworkspace

private | fleet | workspace | tenant | public

workspace_hashstring

Workspace scope for the metadata binding. Omit/empty = global.

Returns

action_idstring
artifact_actionstring
binding_actionstring
evidenceobject
manifestobject
sha256string
source_bindings_countinteger
Register Governed Learned Artifact
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_learned_artifact_register",
    "arguments": {
        "action_id": "string",
        "agent_id": "",
        "derivation_version": "string",
        "external_refs": [
          {}
        ],
        "mime_type": "string",
        "path": "string",
        "retention_policy": "string",
        "source_entities": [
          [
            "string"
          ]
        ],
        "visibility": "workspace",
        "workspace_hash": ""
      }
  }
}
const result = await client.callTool("perseus_vault_learned_artifact_register", {
  "action_id": "string",
  "agent_id": "",
  "derivation_version": "string",
  "external_refs": [
    {}
  ],
  "mime_type": "string",
  "path": "string",
  "retention_policy": "string",
  "source_entities": [
    [
      "string"
    ]
  ],
  "visibility": "workspace",
  "workspace_hash": ""
});
result = await session.call_tool("perseus_vault_learned_artifact_register", arguments={
  "action_id": "string",
  "agent_id": "",
  "derivation_version": "string",
  "external_refs": [
    {}
  ],
  "mime_type": "string",
  "path": "string",
  "retention_policy": "string",
  "source_entities": [
    [
      "string"
    ]
  ],
  "visibility": "workspace",
  "workspace_hash": ""
})
Request Body
{
  "action_id": "string",
  "agent_id": "",
  "derivation_version": "string",
  "external_refs": [
    {}
  ],
  "mime_type": "string",
  "path": "string",
  "retention_policy": "string",
  "source_entities": [
    [
      "string"
    ]
  ],
  "visibility": "workspace",
  "workspace_hash": ""
}
Response
{
  "action_id": "string",
  "artifact_action": "string",
  "binding_action": "string",
  "evidence": {},
  "manifest": {},
  "sha256": "string",
  "source_bindings_count": 0
}

Bind Hermes Profile to Workspace

TOOLperseus_vault_workspace_bind

#879: bind a Hermes profile to a Vault workspace (one profile <-> one workspace; re-binding switches workspace and resets lifecycle state). access_mode read_write | read_only; read_only bindings deny mutations at the tool boundary. Journaled (workspace_bound / workspace_rebound).

Parameters

access_modestringread_writeread_onlyread_writeargument

read_write or read_only

metadataobjectargument

Optional metadata (host, hermes version, actor, ...)

profile_namestringrequiredargument

Hermes profile name (must match the MCP clientInfo.name used at handshake)

workspace_hashstringrequiredargument

Workspace to bind the profile to

Returns

object
Bind Hermes Profile to Workspace
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_workspace_bind",
    "arguments": {
        "access_mode": "read_write",
        "metadata": {},
        "profile_name": "string",
        "workspace_hash": ""
      }
  }
}
const result = await client.callTool("perseus_vault_workspace_bind", {
  "access_mode": "read_write",
  "metadata": {},
  "profile_name": "string",
  "workspace_hash": ""
});
result = await session.call_tool("perseus_vault_workspace_bind", arguments={
  "access_mode": "read_write",
  "metadata": {},
  "profile_name": "string",
  "workspace_hash": ""
})
Response
{}

Unbind Hermes Profile

TOOLperseus_vault_workspace_unbind

#879: unbind a Hermes profile from its workspace (lifecycle: active/quarantined -> unbound; row retained for audit). Journaled (workspace_unbound).

Parameters

profile_namestringrequiredargument

Hermes profile name to unbind

reasonstringargument

Unbind reason (journaled)

Returns

object
Unbind Hermes Profile
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_workspace_unbind",
    "arguments": {
        "profile_name": "string",
        "reason": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_workspace_unbind", {
  "profile_name": "string",
  "reason": "string"
});
result = await session.call_tool("perseus_vault_workspace_unbind", arguments={
  "profile_name": "string",
  "reason": "string"
})
Response
{}

Quarantine or Reactivate Profile Binding

TOOLperseus_vault_workspace_quarantine

#879: operator lifecycle control — quarantine an active binding (stops all access until reactivated) or reactivate a quarantined/unbound binding. Journaled (workspace_quarantined / workspace_reactivated).

Parameters

actionstringquarantinereactivatequarantineargument

quarantine or reactivate

profile_namestringrequiredargument

Hermes profile name

reasonstringargument

Reason (required for quarantine, journaled)

Returns

object
Quarantine or Reactivate Profile Binding
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_workspace_quarantine",
    "arguments": {
        "action": "quarantine",
        "profile_name": "string",
        "reason": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_workspace_quarantine", {
  "action": "quarantine",
  "profile_name": "string",
  "reason": "string"
});
result = await session.call_tool("perseus_vault_workspace_quarantine", arguments={
  "action": "quarantine",
  "profile_name": "string",
  "reason": "string"
})
Response
{}

Workspace Binding Status

TOOLperseus_vault_workspace_status

#879: diagnostics — all profile <-> workspace bindings with lifecycle state, access mode, heartbeat, and staleness signal; distinguishes live, stale, quarantined, and unbound bindings.

Returns

bindingsArray<object>
countinteger
Workspace Binding Status
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_workspace_status",
    "arguments": {}
  }
}
const result = await client.callTool("perseus_vault_workspace_status", {});
result = await session.call_tool("perseus_vault_workspace_status", arguments={})
Response
{
  "bindings": [
    {}
  ],
  "count": 0
}

Serve Artifact Manifest

TOOLperseus_vault_artifact_manifest

Serve the compact deterministic manifest for one artifact identity after scope + visibility filtering. When workspace_hash is omitted, only global bindings are considered — an artifact hash alone is a pointer, not an access grant.

Parameters

requesting_agent_idstringargument

Optional requesting agent id for visibility filtering.

sha256stringrequiredargument

Full 64-hex SHA-256 content identity

workspace_hashstringargument

Exact workspace scope to read; omit for global-only.

Returns

available_retrievalsobject
bindingsArray<object>
byte_lengthinteger
sha256string
significant_signalsArray<string>
structureobject
visible_binding_countinteger
Serve Artifact Manifest
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_artifact_manifest",
    "arguments": {
        "requesting_agent_id": "string",
        "sha256": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_artifact_manifest", {
  "requesting_agent_id": "string",
  "sha256": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_artifact_manifest", arguments={
  "requesting_agent_id": "string",
  "sha256": "string",
  "workspace_hash": "string"
})
Response
{
  "available_retrievals": {},
  "bindings": [
    {}
  ],
  "byte_length": 0,
  "sha256": "string",
  "significant_signals": [
    "string"
  ],
  "structure": {},
  "visible_binding_count": 0
}

Retrieve Exact Artifact Excerpt

TOOLperseus_vault_artifact_excerpt

Retrieve an exact bounded excerpt from the preserved original artifact bytes by either a half-open byte range [start,end) or an inclusive 1-indexed line range. Returns exact source anchors plus base64 bytes, and UTF-8 text when the slice decodes cleanly.

Parameters

byte_endintegerargument

Byte-range end offset (exclusive)

byte_startintegerargument

Byte-range start offset (inclusive)

line_endintegerargument

Line-range end (1-indexed, inclusive)

line_startintegerargument

Line-range start (1-indexed, inclusive)

requesting_agent_idstringargument

Optional requesting agent id for visibility filtering.

sha256stringrequiredargument

Full 64-hex SHA-256 content identity

workspace_hashstringargument

Exact workspace scope to read; omit for global-only.

Returns

anchorsArray<object>
content_b64string
content_utf8string | null
rangeobject
sha256string
why_servedobject
Retrieve Exact Artifact Excerpt
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_artifact_excerpt",
    "arguments": {
        "byte_end": 0,
        "byte_start": 0,
        "line_end": 0,
        "line_start": 0,
        "requesting_agent_id": "string",
        "sha256": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_artifact_excerpt", {
  "byte_end": 0,
  "byte_start": 0,
  "line_end": 0,
  "line_start": 0,
  "requesting_agent_id": "string",
  "sha256": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_artifact_excerpt", arguments={
  "byte_end": 0,
  "byte_start": 0,
  "line_end": 0,
  "line_start": 0,
  "requesting_agent_id": "string",
  "sha256": "string",
  "workspace_hash": "string"
})
Response
{
  "anchors": [
    {}
  ],
  "content_b64": "string",
  "content_utf8": "string",
  "range": {},
  "sha256": "string",
  "why_served": {}
}

Build Deterministic Evidence-Preserving Log Digest

TOOLperseus_vault_artifact_log_digest

Build a deterministic, evidence-preserving navigation digest over a visible UTF-8 log artifact. Repeated non-protected templates are collapsed with exact counts and first/last source anchors. Lines containing error, warn, exception, fatal, panic, denied, refused, timeout, assertion, or traceback remain verbatim. This is never an LLM summary or replacement for original bytes.

Parameters

requesting_agent_idstringargument

Optional requesting agent id for visibility filtering.

sha256stringrequiredargument

Full 64-hex SHA-256 content identity

workspace_hashstringargument

Exact workspace scope to read; omit for global-only.

Returns

config_versionstring
formatstring
input_line_countinteger
omitted_line_countinteger
protected_line_countinteger
protected_linesArray<array>
retrievalstring
sectionsArray<object>
source_sha256string
Build Deterministic Evidence-Preserving Log Digest
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_artifact_log_digest",
    "arguments": {
        "requesting_agent_id": "string",
        "sha256": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_artifact_log_digest", {
  "requesting_agent_id": "string",
  "sha256": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_artifact_log_digest", arguments={
  "requesting_agent_id": "string",
  "sha256": "string",
  "workspace_hash": "string"
})
Response
{
  "config_version": "string",
  "format": "string",
  "input_line_count": 0,
  "omitted_line_count": 0,
  "protected_line_count": 0,
  "protected_lines": [
    []
  ],
  "retrieval": "string",
  "sections": [
    {}
  ],
  "source_sha256": "string"
}

Verify Candidate Against Original Artifact Bytes

TOOLperseus_vault_artifact_verify_value

Verify that a candidate value occurs verbatim in the preserved original artifact bytes, with bounded exact-match search only (no regex). Returns exact source anchors for each match found.

Parameters

candidatestringrequiredargument

Candidate value to verify: UTF-8 text by default, or base64 when encoding='base64'.

encodingstringutf8argument

utf8 | base64

max_matchesinteger5argument

Maximum exact-match anchors to return (bounded).

requesting_agent_idstringargument

Optional requesting agent id for visibility filtering.

sha256stringrequiredargument

Full 64-hex SHA-256 content identity

workspace_hashstringargument

Exact workspace scope to read; omit for global-only.

Returns

candidate_byte_lengthinteger
candidate_encodingstring
match_countinteger
matchesArray<object>
sha256string
truncatedboolean
why_servedobject
Verify Candidate Against Original Artifact Bytes
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_artifact_verify_value",
    "arguments": {
        "candidate": "string",
        "encoding": "utf8",
        "max_matches": 5,
        "requesting_agent_id": "string",
        "sha256": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_artifact_verify_value", {
  "candidate": "string",
  "encoding": "utf8",
  "max_matches": 5,
  "requesting_agent_id": "string",
  "sha256": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_artifact_verify_value", arguments={
  "candidate": "string",
  "encoding": "utf8",
  "max_matches": 5,
  "requesting_agent_id": "string",
  "sha256": "string",
  "workspace_hash": "string"
})
Response
{
  "candidate_byte_length": 0,
  "candidate_encoding": "string",
  "match_count": 0,
  "matches": [
    {}
  ],
  "sha256": "string",
  "truncated": true,
  "why_served": {}
}

Generate Entity Embeddings

destructive
TOOLperseus_vault_embed

Generate and store dense vector embeddings for entities via Ollama /api/embed. Supports single entity (category+key) or batch mode (batch_category). Requires --llm-endpoint to be set. #885: also the operator surface for optional quantized embedding storage — quant_mode converts ALL stored float32 embeddings to int8 or bit (MIB-style sign-bit vectors scored by Hamming) in one transaction with a pre-quantization snapshot; restore_quantized_backup rolls back losslessly from that snapshot; drop_quantized_backup removes it after verification.

Parameters

batch_categorystringargument

Embed all entities in this category lacking embeddings

batch_limitinteger100argument

Max entities in batch mode

categorystringargument

Entity category for single mode

drop_quantized_backupbooleanfalseargument

Drop the pre-quantization snapshot after verifying the quantized store (irreversible; rollback then requires re-embed)

keystringargument

Entity key for single mode

quant_modestringint8bitargument

Store-wide reindex: convert ALL stored embeddings from float32 to int8 or bit (one transaction; pre-quantization float32 snapshot created once). Refused when already quantized — restore first.

restore_quantized_backupbooleanfalseargument

Roll back the embedding column to float32 from the pre-quantization snapshot (lossless for rows that existed at quantization time)

textstringargument

Text to embed (omit to use entity body_json)

Returns

dimensionsinteger

Vector dimensions

embeddedinteger

Number of entities embedded

Generate Entity Embeddings
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_embed",
    "arguments": {
        "batch_category": "string",
        "batch_limit": 100,
        "category": "string",
        "drop_quantized_backup": false,
        "key": "string",
        "quant_mode": "int8",
        "restore_quantized_backup": false,
        "text": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_embed", {
  "batch_category": "string",
  "batch_limit": 100,
  "category": "string",
  "drop_quantized_backup": false,
  "key": "string",
  "quant_mode": "int8",
  "restore_quantized_backup": false,
  "text": "string"
});
result = await session.call_tool("perseus_vault_embed", arguments={
  "batch_category": "string",
  "batch_limit": 100,
  "category": "string",
  "drop_quantized_backup": false,
  "key": "string",
  "quant_mode": "int8",
  "restore_quantized_backup": false,
  "text": "string"
})
Response
{
  "dimensions": 0,
  "embedded": 0
}

Prune Stale Entities

destructive
TOOLperseus_vault_prune

Bulk archive entities by category, decay threshold, or age. Use dry_run=true to preview without archiving. Useful for cleaning stale or low-quality memories. With scope='history' (#398) it instead evicts old superseded versions from entity_history under the given (or env-configured PERSEUS_VAULT_HISTORY_*) bounds, rolling each evicted run into a compaction tombstone; dry_run reports the rows and bytes that would be evicted.

Parameters

categorystringargument

Archive entities in this category

dry_runbooleanfalseargument

Preview without archiving/evicting

limitinteger100argument

Max entities to prune (0 = unlimited)

max_age_daysintegerargument

scope='history': evict versions invalidated more than this many days ago (overrides PERSEUS_VAULT_HISTORY_MAX_AGE_DAYS)

max_bytesintegerargument

scope='history': global stored-history byte budget, globally-oldest evicted first (overrides PERSEUS_VAULT_HISTORY_MAX_BYTES)

max_versions_per_keyintegerargument

scope='history': keep at most this many stored versions per key, oldest evicted first (overrides PERSEUS_VAULT_HISTORY_MAX_VERSIONS_PER_KEY)

min_decaynumberargument

Archive entities with decay_score below this threshold

older_than_daysintegerargument

Archive entities older than this many days

scopestringentitieshistoryargument

'history' prunes superseded versions from entity_history under retention bounds instead of archiving live entities (#398)

Returns

archivedinteger
dry_runboolean
examinedinteger
reasonstring
Prune Stale Entities
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_prune",
    "arguments": {
        "category": "string",
        "dry_run": false,
        "limit": 100,
        "max_age_days": 0,
        "max_bytes": 0,
        "max_versions_per_key": 0,
        "min_decay": 0,
        "older_than_days": 0,
        "scope": "entities"
      }
  }
}
const result = await client.callTool("perseus_vault_prune", {
  "category": "string",
  "dry_run": false,
  "limit": 100,
  "max_age_days": 0,
  "max_bytes": 0,
  "max_versions_per_key": 0,
  "min_decay": 0,
  "older_than_days": 0,
  "scope": "entities"
});
result = await session.call_tool("perseus_vault_prune", arguments={
  "category": "string",
  "dry_run": false,
  "limit": 100,
  "max_age_days": 0,
  "max_bytes": 0,
  "max_versions_per_key": 0,
  "min_decay": 0,
  "older_than_days": 0,
  "scope": "entities"
})
Response
{
  "archived": 0,
  "dry_run": true,
  "examined": 0,
  "reason": "string"
}

Append Journal Entry

destructive
TOOLperseus_vault_journal

Append a structured decision/observation log entry. Uses evaluated/acted/forward pattern: what was considered, what was done, and what happens next. Essential for audit trails and timeline reconstruction. Public admission_source events additionally require an initialized clientInfo.name and an enforce-mode memory.admission.source authority for the exact workspace; caller-supplied identities are never authoritative.

Parameters

actedobjectargument

What action was taken and why

agent_idstringargument

Agent identity (v1.2.0). Records which agent created this journal event.

categorystringargument

Related entity category for linking

entity_idstringargument

Related entity ID for linking

evaluatedobjectargument

What was evaluated: options considered, context, constraints

event_typestringdecisionargument

Event type: 'decision', 'observation', 'action', 'error'

forwardobjectargument

What the plan is going forward

keystringargument

Related entity key for linking

requesting_agent_idstringargument

Transport-stamped caller identity; required for admission_source events.

source_attestationstringargument

HMAC-SHA256 attestation over the canonical admission-source fields; required for public admission_source events and never stored.

workspace_hashstringargument

Explicit workspace attribution for the journal event; empty string denotes the global partition.

Returns

created_at_unix_msinteger

Creation timestamp in unix milliseconds

event_typestring

Event type recorded

idstring

Journal event ID

Append Journal Entry
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_journal",
    "arguments": {
        "acted": {},
        "agent_id": "",
        "category": "string",
        "entity_id": "string",
        "evaluated": {},
        "event_type": "decision",
        "forward": {},
        "key": "string",
        "requesting_agent_id": "string",
        "source_attestation": "string",
        "workspace_hash": ""
      }
  }
}
const result = await client.callTool("perseus_vault_journal", {
  "acted": {},
  "agent_id": "",
  "category": "string",
  "entity_id": "string",
  "evaluated": {},
  "event_type": "decision",
  "forward": {},
  "key": "string",
  "requesting_agent_id": "string",
  "source_attestation": "string",
  "workspace_hash": ""
});
result = await session.call_tool("perseus_vault_journal", arguments={
  "acted": {},
  "agent_id": "",
  "category": "string",
  "entity_id": "string",
  "evaluated": {},
  "event_type": "decision",
  "forward": {},
  "key": "string",
  "requesting_agent_id": "string",
  "source_attestation": "string",
  "workspace_hash": ""
})
Response
{
  "created_at_unix_ms": 0,
  "event_type": "string",
  "id": "string"
}

Check Failure Pattern (Deja-Vu Guard)

read-only
TOOLperseus_vault_check_failure_pattern

Deja-vu guard (#521): call BEFORE retrying a failed command or committing to an approach. Checks the action against workspace-scoped prior failures in both the journal (error events and failure-marked acted/forward payloads) and the entity store (failure/pitfall/root-cause memories), ranked by similarity, recency, and trust. Returns matching prior failures with the recorded cause and resolution, a deja_vu flag, and a one-line warning when the action was already tried and failed. Read-only: never bumps retrieval counts or decay. Record failures via perseus_vault_journal (event_type 'error') or perseus_vault_remember so the guard can find them.

Parameters

actionstringrequiredargument

The command line or approach description you are about to (re)try, e.g. 'cargo build --no-default-features' or 'parse the changelog with a regex'

limitinteger5argument

Maximum number of matches to return (1-50)

workspace_hashstringrequiredargument

Required workspace scope. Use an empty string only for the explicit global partition; other workspaces are never searched.

Returns

deja_vuboolean

True when at least one prior recorded failure matches the action

matchesArray<object>

Prior failures matching the action, best first. Each includes source, ref, workspace_hash, when (unix ms), what_failed, cause, resolution, and score.

Show child attributes
workspace_hashstring

Stored workspace scope of the matched failure; empty means the global partition.

messagestring

Unambiguous empty state ('no prior failures recorded matching this action') when nothing matches

warningstring

One-line agent-actionable deja-vu warning (present only when matches exist)

Check Failure Pattern (Deja-Vu Guard)
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_check_failure_pattern",
    "arguments": {
        "action": "string",
        "limit": 5,
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_check_failure_pattern", {
  "action": "string",
  "limit": 5,
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_check_failure_pattern", arguments={
  "action": "string",
  "limit": 5,
  "workspace_hash": "string"
})
Response
{
  "deja_vu": true,
  "matches": [
    {
      "workspace_hash": "string"
    }
  ],
  "message": "string",
  "warning": "string"
}

Query Journal Timeline

read-only
TOOLperseus_vault_timeline

Query workspace-scoped journal events by time range with optional filters for event type, category, or entity. Use this to reconstruct the decision history and understand what happened when.

Parameters

categorystringargument

Filter by related entity category

entity_idstringargument

Filter by related entity ID

event_typestringargument

Filter by event type: 'decision', 'observation', 'action', 'error'

from_msintegerargument

Start time boundary in unix milliseconds

limitinteger50argument

Maximum number of events to return (max 1000)

offsetinteger0argument

Number of events to skip for pagination

to_msintegerargument

End time boundary in unix milliseconds

workspace_hashstringrequiredargument

Required workspace scope. Use an empty string only for the explicit global partition.

Returns

itemsArray<object>

Journal events matching the query

Show child attributes
event_typestring
idstring
workspace_hashstring

Stored workspace attribution; empty string denotes the global partition.

totalinteger

Number of events returned

Query Journal Timeline
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_timeline",
    "arguments": {
        "category": "string",
        "entity_id": "string",
        "event_type": "string",
        "from_ms": 0,
        "limit": 50,
        "offset": 0,
        "to_ms": 0,
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_timeline", {
  "category": "string",
  "entity_id": "string",
  "event_type": "string",
  "from_ms": 0,
  "limit": 50,
  "offset": 0,
  "to_ms": 0,
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_timeline", arguments={
  "category": "string",
  "entity_id": "string",
  "event_type": "string",
  "from_ms": 0,
  "limit": 50,
  "offset": 0,
  "to_ms": 0,
  "workspace_hash": "string"
})
Response
{
  "items": [
    {
      "event_type": "string",
      "id": "string",
      "workspace_hash": "string"
    }
  ],
  "total": 0
}

Set State Entry

destructive
TOOLperseus_vault_state_set

Set a key-value state entry with optional TTL for auto-expiration. Use this for session state, temporary flags, or configuration values that should expire after a set time.

Parameters

keystringrequiredargument

State key — unique identifier for this state entry

ttl_secondsintegerargument

Time-to-live in seconds. Entry auto-expires and returns null after this duration. Omit for permanent state.

value_jsonstringrequiredargument

JSON value to store

Returns

expires_at_unix_msinteger

Expiration timestamp in unix milliseconds, if TTL was set

keystring

State key set

ttl_secondsinteger

TTL that was set, if any

Set State Entry
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_state_set",
    "arguments": {
        "key": "string",
        "ttl_seconds": 0,
        "value_json": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_state_set", {
  "key": "string",
  "ttl_seconds": 0,
  "value_json": "string"
});
result = await session.call_tool("perseus_vault_state_set", arguments={
  "key": "string",
  "ttl_seconds": 0,
  "value_json": "string"
})
Response
{
  "expires_at_unix_ms": 0,
  "key": "string",
  "ttl_seconds": 0
}

Get State Entry

read-only
TOOLperseus_vault_state_get

Get a state value by key. Returns null if the key has expired or doesn't exist. Use this instead of perseus_vault_recall for transient session state that doesn't need FTS5 search.

Parameters

keystringrequiredargument

State key to retrieve

Returns

created_at_unix_msinteger

Creation timestamp

expires_at_unix_msinteger

Expiration timestamp if TTL was set

foundboolean

Whether the key exists and hasn't expired

keystring

State key requested

valuestring

JSON value if found

Get State Entry
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_state_get",
    "arguments": {
        "key": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_state_get", {
  "key": "string"
});
result = await session.call_tool("perseus_vault_state_get", arguments={
  "key": "string"
})
Response
{
  "created_at_unix_ms": 0,
  "expires_at_unix_ms": 0,
  "found": true,
  "key": "string",
  "value": "string"
}

Delete State Entry

destructive
TOOLperseus_vault_state_delete

Delete a state entry by key. Permanent removal — unlike perseus_vault_forget which is a soft-delete. Use this to clean up expired or unused state entries.

Parameters

keystringrequiredargument

State key to permanently delete

Returns

foundboolean

Whether the key existed and was deleted

keystring

Key that was deleted

Delete State Entry
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_state_delete",
    "arguments": {
        "key": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_state_delete", {
  "key": "string"
});
result = await session.call_tool("perseus_vault_state_delete", arguments={
  "key": "string"
})
Response
{
  "found": true,
  "key": "string"
}

List State Entries

read-only
TOOLperseus_vault_state_list

List all state keys, optionally filtered by a key prefix. Use this to discover what state entries exist without knowing exact keys ahead of time.

Parameters

prefixstringargument

Only return keys that start with this prefix

Returns

keysArray<string>

Matching state keys

totalinteger

Number of keys returned

List State Entries
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_state_list",
    "arguments": {
        "prefix": ""
      }
  }
}
const result = await client.callTool("perseus_vault_state_list", {
  "prefix": ""
});
result = await session.call_tool("perseus_vault_state_list", arguments={
  "prefix": ""
})
Response
{
  "keys": [
    "string"
  ],
  "total": 0
}

Check Health

read-only
TOOLperseus_vault_health

Cheap readiness probe for the vault server and its SQLite database. Returns healthy/unhealthy plus a readiness snapshot: ready (DB answers AND at least one active memory), active_memories, embedded_memories, semantic_recall (available|no_coverage|disabled), db_path, and warnings[] with likely causes. Call this before a recall-heavy workflow, or when recall unexpectedly returns empty, to tell an empty/degraded store apart from a broken MCP child. Use perseus_vault_stats for detailed statistics.

Returns

active_memoriesinteger

Count of non-archived memories (the set recall reads)

binary_pathstring

Absolute path of the running binary (empty when undeterminable)

binary_staleboolean

True when the running binary was replaced on disk since this process started (#858): results come from a stale image — call perseus_vault_handoff_restart or restart the session

db_pathstring

Absolute path of the SQLite file this server is bound to (#671)

embedded_memoriesinteger

Count of active memories carrying a dense embedding

pidinteger

PID of the running server process

readyboolean

True when the DB responds AND the store has at least one active memory — i.e. recall can return non-empty results

semantic_recallstringavailableno_coveragedisabled

Dense/hybrid posture: available (backend on, coverage present), no_coverage (backend on, nothing embedded), or disabled (keyword-only build/config)

statusstringhealthyunhealthy

Server health status (healthy iff the DB responds)

warningsArray<string>

Likely-cause messages for degraded/empty states; empty when nominal

Check Health
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_health",
    "arguments": {}
  }
}
const result = await client.callTool("perseus_vault_health", {});
result = await session.call_tool("perseus_vault_health", arguments={})
Response
{
  "active_memories": 0,
  "binary_path": "string",
  "binary_stale": true,
  "db_path": "string",
  "embedded_memories": 0,
  "pid": 0,
  "ready": true,
  "semantic_recall": "available",
  "status": "healthy",
  "warnings": [
    "string"
  ]
}

Deployment Profile

read-only
TOOLperseus_vault_deployment_profile

Resolved runtime deployment profile (#870): one machine-readable answer to 'what is this vault actually connected to?'. Reports the profile class (offline | local_only | local_with_approved_network | external_actions_enabled), model backend (bundled/ollama/provider/none), embedding backend (kind + available + degraded — a missing/unavailable local backend is reported as degraded, never silently reclassified as empty success), network listeners and non-loopback egress hosts (hosts only — sanitized, no URLs/keys/raw bodies), connectors, cloud-provider use, external-mutation posture, encryption at rest (aes_256_gcm|plaintext + storage-state probe) and in transit, and raw-retention policy. Describes ACTUAL runtime state: offline mode zeroes web/LLM/embedding/connectors at startup, and the profile reflects the effective flags. Read-only.

Returns

cloud_provider_usestring

'none' or comma-joined non-loopback hosts

connectorsarray

name/remote/remote_host

embedding_backendobject

kind/available/degraded/semantic_recall

encryptionobject

at_rest/storage_state/in_transit

external_mutationsstringdisabledenabled
model_backendobject

kind/model/available/degraded

networkobject

listeners/egress_hosts/loopback_only

profilestringofflinelocal_onlylocal_with_approved_networkexternal_actions_enabled

Derived deployment class from runtime state

raw_retentionobject

memory_bodies/raw_logs

Deployment Profile
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_deployment_profile",
    "arguments": {}
  }
}
const result = await client.callTool("perseus_vault_deployment_profile", {});
result = await session.call_tool("perseus_vault_deployment_profile", arguments={})
Response
{
  "cloud_provider_use": "string",
  "connectors": [],
  "embedding_backend": {},
  "encryption": {},
  "external_mutations": "disabled",
  "model_backend": {},
  "network": {},
  "profile": "offline",
  "raw_retention": {}
}

Config Self-Report

read-only
TOOLperseus_vault_config_report

Per-stage provider/config self-report with a requested-vs-resolved diff (#1010). One machine-readable answer to 'did every pipeline stage actually resolve the configuration I asked for?' Reports six stages — embedding_backend, model_backend, quantization, db_path, encryption, network — each with requested (the operator-facing knob as literally given, sanitized: hosts/kind labels only, never secrets), resolved (the runtime's actual resolution), drifted (true when they differ in a way the operator did not ask for), and note (remediation). Drift is a loud condition: a configured-but-unavailable embedding backend is reported as drifted, never silently reclassified as empty success; a store whose embedding format was declared by a previous process drifts against this process's default. Read-only.

Returns

drifted_stagesarray

Stage ids with drifted=true (empty = everything resolved as requested)

generated_at_unix_msnumber

Report timestamp

stagesarray

One entry per stage: stage/requested/resolved/drifted/note

Config Self-Report
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_config_report",
    "arguments": {}
  }
}
const result = await client.callTool("perseus_vault_config_report", {});
result = await session.call_tool("perseus_vault_config_report", arguments={})
Response
{
  "drifted_stages": [],
  "generated_at_unix_ms": 0,
  "stages": []
}

Typed Memory Policies

read-only
TOOLperseus_vault_type_policies

Typed memory-class policy table (#1000, CogniCore borrow): the 8 MemoryTypes (semantic, episodic, procedural, preference, constraint, failure, reflection, knowledge) with per-type decay_multiplier (scales the per-category half-life at decay tick) and retrieval_weight (multiplies the final fused recall score), plus each policy's rationale. Legacy rows (memory_type '') resolve to the SEMANTIC policy — the byte-compatible baseline. Unknown memory_type values on remember() are hard write errors (fail-closed, never a silent fallback). Read-only.

Returns

legacy_rowsstring

Legacy-row resolution semantics

memory_typesarray

One entry per MemoryType: memory_type/decay_multiplier/retrieval_weight/rationale

write_validationstring

Write-time validation semantics

Typed Memory Policies
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_type_policies",
    "arguments": {}
  }
}
const result = await client.callTool("perseus_vault_type_policies", {});
result = await session.call_tool("perseus_vault_type_policies", arguments={})
Response
{
  "legacy_rows": "string",
  "memory_types": [],
  "write_validation": "string"
}

perseus_vault_handoff_restart

TOOLperseus_vault_handoff_restart

Live-update / reconnect for long-lived stdio sessions (#858). When the perseus-vault binary was rebuilt or replaced on disk mid-session, the running process image is stale: every other tool refuses loudly (isError) until the session is restarted — or this tool hot-swaps the process on the SAME stdio connection. States: binary unchanged -> no_handoff_needed (identity report); stale + dry_run -> dry_run (what would happen); stale without confirm -> confirm_required; stale + confirm:true -> the replacement binary is spawned on this session's stdio and the old process exits immediately after this response — the MCP session continues uninterrupted in the new process image. Do not pipeline requests during the handoff.

Parameters

confirmbooleanargument

Required to actually perform the hot-swap when the binary is stale (default false)

dry_runbooleanargument

Report what would happen without performing the handoff (default false)

Returns

Returns MCP content array (text, image, or embedded resource).

perseus_vault_handoff_restart
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_handoff_restart",
    "arguments": {
        "confirm": true,
        "dry_run": true
      }
  }
}
const result = await client.callTool("perseus_vault_handoff_restart", {
  "confirm": true,
  "dry_run": true
});
result = await session.call_tool("perseus_vault_handoff_restart", arguments={
  "confirm": true,
  "dry_run": true
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

perseus_vault_quality_telemetry

TOOLperseus_vault_quality_telemetry

Machine-readable memory-quality telemetry: contradiction rate, supersession lag, class/layer distribution, and promotion-flow proxy.

Parameters

categorystringargument

Category for contradiction scan (default general).

Returns

Returns MCP content array (text, image, or embedded resource).

perseus_vault_quality_telemetry
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_quality_telemetry",
    "arguments": {
        "category": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_quality_telemetry", {
  "category": "string"
});
result = await session.call_tool("perseus_vault_quality_telemetry", arguments={
  "category": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

perseus_vault_retrieval_telemetry

TOOLperseus_vault_retrieval_telemetry

Read-only retrieval telemetry: concentration (top slot/token shares, Herfindahl), repeated-serving rate over a turn/second window, diversity (sources, source classes, Simpson), cross-arm contamination (per-arm audits, delivered-set validation, optional arm-level probe), low-trust query-class fan-out, and diversity/cooldown displacement. Reports include denominators, scope, retrieval profile, source class, and the versioned artifact hash; empty/degraded/unavailable states are separated from zero concentration.

Parameters

probe_modestringargument

Probe mode: lexical|dense|hybrid|fused|graph|proactive (default lexical).

probe_querystringargument

Optional contamination probe: run arm-level SQL deltas for this query and report blocked re-entry per arm.

profilestringargument

Scope: only events recorded under this profile.

window_secsintegerargument

Window in seconds (default 86400).

window_turnsintegerargument

Window in serving batches (distinct recalls). Default: none (window_secs wins).

workspace_hashstringargument

Scope: only events from this workspace.

Returns

Returns MCP content array (text, image, or embedded resource).

perseus_vault_retrieval_telemetry
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_retrieval_telemetry",
    "arguments": {
        "probe_mode": "string",
        "probe_query": "string",
        "profile": "string",
        "window_secs": 0,
        "window_turns": 0,
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_retrieval_telemetry", {
  "probe_mode": "string",
  "probe_query": "string",
  "profile": "string",
  "window_secs": 0,
  "window_turns": 0,
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_retrieval_telemetry", arguments={
  "probe_mode": "string",
  "probe_query": "string",
  "profile": "string",
  "window_secs": 0,
  "window_turns": 0,
  "workspace_hash": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Get Database Statistics

read-only
TOOLperseus_vault_stats

Return comprehensive database statistics: entity counts by category, type, and decay layer; journal event count; state entry count; database file size; date range of stored data; and history growth (stored version rows, bytes, and the top-10 keys by version count — #398).

Returns

by_categoryobject

Entity counts grouped by category

by_layerobject

Entity counts grouped by decay layer (buffer/working/core)

by_typeobject

Entity counts grouped by type

db_file_size_bytesinteger

Database file size on disk in bytes

history_bytesinteger

Stored history body bytes — SUM(LENGTH(body_json)); row/index overhead excluded (#398)

newest_unix_msinteger | null

Newest entity creation timestamp, or null when the database has no entities

oldest_unix_msinteger | null

Oldest entity creation timestamp, or null when the database has no entities

top_history_keysarray

Top-10 (category, key) pairs by stored version count: [{category, key, versions, bytes}] (#398)

total_entitiesinteger

Total entities in the database

total_history_rowsinteger

Superseded versions stored in entity_history, incl. compaction tombstones (#398)

total_journal_eventsinteger

Total journal events recorded

total_state_entriesinteger

Total state entries (including expired)

Get Database Statistics
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_stats",
    "arguments": {}
  }
}
const result = await client.callTool("perseus_vault_stats", {});
result = await session.call_tool("perseus_vault_stats", arguments={})
Response
{
  "by_category": {},
  "by_layer": {},
  "by_type": {},
  "db_file_size_bytes": 0,
  "history_bytes": 0,
  "newest_unix_ms": 0,
  "oldest_unix_ms": 0,
  "top_history_keys": [],
  "total_entities": 0,
  "total_history_rows": 0,
  "total_journal_events": 0,
  "total_state_entries": 0
}

Compact Low-Decay Entities

destructive
TOOLperseus_vault_compact

Archive entities whose decay score has fallen below a threshold. Supports dry-run mode to preview without making changes. Run periodically or threshold-triggered to keep the database focused on active, high-value memories.

Parameters

dry_runbooleanfalseargument

If true, report what would be archived without making changes

min_decaynumber0.1argument

Decay threshold — entities with decay score below this are archived

Returns

completed_at_unix_msinteger

Completion timestamp

dry_runboolean

Whether this was a dry run

entities_archivedinteger

Number of entities actually archived (0 in dry-run mode)

entities_examinedinteger

Number of entities checked

Compact Low-Decay Entities
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_compact",
    "arguments": {
        "dry_run": false,
        "min_decay": 0.1
      }
  }
}
const result = await client.callTool("perseus_vault_compact", {
  "dry_run": false,
  "min_decay": 0.1
});
result = await session.call_tool("perseus_vault_compact", arguments={
  "dry_run": false,
  "min_decay": 0.1
})
Response
{
  "completed_at_unix_ms": 0,
  "dry_run": true,
  "entities_archived": 0,
  "entities_examined": 0
}

Purge Archived Entities

destructive
TOOLperseus_vault_purge

Permanently delete all archived entities and run VACUUM to reclaim disk space. This is the only operation that actually removes entities — prune/forget only soft-archive. Erasure is complete (#398): every superseded version of a purged entity is deleted from entity_history, and journal rows referencing it are redacted in place (payloads scrubbed; rows kept so the audit hash chain stays verifiable). Purged data is DELETED and NOT RECOVERABLE — this forget-then-purge path is the GDPR-style erasure mechanism. Supports dry_run=true to preview first. Deletion-residue accounting (#990): the report carries a four-way residue partition (purged / declared_residual_controlled / declared_residual_uncontrollable / undeclared_residual), and purge REFUSES to complete while the independent sweep observes undeclared residual state (embedding-snapshot rows, projection-basis rows, or unrevoked artifact bindings whose sources are gone). Use sweep_only=true to run just the sweep and enumerate any orphans.

Parameters

dry_runbooleanfalseargument

If true, report what would be deleted (with the residue partition and gate preview) without making changes

sweep_onlybooleanfalseargument

If true, run only the independent residue sweep (#990): enumerate undeclared residual state and report the hard-gate status without deleting anything

Returns

artifact_bindings_revokedinteger

Learned-artifact bindings revoked because their source entity was physically removed; serve paths refuse revoked bindings (#876)

bytes_freedinteger

Bytes reclaimed after VACUUM (0 in dry-run mode)

completed_at_unix_msinteger

Completion timestamp

dry_runboolean

Whether this was a dry run

embeddings_snapshot_deletedinteger

Pre-quantization float32 snapshot rows removed with their purged source (#990)

entities_deletedinteger

Number of archived entities permanently deleted

history_rows_deletedinteger

Superseded versions of the purged entities deleted from entity_history (#398)

journal_rows_redactedinteger

Journal rows referencing purged entities scrubbed in place; the audit hash chain stays valid (#398)

projection_basis_deletedinteger

Declared embedding-basis rows removed with their purged source (#990)

residueobject

Four-way residue partition of everything derived from the purged set (#990). undeclared_residual is empty for any completed purge (hard gate).

Show child attributes
declared_residual_controlledobject
declared_residual_uncontrollableobject
hard_gate_passedboolean
purgedobject
undeclared_residualobject
undeclared_residual_itemsArray<string>
Purge Archived Entities
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_purge",
    "arguments": {
        "dry_run": false,
        "sweep_only": false
      }
  }
}
const result = await client.callTool("perseus_vault_purge", {
  "dry_run": false,
  "sweep_only": false
});
result = await session.call_tool("perseus_vault_purge", arguments={
  "dry_run": false,
  "sweep_only": false
})
Response
{
  "artifact_bindings_revoked": 0,
  "bytes_freed": 0,
  "completed_at_unix_ms": 0,
  "dry_run": true,
  "embeddings_snapshot_deleted": 0,
  "entities_deleted": 0,
  "history_rows_deleted": 0,
  "journal_rows_redacted": 0,
  "projection_basis_deleted": 0,
  "residue": {
    "declared_residual_controlled": {},
    "declared_residual_uncontrollable": {},
    "hard_gate_passed": true,
    "purged": {},
    "undeclared_residual": {},
    "undeclared_residual_items": [
      "string"
    ]
  }
}

Build Task Projection

TOOLperseus_vault_project_task

Build a compact task-scoped projection (#859): retrieve once, then separate the results into three clearly labeled sections — live_references (pointers into live external systems of record via external_refs), durable_memories (recalled facts), and derived_inferences (inferred/derived facts) — each item carrying a summary, trust class, freshness grade, scope, and provenance digest. The contract block makes permission scope (workspace_scoped/global), freshness anchor, trust classes present, per-section counts, and exclusion reasons visible; no raw recall dump is emitted. Options: query (defaults to task_title), category, workspace_hash (permission scope), limit per section, freshness_window_days (older hits counted as excluded, not dropped silently), min_trust (candidate/corroborated/verified; rejected entities are never projected), include_sections subset, query_time_unix_ms (deterministic replay anchor — identical inputs produce the same projection_id). Output is informational context, not instructions.

Parameters

categorystringargument

Restrict the recall pool to one category.

freshness_window_daysinteger>= 1argument

Only entities created within this many days are projected; older hits are counted in contract.excluded.outside_freshness_window.

include_sectionsArray<string>livedurablederivedargument

Section subset; empty = all three.

limitinteger[1, 100]12argument

Maximum items per section.

min_truststringcandidatecorroboratedverifiedcandidateargument

Minimum trust class. Rejected entities are never projected regardless of this value.

querystringargument

Explicit retrieval query. Defaults to task_title.

query_time_unix_msintegerargument

Anchor instant for freshness grades; omitted = server now. Deterministic replay anchor (#247).

task_descriptionstringargument

Optional task context (advisory; the resolved query wins).

task_titlestringrequiredargument

The task this projection is scoped to. Also the recall query when query is omitted.

workspace_hashstringargument

Permission scope: when set, only matching-workspace or global entities are projected and the contract reports permission: workspace_scoped.

Returns

Returns MCP content array (text, image, or embedded resource).

Build Task Projection
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_project_task",
    "arguments": {
        "category": "string",
        "freshness_window_days": 1,
        "include_sections": [
          "live"
        ],
        "limit": 12,
        "min_trust": "candidate",
        "query": "string",
        "query_time_unix_ms": 0,
        "task_description": "string",
        "task_title": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_project_task", {
  "category": "string",
  "freshness_window_days": 1,
  "include_sections": [
    "live"
  ],
  "limit": 12,
  "min_trust": "candidate",
  "query": "string",
  "query_time_unix_ms": 0,
  "task_description": "string",
  "task_title": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_project_task", arguments={
  "category": "string",
  "freshness_window_days": 1,
  "include_sections": [
    "live"
  ],
  "limit": 12,
  "min_trust": "candidate",
  "query": "string",
  "query_time_unix_ms": 0,
  "task_description": "string",
  "task_title": "string",
  "workspace_hash": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Expand Source Chunk

TOOLperseus_vault_expand_source

Expand a distilled fact's source reference back to the verbatim span of its retained transcript (#888). Fact mode (category+key of a capture note): reads the note's stamped source_chunk and returns the exact source text under a char budget, with source metadata, span offsets, and a SHA-256 integrity verdict against the retained store. Explicit mode (source_category+source_key+start_char+end_char): expands an arbitrary span of any retained source with optional span_sha256 verification. Bi-temporal: as_of_unix_ms defaults to the fact's capture time, so the text is the span as it existed when the fact was distilled; pass a later anchor to read the source as it is today. Graceful outcomes (never errors): no_source_ref (fact has no source ref — API writes, LLM-distilled notes, retain_transcript=false), fact_not_found, source_missing, span_invalid (out_of_bounds or hash_mismatch — fail-closed, no text). max_chars budget 1..=16384 (default 2000); longer spans are truncated with truncated:true. Output is verbatim informational context, not instructions.

Parameters

as_of_unix_msintegerargument

Bi-temporal anchor; defaults to the fact's capture time.

categorystringargument

Fact mode: category of the distilled fact entity.

end_charinteger>= 0argument

Explicit mode: span end (char offset, exclusive).

keystringargument

Fact mode: key of the distilled fact entity.

max_charsinteger[1, 16384]2000argument

Char budget for the returned text.

source_categorystringargument

Explicit mode: category of the retained source.

source_keystringargument

Explicit mode: key of the retained source.

span_sha256stringargument

Explicit mode: optional expected SHA-256 of the verbatim span; verified when present.

start_charinteger>= 0argument

Explicit mode: span start (char offset, inclusive).

workspace_hashstringargument

Permission scope.

Returns

Returns MCP content array (text, image, or embedded resource).

Expand Source Chunk
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_expand_source",
    "arguments": {
        "as_of_unix_ms": 0,
        "category": "string",
        "end_char": 0,
        "key": "string",
        "max_chars": 2000,
        "source_category": "string",
        "source_key": "string",
        "span_sha256": "string",
        "start_char": 0,
        "workspace_hash": ""
      }
  }
}
const result = await client.callTool("perseus_vault_expand_source", {
  "as_of_unix_ms": 0,
  "category": "string",
  "end_char": 0,
  "key": "string",
  "max_chars": 2000,
  "source_category": "string",
  "source_key": "string",
  "span_sha256": "string",
  "start_char": 0,
  "workspace_hash": ""
});
result = await session.call_tool("perseus_vault_expand_source", arguments={
  "as_of_unix_ms": 0,
  "category": "string",
  "end_char": 0,
  "key": "string",
  "max_chars": 2000,
  "source_category": "string",
  "source_key": "string",
  "span_sha256": "string",
  "start_char": 0,
  "workspace_hash": ""
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Expire Due Entities

destructive
TOOLperseus_vault_expire

Time-based lifecycle sweep (#868): transition entities whose expires_at_unix_ms has passed to status='expired'. Content, history, and searchability are RETAINED — expiry is not erasure, and recall already excludes expired rows; the sweep makes the lifecycle state explicit and observable. Idempotent and re-runnable; use dry_run=true to preview with identical predicates. Contract: docs/specs/data-boundaries-retention-lifecycle.md.

Parameters

dry_runbooleanfalseargument

If true, report what would be expired without making changes

workspace_hashstringargument

Restrict the sweep to one workspace (empty = global sweep)

Returns

completed_at_unix_msinteger

Completion timestamp

dry_runboolean

Whether this was a dry run

entities_expiredinteger

Entities transitioned to status='expired'

workspace_hashstring

Workspace the sweep was restricted to ('' = global)

Expire Due Entities
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_expire",
    "arguments": {
        "dry_run": false,
        "workspace_hash": ""
      }
  }
}
const result = await client.callTool("perseus_vault_expire", {
  "dry_run": false,
  "workspace_hash": ""
});
result = await session.call_tool("perseus_vault_expire", arguments={
  "dry_run": false,
  "workspace_hash": ""
})
Response
{
  "completed_at_unix_ms": 0,
  "dry_run": true,
  "entities_expired": 0,
  "workspace_hash": "string"
}

Redact Entity Content

destructive
TOOLperseus_vault_redact

Content redaction (#868): scrub the body of a workspace-scoped entity to a hash-only marker, delete its history snapshots and FTS text, and append a hash-only 'redacted' journal event. Metadata (id, key, links, provenance) is RETAINED; re-ingest of the same value stays allowed (redaction ≠ erasure). Requires an explicit workspace_hash (fail-closed, #854). Contract: docs/specs/data-boundaries-retention-lifecycle.md.

Parameters

agent_idstringargument

Acting agent for attribution (overridden by the transport-stamped requesting_agent_id when present)

categorystringrequiredargument

Entity category

keystringrequiredargument

Entity key

requesting_agent_idstringargument

MCP session identity stamped by the transport; overrides agent_id

workspace_hashstringrequiredargument

Workspace scope of the entity (required — a bare category/key is ambiguous)

Returns

completed_at_unix_msinteger

Completion timestamp

entity_idstring

Id of the first redacted row

foundboolean

Whether a matching entity was found and redacted

fts_cleanedinteger

FTS index rows removed

history_deletedinteger

History snapshot rows deleted (content-bearing)

journal_event_idstring

Id of the hash-only 'redacted' journal event

value_sha256string

Hash-only audit evidence: sha256 of the scrubbed body

workspace_hashstring

Workspace the redaction was scoped to

Redact Entity Content
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_redact",
    "arguments": {
        "agent_id": "",
        "category": "string",
        "key": "string",
        "requesting_agent_id": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_redact", {
  "agent_id": "",
  "category": "string",
  "key": "string",
  "requesting_agent_id": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_redact", arguments={
  "agent_id": "",
  "category": "string",
  "key": "string",
  "requesting_agent_id": "string",
  "workspace_hash": "string"
})
Response
{
  "completed_at_unix_ms": 0,
  "entity_id": "string",
  "found": true,
  "fts_cleaned": 0,
  "history_deleted": 0,
  "journal_event_id": "string",
  "value_sha256": "string",
  "workspace_hash": "string"
}

Erase Entity Permanently

destructive
TOOLperseus_vault_erase

Physical erasure (#868/#866): permanently remove a workspace-scoped entity from the primary store AND all derived layers (FTS, history, history-FTS, community membership, inbound links, journal payloads), quarantine derived entities that cited it via evidence links, install a permanent rejection tombstone + governance mandate (re-ingest fails closed and survives primary-DB rollback), and append a hash-only 'erased' journal event. ERASED DATA IS NOT RECOVERABLE. Requires an explicit workspace_hash (fail-closed, #854). Use dry_run=true to preview exact counts. Contract: docs/specs/data-boundaries-retention-lifecycle.md.

Parameters

agent_idstringargument

Acting agent for attribution (overridden by the transport-stamped requesting_agent_id when present)

categorystringrequiredargument

Entity category

dry_runbooleanfalseargument

If true, report exactly what would be erased without making changes

keystringrequiredargument

Entity key

requesting_agent_idstringargument

MCP session identity stamped by the transport; overrides agent_id

workspace_hashstringrequiredargument

Workspace scope of the entity (required — a bare category/key is ambiguous)

Returns

community_memberships_cleanedinteger

Community member_ids entries removed

community_rows_deletedinteger

Communities deleted because the erased entity was their last member

completed_at_unix_msinteger

Completion timestamp

derived_quarantinedinteger

Derived entities citing the erased source, now quarantined pending operator review

dry_runboolean

Whether this was a dry run

entities_erasedinteger

Primary rows removed

fts_cleanedinteger

FTS index rows removed

governance_mandate_okboolean

False if the permanent re-ingest mandate could not be installed (content is gone; guard needs operator attention)

history_deletedinteger

History snapshot rows removed

inbound_links_cleanedinteger

Inbound link edges removed from other rows

journal_event_idstring

Id of the hash-only 'erased' journal event

journal_rows_redactedinteger

Journal payloads scrubbed in place (audit chain preserved)

value_sha256string

Hash-only evidence: sha256 of the erased body

workspace_hashstring

Workspace the erasure was scoped to

Erase Entity Permanently
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_erase",
    "arguments": {
        "agent_id": "",
        "category": "string",
        "dry_run": false,
        "key": "string",
        "requesting_agent_id": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_erase", {
  "agent_id": "",
  "category": "string",
  "dry_run": false,
  "key": "string",
  "requesting_agent_id": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_erase", arguments={
  "agent_id": "",
  "category": "string",
  "dry_run": false,
  "key": "string",
  "requesting_agent_id": "string",
  "workspace_hash": "string"
})
Response
{
  "community_memberships_cleaned": 0,
  "community_rows_deleted": 0,
  "completed_at_unix_ms": 0,
  "derived_quarantined": 0,
  "dry_run": true,
  "entities_erased": 0,
  "fts_cleaned": 0,
  "governance_mandate_ok": true,
  "history_deleted": 0,
  "inbound_links_cleaned": 0,
  "journal_event_id": "string",
  "journal_rows_redacted": 0,
  "value_sha256": "string",
  "workspace_hash": "string"
}

Memories Directory (Anthropic convention)

TOOLperseus_vault_memories

Anthropic memory-tool compatible file interface over the vault: view / create / str_replace / insert / delete / rename on paths under /memories. Files are stored as vault entities (category 'memories', FTS-indexed, encrypted at rest, edits versioned via history), so clients built against Claude's native memory directory convention can use the vault unchanged. Use command='view' with path='/memories' to list files.

Parameters

commandstringviewcreatestr_replaceinsertdeleterenamerequiredargument

The operation to perform

file_textstringargument

create: full file content to write (overwrites an existing file)

insert_lineintegerargument

insert: line number to insert AT (0 = beginning of file)

insert_textstringargument

insert: the line to insert

new_pathstringargument

rename: destination path (must not exist)

new_strstringargument

str_replace: replacement text

old_pathstringargument

rename: current path

old_strstringargument

str_replace: exact text to replace — must occur exactly once in the file

pathstringargument

Path under /memories (e.g. '/memories/notes.md'). For view, '/memories' lists the directory.

Returns

Returns MCP content array (text, image, or embedded resource).

Memories Directory (Anthropic convention)
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_memories",
    "arguments": {
        "command": "view",
        "file_text": "string",
        "insert_line": 0,
        "insert_text": "string",
        "new_path": "string",
        "new_str": "string",
        "old_path": "string",
        "old_str": "string",
        "path": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_memories", {
  "command": "view",
  "file_text": "string",
  "insert_line": 0,
  "insert_text": "string",
  "new_path": "string",
  "new_str": "string",
  "old_path": "string",
  "old_str": "string",
  "path": "string"
});
result = await session.call_tool("perseus_vault_memories", arguments={
  "command": "view",
  "file_text": "string",
  "insert_line": 0,
  "insert_text": "string",
  "new_path": "string",
  "new_str": "string",
  "old_path": "string",
  "old_str": "string",
  "path": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Migrate Legacy Database

destructive
TOOLperseus_vault_migrate

Migrate a v0.1.x Perseus Vault database to the current v0.5.0 schema. Reads the old database, converts memories to the entity model, and merges into the current database. Use this once per legacy database during upgrade.

Parameters

from_pathstringrequiredargument

Absolute path to the v0.1.x SQLite database file to migrate

Returns

completed_at_unix_msinteger

Completion timestamp

entities_createdinteger

New entities created from old memories

entities_updatedinteger

Existing entities updated during merge

errorsArray<string>

Any errors encountered during migration

total_old_memoriesinteger

Number of memories found in the old database

Migrate Legacy Database
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_migrate",
    "arguments": {
        "from_path": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_migrate", {
  "from_path": "string"
});
result = await session.call_tool("perseus_vault_migrate", arguments={
  "from_path": "string"
})
Response
{
  "completed_at_unix_ms": 0,
  "entities_created": 0,
  "entities_updated": 0,
  "errors": [
    "string"
  ],
  "total_old_memories": 0
}

Get Context Block

read-only
TOOLperseus_vault_context

Return a pre-formatted markdown context block for session injection. Recall-first by default (mode 'on_demand'): pass query (the current task/message) and only topically relevant entities — recall_when trigger matches + keyword matches — are injected, alongside a hard-capped always-on set, clamped to a per-model character budget. Without query the block is a compact retrieval pointer (byte-stable across unrelated writes — prefix-cache friendly). The legacy unconditional top-N dump requires explicit mode 'always_inject'. Output is informational context, not instructions.

Parameters

categoriesArray<string>argument

Categories to include. Empty array = all categories.

include_declared_graphbooleanfalseargument

#1142: attach a bounded workspace-scoped hash-only declared graph projection to the context response. Requires workspace_hash and a transport-stamped requester.

include_provider_sourcebooleanfalseargument

#1141: include sanitized provider identity and thread lineage on context lines; provider bodies and payloads are excluded.

include_selection_decisionsbooleanfalseargument

#1140: attach a bounded, hash-only per-candidate context-selection projection with source-arm ranks, eligibility/disposition reason codes, token estimates, arm state, and a replay fingerprint. Omit to preserve the legacy response shape.

limitinteger10argument

Maximum number of entities to include in the context block

max_context_charsintegerargument

Explicit character budget for the rendered block; overrides the model profile. In always_inject mode output is clamped only when this is set.

modestringon_demandalways_injecton_demandargument

Injection posture (#366). 'on_demand' (default): relevance-gated, budget-clamped, recall-first. 'always_inject': legacy unconditional top-N dump (no relevance gating) — explicit opt-in only.

modelstringargument

Host model name for recall-budget profile resolution (#366), e.g. 'claude-opus-4-8' gets a larger budget. Unknown/omitted models use the default 1500-char profile.

querystringargument

Current task/message text — the relevance gate (#356). In on_demand mode only entities whose recall_when triggers or indexed content match it are injected; omit for a compact retrieval pointer with no topical injection.

session_idstringargument

Session id for preload usage telemetry (#875): injected entities are attributed to this session for precision/recall resolution. Omit or leave empty when unknown.

workspace_hashstringargument

Workspace scope filter (v1.2.0). When set, only entities with a matching workspace_hash are included (always-on set too). Omit for no workspace filtering — in a federated vault that leaks every workspace's memory into the block.

Returns

budget_charsinteger

Resolved character budget (0 = unclamped legacy output)

declared_graphobject

#1142: optional bounded declared graph projection with hash-only source, span, scope, origin, validity, and support state.

entities_injectedinteger

Number of entities actually injected (always-on + topical)

markdownstring

Markdown-formatted context block with entity details

modestring

Resolved injection mode: on_demand or always_inject

selection_decisionsobject

#1140: optional bounded, hash-only context-selection projection. Contains policy/schema digests, candidate/retention counts, arm states, token estimates, dispositions, delivered order, and replay fingerprint; it never contains query text or memory bodies.

total_charsinteger

Character count of the markdown content

warningsArray<string>

Soft warnings: always-on cap overflow, budget truncation

Get Context Block
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_context",
    "arguments": {
        "categories": [
          "string"
        ],
        "include_declared_graph": false,
        "include_provider_source": false,
        "include_selection_decisions": false,
        "limit": 10,
        "max_context_chars": 0,
        "mode": "on_demand",
        "model": "string",
        "query": "string",
        "session_id": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_context", {
  "categories": [
    "string"
  ],
  "include_declared_graph": false,
  "include_provider_source": false,
  "include_selection_decisions": false,
  "limit": 10,
  "max_context_chars": 0,
  "mode": "on_demand",
  "model": "string",
  "query": "string",
  "session_id": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_context", arguments={
  "categories": [
    "string"
  ],
  "include_declared_graph": false,
  "include_provider_source": false,
  "include_selection_decisions": false,
  "limit": 10,
  "max_context_chars": 0,
  "mode": "on_demand",
  "model": "string",
  "query": "string",
  "session_id": "string",
  "workspace_hash": "string"
})
Response
{
  "budget_chars": 0,
  "declared_graph": {},
  "entities_injected": 0,
  "markdown": "string",
  "mode": "string",
  "selection_decisions": {},
  "total_chars": 0,
  "warnings": [
    "string"
  ]
}

Extract Structured Knowledge

read-only
TOOLperseus_vault_extract

Extract structured knowledge — facts, preferences, temporal events, episodes — from raw text or a stored entity, using a fully local, deterministic rule-based extractor (no cloud LLM, no embedding/API call, no network). Read-only: never writes to the store. Provide text, or category + key to extract from a stored entity.

Parameters

categorystringargument

Category of a stored entity to extract from (requires key).

keystringargument

Key of a stored entity to extract from (requires category).

strategystringrule_basednonerule_basedargument

Extractor strategy: 'rule_based' (local heuristics) or 'none' (no-op).

textstringargument

Raw text to extract from. If omitted, category + key of a stored entity are used.

Returns

itemsArray<object>

Extracted items, each an object with kind and text.

strategystring

Extractor strategy used

totalinteger

Number of items extracted

Extract Structured Knowledge
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_extract",
    "arguments": {
        "category": "string",
        "key": "string",
        "strategy": "rule_based",
        "text": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_extract", {
  "category": "string",
  "key": "string",
  "strategy": "rule_based",
  "text": "string"
});
result = await session.call_tool("perseus_vault_extract", arguments={
  "category": "string",
  "key": "string",
  "strategy": "rule_based",
  "text": "string"
})
Response
{
  "items": [
    {}
  ],
  "strategy": "string",
  "total": 0
}

Capture Session Insights

TOOLperseus_vault_capture

Opt-in in-session memory capture (#520): distill a session transcript or insight payload into durable memory entities the moment a problem is solved, instead of waiting for a scheduled harvest. Splits the payload into candidate notes (headed sections, paragraphs, or JSONL records — auto-detected), classifies each by cheap local signals into root-cause / pitfall / decision / pattern / takeaway, and writes each through the normal remember path with source='capture' (layer buffer, moderate importance). Fully local and deterministic by default — no LLM, no network; pass llm=true to distill via the configured --llm-endpoint instead (falls back to the rule-based path on any LLM failure or timeout). Anti-flood by design: near-duplicate merging stays ON (a re-captured solved problem merges into the existing memory), same-headline notes update in place, and writes are capped per invocation with dropped notes reported. Nothing runs automatically — capture happens only when this tool (or the perseus-vault capture CLI verb) is explicitly invoked, e.g. from an on_insight or SessionEnd lifecycle hook (run maintain after end-of-session capture).

Body

application/json
agent_idstring

Agent ID recorded on the captured entities.

consumebooleanfalse

#563: after a SUCCESSFUL non-dry-run capture, atomically remove exactly the captured regions from source_file (temp file + rename, leaving a .bak). Scoped to captured records only — surrounding headers/rules/pointers are left untouched. No-op under dry_run, when nothing was captured, or when source_file is unset, so it can never delete content that was not durably stored. Use it to keep a host-inlined write-buffer (e.g. an AGENTS.local.md the agent loads every turn) from accumulating already-stored blocks forever. The result reports 'consumed' (regions removed) and 'source_backup'.

dry_runbooleanfalse

Distill and return the would-be notes without writing anything.

evidenceobject

Write-time evidence envelope for captured notes. Omit only for legacy_unknown compatibility.

Show child attributes
capture_modestringsnapshothash_onlypointer_onlynot_requestedcapture_failedlegacy_unknownrequired
captured_at_unix_msintegerrequired
content_sha256string
replayablebooleanrequired
resolved_valueany

Resolved source value retained at capture time

source_refstring
source_systemstring
llmbooleanfalse

Distill via the configured LLM endpoint instead of the local rule-based distiller. Requires --llm-endpoint; falls back to the rule-based path on any LLM failure (the result's llm_fallback field says why).

max_entitiesinteger20

Anti-flood cap: max entities written by this invocation (1-20; callers can lower the cap, not raise it). Notes beyond the cap are dropped and counted in the result.

source_filestring

#563: path to the file the payload came from. Required for consume to have anything to prune; ignored when consume is false.

textstringrequired

The transcript / insight payload to distill. Plain text, markdown (headed sections become separate notes), or JSONL (one note per record, using its content/text/insight/lesson/summary/message field).

workspace_hashstring

Workspace hash to scope the captured entities to. Omit for unscoped (global) capture.

Returns

candidatesinteger

Candidate notes found in the payload before capping

capturedinteger

Number of notes distilled (and written, unless dry_run)

consumedinteger

#563: number of captured regions removed from source_file (0 unless consume=true and the prune ran). See source_backup / consume_skipped / consume_error.

createdinteger

Notes that created a new entity

distillerstring

'rule_based' or 'llm' — which distiller produced the notes

droppedinteger

Candidate notes dropped by the per-invocation cap

dry_runboolean

True when nothing was written

llm_fallbackstring

Present when llm=true was requested but the rule-based path was used; says why

mergedinteger

Notes merged into an existing near-duplicate entity by the trigram dedup (the capture flood control)

messagestring

Unambiguous empty state when the payload contained nothing durable

notesArray<object>

Per-note report: {id, key, type, summary, action}

source_backupstring

#563: path to the pre-prune backup (.bak) written when consumed > 0

updatedinteger

Notes that updated an existing entity in place (same category+key)

Capture Session Insights
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_capture",
    "arguments": {
        "agent_id": "string",
        "consume": false,
        "dry_run": false,
        "evidence": {
          "capture_mode": "snapshot",
          "captured_at_unix_ms": 0,
          "content_sha256": "string",
          "replayable": true,
          "source_ref": "string",
          "source_system": "string"
        },
        "llm": false,
        "max_entities": 20,
        "source_file": "string",
        "text": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_capture", {
  "agent_id": "string",
  "consume": false,
  "dry_run": false,
  "evidence": {
    "capture_mode": "snapshot",
    "captured_at_unix_ms": 0,
    "content_sha256": "string",
    "replayable": true,
    "source_ref": "string",
    "source_system": "string"
  },
  "llm": false,
  "max_entities": 20,
  "source_file": "string",
  "text": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_capture", arguments={
  "agent_id": "string",
  "consume": false,
  "dry_run": false,
  "evidence": {
    "capture_mode": "snapshot",
    "captured_at_unix_ms": 0,
    "content_sha256": "string",
    "replayable": true,
    "source_ref": "string",
    "source_system": "string"
  },
  "llm": false,
  "max_entities": 20,
  "source_file": "string",
  "text": "string",
  "workspace_hash": "string"
})
Request Body
{
  "agent_id": "string",
  "consume": false,
  "dry_run": false,
  "evidence": {
    "capture_mode": "snapshot",
    "captured_at_unix_ms": 0,
    "content_sha256": "string",
    "replayable": true,
    "source_ref": "string",
    "source_system": "string"
  },
  "llm": false,
  "max_entities": 20,
  "source_file": "string",
  "text": "string",
  "workspace_hash": "string"
}
Response
{
  "candidates": 0,
  "captured": 0,
  "consumed": 0,
  "created": 0,
  "distiller": "string",
  "dropped": 0,
  "dry_run": true,
  "llm_fallback": "string",
  "merged": 0,
  "message": "string",
  "notes": [
    {}
  ],
  "source_backup": "string",
  "updated": 0
}

Traverse Entity Graph

read-only
TOOLperseus_vault_traverse

Walk the entity link graph starting from a given entity up to a configurable depth. Returns a chain of linked entities — useful for exploring dependencies, decision trees, and relationship graphs built via perseus_vault_link.

Parameters

categorystringrequiredargument

Starting entity category

include_declared_graphbooleanfalseargument

#1142: attach a bounded hash-only declared graph projection; ordinary entity traversal never queries it.

keystringrequiredargument

Starting entity key

max_depthinteger3argument

Maximum traversal depth from the starting entity

max_nodesinteger100argument

Maximum total nodes to traverse before stopping

requesting_agent_idstringargument

Transport-stamped requester identity; required at runtime for body-safe traversal.

workspace_hashstringargument

Workspace scope required when include_declared_graph is true.

Returns

declared_graphobject

#1142: optional bounded declared graph projection with hash-only source, span, scope, origin, validity, and support state.

entityobjectrequired

Root entity with its links

traversedArray<object>required

Linked entities traversed from root

Traverse Entity Graph
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_traverse",
    "arguments": {
        "category": "string",
        "include_declared_graph": false,
        "key": "string",
        "max_depth": 3,
        "max_nodes": 100,
        "requesting_agent_id": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_traverse", {
  "category": "string",
  "include_declared_graph": false,
  "key": "string",
  "max_depth": 3,
  "max_nodes": 100,
  "requesting_agent_id": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_traverse", arguments={
  "category": "string",
  "include_declared_graph": false,
  "key": "string",
  "max_depth": 3,
  "max_nodes": 100,
  "requesting_agent_id": "string",
  "workspace_hash": "string"
})
Response
{
  "declared_graph": {},
  "entity": {},
  "traversed": [
    {}
  ]
}

Graph Drift Report

read-only
TOOLperseus_vault_graph_drift

Read-only graph/entities/indexes/receipts drift report (#869): counts unattested edges (no evidence anchor — NOT serveable by the graph recall arms), dangling links, links to archived/expired targets, cross-workspace links, stale community memberships, FTS drift, and journal receipts referencing missing entities. consistent is true when all structural graph checks are clear. Run this after upgrades or bulk imports to see whether the link graph is in a serveable, synchronized state.

Parameters

workspace_hashstringargument

Optional workspace scope. Omit (or "") for all workspaces.

Returns

checked_at_unix_msinteger
consistentboolean
driftobject
entitiesobject
linksobject
workspacestring
Graph Drift Report
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_graph_drift",
    "arguments": {
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_graph_drift", {
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_graph_drift", arguments={
  "workspace_hash": "string"
})
Response
{
  "checked_at_unix_ms": 0,
  "consistent": true,
  "drift": {},
  "entities": {},
  "links": {},
  "workspace": "string"
}

Attest Legacy Graph Edges

destructive
TOOLperseus_vault_graph_attest

Stamp the from-side entity id as the evidence anchor on legacy edges that lack one (pre-#869 rows, hand-edited data), making them serveable by the graph recall arms. Workspace-scoped; use dry_run to preview. Applied runs journal one graph_attest event. After attestation, perseus_vault_graph_drift reports unattested = 0 for the covered scope.

Parameters

dry_runbooleanfalseargument

Preview the stamping without writing.

workspace_hashstringargument

Optional workspace scope. Omit (or "") for all workspaces.

Returns

dry_runboolean
entities_affectedinteger
journal_eventstring
links_stampedinteger
links_to_stampinteger
workspacestring
Attest Legacy Graph Edges
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_graph_attest",
    "arguments": {
        "dry_run": false,
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_graph_attest", {
  "dry_run": false,
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_graph_attest", arguments={
  "dry_run": false,
  "workspace_hash": "string"
})
Response
{
  "dry_run": true,
  "entities_affected": 0,
  "journal_event": "string",
  "links_stamped": 0,
  "links_to_stamp": 0,
  "workspace": "string"
}

Score Entity Quality

destructive
TOOLperseus_vault_score

Assign a quality score (0.0–1.0) to an entity. The score persists as an importance floor: decay_tick/cohere never recompute decay_score below it, so an explicitly scored memory survives idle time indefinitely (fidelity beats recency). Scores >= 0.7 also mark the entity verified. Re-score with 0.0 to clear the floor. Use this to mark entities as accurate, verified, or deprecated.

Parameters

categorystringrequiredargument

Entity category to score

keystringrequiredargument

Entity key to score

scorenumberrequiredargument

Quality score 0.0–1.0. 1.0 = verified, 0.5 = neutral, 0.0 = low quality

Returns

categorystring

Entity category

foundboolean

Whether the entity was found

keystring

Entity key

scorenumber

Quality score assigned

Score Entity Quality
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_score",
    "arguments": {
        "category": "string",
        "key": "string",
        "score": 0
      }
  }
}
const result = await client.callTool("perseus_vault_score", {
  "category": "string",
  "key": "string",
  "score": 0
});
result = await session.call_tool("perseus_vault_score", arguments={
  "category": "string",
  "key": "string",
  "score": 0
})
Response
{
  "category": "string",
  "found": true,
  "key": "string",
  "score": 0
}

Record Follow/Miss Efficacy Signal

destructive
TOOLperseus_vault_follow

Record whether an entity (typically a convention/insight/lesson) was actually FOLLOWED or MISSED by the agent — the honest follow-rate signal. Unlike retrieval_count (how often a memory is recalled), this tracks whether recall changed behavior. After enough attempts, efficacy_status flips to 'useful' or 'dead' and feeds into decay scoring so ignored rules decay out of recall while followed ones resist decay.

Parameters

categorystringrequiredargument

Entity category

contextstringargument

Optional description of the action/context this observation relates to

followedbooleanrequiredargument

true if the agent's action followed/honored this entity's guidance, false if it was ignored/missed

keystringrequiredargument

Entity key

workspace_hashstringargument

Workspace scope filter. When set, the stamped row is resolved with strict workspace equality — the same semantics as a workspace-scoped recall — so the signal lands on the row the agent actually saw (no global fallback). Omit to keep the unscoped deterministic pick (global '' row first, then lexicographically-first workspace).

Returns

categorystring
efficacy_statusstring

'unverified' | 'useful' | 'dead'

follow_countinteger
follow_ratenumber
foundboolean

Whether the entity was found

keystring
miss_countinteger
Record Follow/Miss Efficacy Signal
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_follow",
    "arguments": {
        "category": "string",
        "context": "string",
        "followed": true,
        "key": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_follow", {
  "category": "string",
  "context": "string",
  "followed": true,
  "key": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_follow", arguments={
  "category": "string",
  "context": "string",
  "followed": true,
  "key": "string",
  "workspace_hash": "string"
})
Response
{
  "category": "string",
  "efficacy_status": "string",
  "follow_count": 0,
  "follow_rate": 0,
  "found": true,
  "key": "string",
  "miss_count": 0
}

perseus_vault_operator_review

TOOLperseus_vault_operator_review

Read-only operator review queue for contradictions, stale/low-actionability facts, and deprecated supersession lag. Does not resolve or hide findings.

Parameters

categorystringargument

Category to review (default general).

limitinteger[1, 1000]argument
stale_thresholdnumber[0, 1]argument

Returns

Returns MCP content array (text, image, or embedded resource).

perseus_vault_operator_review
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_operator_review",
    "arguments": {
        "category": "string",
        "limit": 1,
        "stale_threshold": 0
      }
  }
}
const result = await client.callTool("perseus_vault_operator_review", {
  "category": "string",
  "limit": 1,
  "stale_threshold": 0
});
result = await session.call_tool("perseus_vault_operator_review", arguments={
  "category": "string",
  "limit": 1,
  "stale_threshold": 0
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

perseus_vault_eval_history

TOOLperseus_vault_eval_history

#930: read-only scheduled-recall evaluation history — bounded quality-run snapshots (nightly curation + midday eval) with per-metric trend and regression breach records. Never mutates.

Parameters

kindstringargument

Cadence filter: nightly | midday | manual (default all).

limitinteger[1, 100]argument

Max runs (default 20).

regressed_onlybooleanargument

Only runs with regression breaches (default false).

Returns

Returns MCP content array (text, image, or embedded resource).

perseus_vault_eval_history
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_eval_history",
    "arguments": {
        "kind": "string",
        "limit": 1,
        "regressed_only": true
      }
  }
}
const result = await client.callTool("perseus_vault_eval_history", {
  "kind": "string",
  "limit": 1,
  "regressed_only": true
});
result = await session.call_tool("perseus_vault_eval_history", arguments={
  "kind": "string",
  "limit": 1,
  "regressed_only": true
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

perseus_vault_web_gap_fill

TOOLperseus_vault_web_gap_fill

#929: OPT-IN live-web gap-fill write-back. The vault never fetches the web; the agent fetches, then reports grounded content + source URLs here for validation (allowlisted hosts, no secrets) and audited storage as unverified-until-confirmed.

Parameters

agent_idstringargument

Write attribution.

categorystringargument

Entity category (default "web").

contentstringargument

Agent-fetched page content (max 64 KiB).

keystringargument

Stable key (default: web-<sha256(content)[..16]>).

querystringargument

The recall query that missed.

relevance_scorenumberargument

Agent-judged relevance 0-1 (must clear the configured floor).

sourcesArray<string>argument

1-8 http/https source URLs actually fetched by the agent.

titlestringargument

Page title (max 512 chars).

workspace_hashstringargument

Workspace scope (required; must be allowlisted).

Returns

Returns MCP content array (text, image, or embedded resource).

perseus_vault_web_gap_fill
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_web_gap_fill",
    "arguments": {
        "agent_id": "string",
        "category": "string",
        "content": "string",
        "key": "string",
        "query": "string",
        "relevance_score": 0,
        "sources": [
          "string"
        ],
        "title": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_web_gap_fill", {
  "agent_id": "string",
  "category": "string",
  "content": "string",
  "key": "string",
  "query": "string",
  "relevance_score": 0,
  "sources": [
    "string"
  ],
  "title": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_web_gap_fill", arguments={
  "agent_id": "string",
  "category": "string",
  "content": "string",
  "key": "string",
  "query": "string",
  "relevance_score": 0,
  "sources": [
    "string"
  ],
  "title": "string",
  "workspace_hash": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

perseus_vault_mental_model_set

TOOLperseus_vault_mental_model_set

#886: create or refresh a curated mental model — the ONLY sanctioned write path for the mental_model category (auto-generated passes refuse it). Versioned via the audited remember path (entity_history); provenance stamped (curated_by/curated_at); revision bumps on every re-assert; review clock resets. recall_when triggers attach for scheduled re-verification.

Parameters

keystringrequiredargument

Stable key of the mental model (e.g. "stack-portal")

recall_whenArray<string>argument

Triggers for scheduled re-verification (matched by perseus_vault_recall_when / prepare)

requesting_agent_idstringargument

Curator identity (default "operator")

review_interval_daysinteger30argument

Age-based review interval (1..=3650)

scopestringargument

Raw-fact category this model covers ("" = none); enables the newer-facts staleness check

source_idsArray<string>argument

Provenance: raw fact / observation entity ids it was curated from

summarystringrequiredargument

The curated summary (1..=4096 chars) — what the model answers; consulted before observations and raw facts in ask/recall

workspace_hashstringargument

Workspace scope (default global/empty)

Returns

curated_bystring
idstring
keystring
okboolean
revisioninteger
perseus_vault_mental_model_set
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_mental_model_set",
    "arguments": {
        "key": "string",
        "recall_when": [
          "string"
        ],
        "requesting_agent_id": "string",
        "review_interval_days": 30,
        "scope": "string",
        "source_ids": [
          "string"
        ],
        "summary": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_mental_model_set", {
  "key": "string",
  "recall_when": [
    "string"
  ],
  "requesting_agent_id": "string",
  "review_interval_days": 30,
  "scope": "string",
  "source_ids": [
    "string"
  ],
  "summary": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_mental_model_set", arguments={
  "key": "string",
  "recall_when": [
    "string"
  ],
  "requesting_agent_id": "string",
  "review_interval_days": 30,
  "scope": "string",
  "source_ids": [
    "string"
  ],
  "summary": "string",
  "workspace_hash": "string"
})
Response
{
  "curated_by": "string",
  "id": "string",
  "key": "string",
  "ok": true,
  "revision": 0
}

perseus_vault_mental_model_review

TOOLperseus_vault_mental_model_review

#886: mental-model review — list flagged stale curated summaries (reason: age / newer_facts: / malformed_body, with age_days and newest-fact trace), or stamp an operator approve/dismiss decision (resets the age clock and records the decision; the summary itself only changes via perseus_vault_mental_model_set). Flags are also surfaced in perseus_vault_operator_review.

Parameters

actionstringlistapprovedismisslistargument

list flagged stale models (default) | approve | dismiss

keystringargument

Key of the model to decide on (required for approve/dismiss)

limitinteger<= 100050argument
requesting_agent_idstringargument

Reviewer identity (default "operator")

workspace_hashstringargument

Workspace scope (default global/empty)

Returns

actionstring
flaggedArray<object>
flagged_countinteger
perseus_vault_mental_model_review
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_mental_model_review",
    "arguments": {
        "action": "list",
        "key": "string",
        "limit": 50,
        "requesting_agent_id": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_mental_model_review", {
  "action": "list",
  "key": "string",
  "limit": 50,
  "requesting_agent_id": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_mental_model_review", arguments={
  "action": "list",
  "key": "string",
  "limit": 50,
  "requesting_agent_id": "string",
  "workspace_hash": "string"
})
Response
{
  "action": "string",
  "flagged": [
    {}
  ],
  "flagged_count": 0
}

perseus_vault_write_quarantine

TOOLperseus_vault_write_quarantine

#874: review the write-quarantine hold — writes whose measured interference exceeded the configured bound are staged here (never served by any read surface) instead of committing to memory. list (default): pending holds with scores; show: full record incl. decrypted body + interference report; release: materialize one through the audited remember path (the operator review IS the approval; refused when the identity is already live); delete: drop one without materialization. Every decision is journaled (interference_released / interference_deleted). Pending items also surface in perseus_vault_operator_review.

Parameters

actionstringlistshowreleasedeletelistargument

list (default) | show | release | delete

idstringargument

Quarantine id (required for show/release/delete)

limitinteger<= 1000050argument
requesting_agent_idstringargument

Reviewer identity stamped into the journal (default empty)

workspace_hashstringargument

Workspace scope for list (default all)

Returns

countinteger
deletedboolean
itemsArray<object>
releasedboolean
perseus_vault_write_quarantine
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_write_quarantine",
    "arguments": {
        "action": "list",
        "id": "string",
        "limit": 50,
        "requesting_agent_id": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_write_quarantine", {
  "action": "list",
  "id": "string",
  "limit": 50,
  "requesting_agent_id": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_write_quarantine", arguments={
  "action": "list",
  "id": "string",
  "limit": 50,
  "requesting_agent_id": "string",
  "workspace_hash": "string"
})
Response
{
  "count": 0,
  "deleted": true,
  "items": [
    {}
  ],
  "released": true
}

perseus_vault_admission_decide

TOOLperseus_vault_admission_decide

#1107: resolve a proposed trust-admission candidate through an explicit operator decision. approve re-signs the pending evidence as SAVE and activates the existing row through the verified writer; reject requires rejection_class=drop or block, re-signs the evidence as that terminal class, archives the row, and never serves it. Both transitions are hash-only in the response, record an admission_review_started intent before mutation, and append a completed admission_approved/admission_rejected receipt only after durable transition. Public calls require an initialized clientInfo.name and an enforce-mode memory.admission.review authority for the exact workspace.

Parameters

categorystringrequiredargument

Candidate entity category

decisionstringapproverejectrequiredargument
keystringrequiredargument

Candidate entity key

reasonstringrequiredargument

Bounded non-empty review reason; the response stores only its SHA-256

rejection_classstringdropblockargument

Required when decision=reject

requesting_agent_idstringrequiredargument

Operator/reviewer identity stamped into the audit event

workspace_hashstringrequiredargument

Exact non-empty workspace scope of the candidate

Returns

audit_event_idstring
categorystring
decisionstringapprovereject
idstring
keystring
okboolean
outcome_classstringsavedropblock
reason_sha256string
serveableboolean
statusstring
perseus_vault_admission_decide
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_admission_decide",
    "arguments": {
        "category": "string",
        "decision": "approve",
        "key": "string",
        "reason": "string",
        "rejection_class": "drop",
        "requesting_agent_id": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_admission_decide", {
  "category": "string",
  "decision": "approve",
  "key": "string",
  "reason": "string",
  "rejection_class": "drop",
  "requesting_agent_id": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_admission_decide", arguments={
  "category": "string",
  "decision": "approve",
  "key": "string",
  "reason": "string",
  "rejection_class": "drop",
  "requesting_agent_id": "string",
  "workspace_hash": "string"
})
Response
{
  "audit_event_id": "string",
  "category": "string",
  "decision": "approve",
  "id": "string",
  "key": "string",
  "ok": true,
  "outcome_class": "save",
  "reason_sha256": "string",
  "serveable": true,
  "status": "string"
}

perseus_vault_admission_quarantine

TOOLperseus_vault_admission_quarantine

#1026: review the admission-quarantine hold — candidates disposed as quarantined by trust admission are sealed OUTSIDE the authoritative head (never served by any read surface; storage presence confers no authority). list (default): active candidates with attempt metadata (no bodies); show: full sealed record incl. decrypted body + admission attempt linkage + hash-only receipt; retire: record the review decision (the row is retained so its proposal identifier stays retired); purge: reclaim retired rows and/or active rows past the age watermark (purged proposal identifiers become reusable). Every decision is journaled (admission_quarantined / admission_quarantine_retired / admission_quarantine_purged). Pending items also surface in perseus_vault_operator_review.

Parameters

actionstringlistshowretirepurgelistargument

list (default) | show | retire | purge

idstringargument

Quarantine id (required for show/retire)

include_retiredbooleanfalseargument

list: include retired rows (default active only)

limitinteger<= 1000050argument
max_age_daysinteger[1, 3650]argument

purge: reclaim active rows older than this many days (default 30)

purge_retiredbooleantrueargument

purge: reclaim retired rows (default true)

requesting_agent_idstringargument

Reviewer identity stamped into the journal (default empty)

workspace_hashstringargument

Workspace scope for list (default all)

Returns

countinteger
itemsArray<object>
purgedinteger
retiredboolean
perseus_vault_admission_quarantine
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_admission_quarantine",
    "arguments": {
        "action": "list",
        "id": "string",
        "include_retired": false,
        "limit": 50,
        "max_age_days": 1,
        "purge_retired": true,
        "requesting_agent_id": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_admission_quarantine", {
  "action": "list",
  "id": "string",
  "include_retired": false,
  "limit": 50,
  "max_age_days": 1,
  "purge_retired": true,
  "requesting_agent_id": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_admission_quarantine", arguments={
  "action": "list",
  "id": "string",
  "include_retired": false,
  "limit": 50,
  "max_age_days": 1,
  "purge_retired": true,
  "requesting_agent_id": "string",
  "workspace_hash": "string"
})
Response
{
  "count": 0,
  "items": [
    {}
  ],
  "purged": 0,
  "retired": true
}

perseus_vault_writer_handoff

TOOLperseus_vault_writer_handoff

#1027: epoch-fenced writer handoff — prevent split-brain on concurrent multi-agent writes. Directory-serialized lifecycle actions, each appending a signed lifecycle result (receipt digest): prepare (open the handoff pointer; the source may still advance), abort (clear the pointer; source stays active), fence (clear the writer + advance the epoch — after this NO writer is authorized; a crash in the Fence→Activate gap leaves zero writers, fail-closed), retarget (advance target + epoch; the abandoned target can no longer activate), activate (admission against the exact fenced revision; the current target becomes the active writer, epoch advances again). status: read the directory. Every write (remember) against an active directory must present the current writer_epoch — stale writes fail with a stable StaleRevision / WriterEpoch reason. Workspace-scoped; absent directory = unfenced legacy posture.

Parameters

actionstringprepareabortfenceretargetactivatestatusstatusargument

status (default) | prepare | abort | fence | retarget | activate

presented_epochintegerargument

activate: the fenced epoch the activating agent must present (exact match required)

requesting_agent_idstringargument

Acting identity — activate requires it to equal target_agent_id; stamped into lifecycle receipts

target_agent_idstringargument

Handoff target agent (required for prepare/retarget)

workspace_hashstringargument

Workspace whose writer directory is managed (required except status; must be non-empty)

Returns

directoryobject
epochinteger
lifecycle_leninteger
pointer_statestring
receipt_digeststring
target_agent_idstring
writer_agent_idstring
perseus_vault_writer_handoff
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_writer_handoff",
    "arguments": {
        "action": "status",
        "presented_epoch": 0,
        "requesting_agent_id": "string",
        "target_agent_id": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_writer_handoff", {
  "action": "status",
  "presented_epoch": 0,
  "requesting_agent_id": "string",
  "target_agent_id": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_writer_handoff", arguments={
  "action": "status",
  "presented_epoch": 0,
  "requesting_agent_id": "string",
  "target_agent_id": "string",
  "workspace_hash": "string"
})
Response
{
  "directory": {},
  "epoch": 0,
  "lifecycle_len": 0,
  "pointer_state": "string",
  "receipt_digest": "string",
  "target_agent_id": "string",
  "writer_agent_id": "string"
}

perseus_vault_impact_report

TOOLperseus_vault_impact_report

#1029: supersession impact index — when a fact is superseded or retracted, enumerate the downstream decisions and actions that derived from it (reverse closure over derived_from citations + action justifications). Lists dependent entities ordered by authority (importance) + recency, flags PENDING actions whose cited justification changed (AAR review flag — re-validate freshness before execution), and lists COMPLETED actions for review (external effects are irreversible — flag only, never automatic reversal). Bounded closure: depth_cap (1..16, default 3), age_cap_days (default 365); as_of_unix_ms computes the report at a past transaction instant (v1 filters by dependent creation time; full bi-temporal closure via entity_history is a documented follow-on). Computed lazily at read time.

Parameters

age_cap_daysinteger[1, 36500]365argument

Ignore dependents older than this many days

as_of_unix_msintegerargument

Compute the report as of this transaction instant (default: now)

categorystringargument

The changed fact's category (with key; alternative to entity_id)

depth_capinteger[1, 16]3argument

Max closure depth (transitive derived_from hops)

entity_idstringargument

The changed fact's id (alternative to category+key)

keystringargument

The changed fact's key (with category; alternative to entity_id)

Returns

bounded_closureobject
completed_actionsArray<object>
dependentsArray<object>
pending_actionsArray<object>
targetobject
perseus_vault_impact_report
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_impact_report",
    "arguments": {
        "age_cap_days": 365,
        "as_of_unix_ms": 0,
        "category": "string",
        "depth_cap": 3,
        "entity_id": "string",
        "key": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_impact_report", {
  "age_cap_days": 365,
  "as_of_unix_ms": 0,
  "category": "string",
  "depth_cap": 3,
  "entity_id": "string",
  "key": "string"
});
result = await session.call_tool("perseus_vault_impact_report", arguments={
  "age_cap_days": 365,
  "as_of_unix_ms": 0,
  "category": "string",
  "depth_cap": 3,
  "entity_id": "string",
  "key": "string"
})
Response
{
  "bounded_closure": {},
  "completed_actions": [
    {}
  ],
  "dependents": [
    {}
  ],
  "pending_actions": [
    {}
  ],
  "target": {}
}

perseus_vault_finding_record

TOOLperseus_vault_finding_record

#1033: record an authenticated impact finding — the durable, receipted admission record a detection pass produces about a superseded/retracted fact (the supersession impact index surface is the read side; this is the write side compensation intents cite). A finding is detection output, NEVER a decision: it cannot self-trigger execution; the disposition (accept-drift / revalidate-pending / open-compensation-case / escalate) is chosen by the authority plane. Compensation intents (action_intent with compensates_for) must cite a finding_ref whose covers list includes the compensated effect and whose cited_head matches the presented superseding_head — fail-closed, stable compensation_* reason codes. covered effects must reference existing action receipts; (category,key) or entity_id targets the changed fact.

Parameters

agent_idstringargument

Recording agent identity (stamped into the journal)

basisstringargument

Why the finding exists (e.g. 'supersession', 'retraction')

categorystringargument

Changed fact's category (with key; alternative to entity_id)

cited_headstringrequiredargument

Exact superseding head that invalidated the original justification (required)

coversArray<string>argument

Original effect/action receipt ids this finding covers (each must exist)

entity_idstringargument

Changed fact's entity id (alternative to category+key)

finding_refstringrequiredargument

Stable caller-facing reference, unique per workspace

keystringargument

Changed fact's key (with category; alternative to entity_id)

workspace_hashstringargument

Workspace the finding belongs to

Returns

archivedboolean
cited_headstring
coversArray<string>
created_at_unix_msinteger
finding_refstring
idstring
statusstring
perseus_vault_finding_record
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_finding_record",
    "arguments": {
        "agent_id": "string",
        "basis": "string",
        "category": "string",
        "cited_head": "string",
        "covers": [
          "string"
        ],
        "entity_id": "string",
        "finding_ref": "string",
        "key": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_finding_record", {
  "agent_id": "string",
  "basis": "string",
  "category": "string",
  "cited_head": "string",
  "covers": [
    "string"
  ],
  "entity_id": "string",
  "finding_ref": "string",
  "key": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_finding_record", arguments={
  "agent_id": "string",
  "basis": "string",
  "category": "string",
  "cited_head": "string",
  "covers": [
    "string"
  ],
  "entity_id": "string",
  "finding_ref": "string",
  "key": "string",
  "workspace_hash": "string"
})
Response
{
  "archived": true,
  "cited_head": "string",
  "covers": [
    "string"
  ],
  "created_at_unix_ms": 0,
  "finding_ref": "string",
  "id": "string",
  "status": "string"
}

perseus_vault_grounding_admit

TOOLperseus_vault_grounding_admit

#1034: admit a deterministic grounding fingerprint for evidence grounded to a file/symbol. Captures a K=64 seeded-sha256 trigram MinHash + neighbor set at admission (zero LLM, reproducible). Fail-closed authoring rule: if trustworthy ground facts are unavailable, stop and report it — never invent node ids or fingerprints. The agent supplies the grounded content; the vault never fetches. Re-admission refreshes the baseline with an appended provenance trail (never silent last-write-wins).

Parameters

contentstringrequiredargument

The grounded source content at admission (agent-supplied; bounded)

entity_idstringrequiredargument

Evidence entity the grounding anchors (must exist)

kindstringfilesymbolargument

What target_ref names

target_refstringrequiredargument

File path or symbol reference the evidence is grounded to

workspace_hashstringargument

Workspace the grounding belongs to

Returns

baseline_digeststring
captured_at_unix_msinteger
fingerprint_hexstring
idstring
statusstring
target_refstring
perseus_vault_grounding_admit
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_grounding_admit",
    "arguments": {
        "content": "string",
        "entity_id": "string",
        "kind": "file",
        "target_ref": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_grounding_admit", {
  "content": "string",
  "entity_id": "string",
  "kind": "file",
  "target_ref": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_grounding_admit", arguments={
  "content": "string",
  "entity_id": "string",
  "kind": "file",
  "target_ref": "string",
  "workspace_hash": "string"
})
Response
{
  "baseline_digest": "string",
  "captured_at_unix_ms": 0,
  "fingerprint_hex": "string",
  "id": "string",
  "status": "string",
  "target_ref": "string"
}

perseus_vault_grounding_reconcile

TOOLperseus_vault_grounding_reconcile

#1034: reconcile admitted groundings against a current-content scan (agent-supplied target_ref/content pairs). Deterministic, zero LLM: identical digest → ok; exists-but-changed → GROUNDING_DRIFT; reconcile score (0.7×minhashJaccard + 0.3×neighborOverlap, HI 0.85 / LO 0.55) → MOVED (auto-rewrite anchor + migrate baseline with a provenance trail) / GONE (flag for review) / AMBIGUOUS (surface candidates for operator review).

Body

application/json
currentArray<object>

Current content scan: target_ref + content pairs

Show child attributes
contentstring
target_refstring
workspace_hashstring

Workspace to reconcile

Returns

ambiguousinteger
checkedinteger
driftinteger
goneinteger
issuesArray<object>
movedinteger
notestring
okinteger
perseus_vault_grounding_reconcile
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_grounding_reconcile",
    "arguments": {
        "current": [
          {
            "content": "string",
            "target_ref": "string"
          }
        ],
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_grounding_reconcile", {
  "current": [
    {
      "content": "string",
      "target_ref": "string"
    }
  ],
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_grounding_reconcile", arguments={
  "current": [
    {
      "content": "string",
      "target_ref": "string"
    }
  ],
  "workspace_hash": "string"
})
Request Body
{
  "current": [
    {
      "content": "string",
      "target_ref": "string"
    }
  ],
  "workspace_hash": "string"
}
Response
{
  "ambiguous": 0,
  "checked": 0,
  "drift": 0,
  "gone": 0,
  "issues": [
    {}
  ],
  "moved": 0,
  "note": "string",
  "ok": 0
}

perseus_vault_drift_check

TOOLperseus_vault_drift_check

#1035: deterministic drift-check pre-pass over the store (zero LLM in detection): REFERENCE_INTEGRITY (dangling derived_from citations), GROUNDING_STATUS (drift/gone/ambiguous fingerprints), PATH_EXISTENCE (missing grounded files), CROSS_FILE_CONFLICT (two evidence entities asserting different values for the same keyed claim), STALE_ENTITY (stale vs last-access threshold). Health score = 100 − (10×error + 3×warning + 1×info). Repair scope = flagged items only (perseus_vault_drift_repair).

Parameters

staleness_daysinteger[1, 3650]90argument

Staleness threshold in days

workspace_hashstringargument

Optional workspace scope

Returns

checker_countsobject
errorsinteger
health_scoreinteger
infosinteger
issuesArray<object>
notestring
warningsinteger
perseus_vault_drift_check
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_drift_check",
    "arguments": {
        "staleness_days": 90,
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_drift_check", {
  "staleness_days": 90,
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_drift_check", arguments={
  "staleness_days": 90,
  "workspace_hash": "string"
})
Response
{
  "checker_counts": {},
  "errors": 0,
  "health_score": 0,
  "infos": 0,
  "issues": [
    {}
  ],
  "note": "string",
  "warnings": 0
}

perseus_vault_drift_repair

TOOLperseus_vault_drift_repair

#1035: targeted repair + verify leg of the drift loop. Mechanical fixes only: unlink dangling derived_from references (journaled), acknowledge grounding findings. Contradictions, staleness, and missing files are never auto-resolved — they land in requires_review for the operator queue. Re-runs the check and reports the before/after health-score delta; a repair that regresses the score is refused fail-closed.

Parameters

staleness_daysinteger[1, 3650]90argument

Staleness threshold in days

workspace_hashstringargument

Optional workspace scope

Returns

after_scoreinteger
before_scoreinteger
notestring
repairedArray<string>
requires_reviewArray<string>
perseus_vault_drift_repair
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_drift_repair",
    "arguments": {
        "staleness_days": 90,
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_drift_repair", {
  "staleness_days": 90,
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_drift_repair", arguments={
  "staleness_days": 90,
  "workspace_hash": "string"
})
Response
{
  "after_score": 0,
  "before_score": 0,
  "note": "string",
  "repaired": [
    "string"
  ],
  "requires_review": [
    "string"
  ]
}

perseus_vault_restore_forward

TOOLperseus_vault_restore_forward

#1028: forward-only restoration — restore from a checkpoint directory as an audited VERSION ADVANCE of the current head, never as a rewrite. Each checkpoint entity advances its (category, key, workspace) identity: the pre-restore version moves to entity_history (the parent; a rollback is just another forward migration) and the checkpoint body becomes the new head. Protected authority paths always take CURRENT values — authority, policy, revocation, issuer, writer, epoch, dirSeq/lifecycle, createdFrom/provenance are excluded from the mask (M ∩ P = ∅; only entities is maskable in v1), so a restore can never revive a stale credential, resurrect a superseded authority, or undo a recorded external effect (authorized actions untouched). Workspace-scoped; an active writer directory (#1027) requires the current writer_epoch. Report: restored / superseded_current_heads / created / errors.

Parameters

checkpoint_dirstringargument

Directory of vault-format .md files (the vault_export wire shape)

path_maskArray<string>entitiesargument

State paths to restore (only entities in v1; protected paths are refused fail-closed)

requesting_agent_idstringargument

Acting identity stamped into the journal

workspace_hashstringargument

Workspace to restore into (required)

writer_epochintegerargument

Required when the workspace has an active writer directory (#1027)

Returns

createdinteger
errorsArray<string>
protected_pathsArray<string>
restoredinteger
superseded_current_headsinteger
perseus_vault_restore_forward
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_restore_forward",
    "arguments": {
        "checkpoint_dir": "string",
        "path_mask": [
          "entities"
        ],
        "requesting_agent_id": "string",
        "workspace_hash": "string",
        "writer_epoch": 0
      }
  }
}
const result = await client.callTool("perseus_vault_restore_forward", {
  "checkpoint_dir": "string",
  "path_mask": [
    "entities"
  ],
  "requesting_agent_id": "string",
  "workspace_hash": "string",
  "writer_epoch": 0
});
result = await session.call_tool("perseus_vault_restore_forward", arguments={
  "checkpoint_dir": "string",
  "path_mask": [
    "entities"
  ],
  "requesting_agent_id": "string",
  "workspace_hash": "string",
  "writer_epoch": 0
})
Response
{
  "created": 0,
  "errors": [
    "string"
  ],
  "protected_paths": [
    "string"
  ],
  "restored": 0,
  "superseded_current_heads": 0
}

perseus_vault_op_run

TOOLperseus_vault_op_run

#871: durable long-running operation states. Lifecycle tool for the shared run/run-item contract (maintenance, embed, consolidation, export/import, reindex). Actions: begin (queued; requires op_type, optional scope/input_digest/max_retries 0..10/created_by), start (queued->running), progress (done/failed/total counters; partial derived), complete (running->completed with receipt linkage), fail (running->failed; error_detail is sanitized at rest — secrets masked, length capped), failed_to_start (queued->failed_to_start), cancel (queued|running->cancelled), timeout (running->failed with timeout flag), item_add/item_start/item_complete/item_fail/item_cancel (per-item receipts; UNIQUE(run_id, item_ref)). Terminal states accept no further transitions. Restart recovery marks in-flight runs interrupted (mark-only); resume only via perseus_vault_op_run_retry.

Parameters

actionstringbeginstartprogresscompletefailfailed_to_startcanceltimeoutitem_additem_startitem_completeitem_failitem_cancelbeginargument

Lifecycle action

created_bystringargument

Caller identity for begin

doneintegerargument

progress: items completed

error_classstringargument

fail/item_fail: error class

error_detailstringargument

fail/item_fail: detail (sanitized at rest)

failedintegerargument

progress: items failed

input_digeststringargument

sha256 of the input reference set (idempotency anchor)

item_digeststringargument

item_add: item digest

item_refstringargument

item ops: item reference (entity id / file path / ordinal)

max_retriesinteger[0, 10]2argument
op_typestringargument

Operation kind for begin: consolidate|embed_flush|export|import|decay|maintain|reindex|cohere|compact|custom

receiptstringargument

complete: terminal receipt linkage (journal event id / artifact ref)

receipt_refstringargument

item_complete: per-item receipt linkage

run_idstringargument

Run id (opr-...) for all actions except begin

scopestringargument

Workspace hash or empty for global

totalintegerargument

progress: expected items (omit to keep stored total)

Returns

idstring
statestring
perseus_vault_op_run
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_op_run",
    "arguments": {
        "action": "begin",
        "created_by": "string",
        "done": 0,
        "error_class": "string",
        "error_detail": "string",
        "failed": 0,
        "input_digest": "string",
        "item_digest": "string",
        "item_ref": "string",
        "max_retries": 2,
        "op_type": "string",
        "receipt": "string",
        "receipt_ref": "string",
        "run_id": "string",
        "scope": "string",
        "total": 0
      }
  }
}
const result = await client.callTool("perseus_vault_op_run", {
  "action": "begin",
  "created_by": "string",
  "done": 0,
  "error_class": "string",
  "error_detail": "string",
  "failed": 0,
  "input_digest": "string",
  "item_digest": "string",
  "item_ref": "string",
  "max_retries": 2,
  "op_type": "string",
  "receipt": "string",
  "receipt_ref": "string",
  "run_id": "string",
  "scope": "string",
  "total": 0
});
result = await session.call_tool("perseus_vault_op_run", arguments={
  "action": "begin",
  "created_by": "string",
  "done": 0,
  "error_class": "string",
  "error_detail": "string",
  "failed": 0,
  "input_digest": "string",
  "item_digest": "string",
  "item_ref": "string",
  "max_retries": 2,
  "op_type": "string",
  "receipt": "string",
  "receipt_ref": "string",
  "run_id": "string",
  "scope": "string",
  "total": 0
})
Response
{
  "id": "string",
  "state": "string"
}

perseus_vault_op_run_list

TOOLperseus_vault_op_run_list

#871: list durable operation runs, newest first. Optional state filter (queued|running|completed|failed|cancelled|interrupted|failed_to_start) and op_type filter; bounded limit (1..=100, default 20).

Parameters

limitinteger[1, 100]20argument
op_typestringargument

Optional operation-kind filter

statestringargument

Optional terminal-state filter

Returns

countinteger
runsArray<object>
perseus_vault_op_run_list
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_op_run_list",
    "arguments": {
        "limit": 20,
        "op_type": "string",
        "state": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_op_run_list", {
  "limit": 20,
  "op_type": "string",
  "state": "string"
});
result = await session.call_tool("perseus_vault_op_run_list", arguments={
  "limit": 20,
  "op_type": "string",
  "state": "string"
})
Response
{
  "count": 0,
  "runs": [
    {}
  ]
}

perseus_vault_op_run_get

TOOLperseus_vault_op_run_get

#871: fetch one durable operation run with its per-item receipts.

Parameters

run_idstringrequiredargument

Run id (opr-...)

Returns

itemsArray<object>
runobject
perseus_vault_op_run_get
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_op_run_get",
    "arguments": {
        "run_id": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_op_run_get", {
  "run_id": "string"
});
result = await session.call_tool("perseus_vault_op_run_get", arguments={
  "run_id": "string"
})
Response
{
  "items": [
    {}
  ],
  "run": {}
}

perseus_vault_op_run_retry

TOOLperseus_vault_op_run_retry

#871: bounded, scoped, idempotent retry of a TERMINAL run. Forks a NEW child run re-queuing only failed/cancelled/interrupted/unattempted items; completed items are carried into the child with their receipts (never re-executed — retry cannot duplicate writes or receipts). Refused fail-closed on retry exhaustion (retry_count >= max_retries) or when nothing is recoverable.

Parameters

run_idstringrequiredargument

Terminal run id to retry

Returns

child_run_idstring
retried_fromstring
retry_countinteger
statestring
perseus_vault_op_run_retry
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_op_run_retry",
    "arguments": {
        "run_id": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_op_run_retry", {
  "run_id": "string"
});
result = await session.call_tool("perseus_vault_op_run_retry", arguments={
  "run_id": "string"
})
Response
{
  "child_run_id": "string",
  "retried_from": "string",
  "retry_count": 0,
  "state": "string"
}

perseus_vault_op_run_prune

TOOLperseus_vault_op_run_prune

#871: retention prune of TERMINAL runs older than retention_days (min 1, default PERSEUS_VAULT_OP_RETENTION_DAYS=30) plus their items. In-flight runs are never pruned. maintain runs a prune pass each cycle.

Parameters

retention_daysinteger>= 1argument

Retention bound (default env PERSEUS_VAULT_OP_RETENTION_DAYS, 30)

Returns

prunedinteger
retention_daysinteger
perseus_vault_op_run_prune
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_op_run_prune",
    "arguments": {
        "retention_days": 1
      }
  }
}
const result = await client.callTool("perseus_vault_op_run_prune", {
  "retention_days": 1
});
result = await session.call_tool("perseus_vault_op_run_prune", arguments={
  "retention_days": 1
})
Response
{
  "pruned": 0,
  "retention_days": 0
}

perseus_vault_preload_resolve

TOOLperseus_vault_preload_resolve

#875: resolve open preload usage events into per-session precision/recall. Events older than the usage window are marked used/unused from entity read activity (serving itself never counts), then folded into preload_sessions. window_minutes defaults to 30. Telemetry bookkeeping only — never touches entity bodies.

Parameters

window_minutesintegerargument

Session usage window in minutes (default 30).

Returns

events_resolvedinteger
sessions_writteninteger
window_minutesinteger
perseus_vault_preload_resolve
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_preload_resolve",
    "arguments": {
        "window_minutes": 0
      }
  }
}
const result = await client.callTool("perseus_vault_preload_resolve", {
  "window_minutes": 0
});
result = await session.call_tool("perseus_vault_preload_resolve", arguments={
  "window_minutes": 0
})
Response
{
  "events_resolved": 0,
  "sessions_written": 0,
  "window_minutes": 0
}

perseus_vault_preload_stats

TOOLperseus_vault_preload_stats

#875: read-only preload usage telemetry — which preloaded memories actually got used. Per-trigger precision/recall (separate from #872 serving-concentration), per-session rows, or overall aggregates. Usage = the entity was touched after serving (read paths only; serving itself never counts). Run this before perseus_vault_preload_propose to see the evidence behind tuning proposals.

Parameters

limitinteger50argument

Max rows for trigger/session scopes (1-1000)

scopestringoveralltriggersessionoverallargument

'trigger': per recall_when trigger precision (used/served) + recall (used/(used+missed-by-trigger)); 'session': per-session precision/recall/miss_rate rows; 'overall': aggregate summary.

since_daysinteger7argument

Only events/sessions at least this recent (0 = all)

Returns

object
perseus_vault_preload_stats
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_preload_stats",
    "arguments": {
        "limit": 50,
        "scope": "overall",
        "since_days": 7
      }
  }
}
const result = await client.callTool("perseus_vault_preload_stats", {
  "limit": 50,
  "scope": "overall",
  "since_days": 7
});
result = await session.call_tool("perseus_vault_preload_stats", arguments={
  "limit": 50,
  "scope": "overall",
  "since_days": 7
})
Response
{}

perseus_vault_preload_propose

TOOLperseus_vault_preload_propose

#875: offline trigger-tuning pass. From resolved usage history, raises PENDING proposals: retire for triggers served >= PERSEUS_VAULT_PRELOAD_MIN_SERVED (3) with precision < PERSEUS_VAULT_PRELOAD_RETIRE_PRECISION (0.25); add_trigger for entities used in >= 2 sessions but never preloaded (word from the sessions' contexts). Proposals write ONLY the proposals table (journaled); entity mutations happen exclusively via perseus_vault_preload_review approve — never silently.

Parameters

bystringoperatorargument

Agent id recorded as the proposal author

Returns

object
perseus_vault_preload_propose
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_preload_propose",
    "arguments": {
        "by": "operator"
      }
  }
}
const result = await client.callTool("perseus_vault_preload_propose", {
  "by": "operator"
});
result = await session.call_tool("perseus_vault_preload_propose", arguments={
  "by": "operator"
})
Response
{}

perseus_vault_preload_review

TOOLperseus_vault_preload_review

#875: operator review queue for preload trigger tuning — the ONLY mutation surface. 'approve' applies the proposal through the audited remember path (journal preload_tuning_applied + entity_history provenance, revision bump): retire removes the trigger from the entity's recall_when (others untouched); add_trigger appends the proposed word. 'dismiss' records the decision without mutating anything. Both are journaled with the operator id.

Parameters

actionstringlistapprovedismisslistargument

'list': pending proposals with rationale; 'approve': apply proposal_id; 'dismiss': decline proposal_id with a reason.

bystringoperatorargument

Agent id recorded as the decision maker

limitinteger50argument

Max proposals for list (1-1000)

proposal_idstringargument

Proposal id (required for approve/dismiss)

reasonstringargument

Dismissal reason (dismiss only)

Returns

object
perseus_vault_preload_review
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_preload_review",
    "arguments": {
        "action": "list",
        "by": "operator",
        "limit": 50,
        "proposal_id": "string",
        "reason": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_preload_review", {
  "action": "list",
  "by": "operator",
  "limit": 50,
  "proposal_id": "string",
  "reason": "string"
});
result = await session.call_tool("perseus_vault_preload_review", arguments={
  "action": "list",
  "by": "operator",
  "limit": 50,
  "proposal_id": "string",
  "reason": "string"
})
Response
{}

perseus_vault_guide_seed

TOOLperseus_vault_guide_seed

#924: seed (create or refresh) the vault operating guide — a 'how to use this vault' manual living as a discoverable entity (category 'guide', key 'vault-operating-guide') with recall_when triggers ('operating guide', ...). Session context blocks then emit a one-line pointer instead of inlining operating instructions; agents retrieve the full guide on demand via normal recall. Idempotent: re-seeding updates in place, never duplicates. Advisory metadata only — never gates writes.

Parameters

workspace_hashstringargument

Workspace scope for the guide entity (empty = global).

Returns

actionstring
categorystring
idstring
keystring
perseus_vault_guide_seed
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_guide_seed",
    "arguments": {
        "workspace_hash": ""
      }
  }
}
const result = await client.callTool("perseus_vault_guide_seed", {
  "workspace_hash": ""
});
result = await session.call_tool("perseus_vault_guide_seed", arguments={
  "workspace_hash": ""
})
Response
{
  "action": "string",
  "category": "string",
  "id": "string",
  "key": "string"
}

Declare Category Retrieval Contract

TOOLperseus_vault_declared_schema_set

#923: declare (or replace) the typed retrieval contract for a category — the deterministic exact-match arm. Fields are typed ('scalar' = exact string equality, 'string_list' = array membership) and may be facet-eligible. Advisory retrieval metadata only: never gates writes. Fail-closed validation: unknown field types, duplicate/empty names, reserved names (id/category/key/recall_when/origin/external_refs/expires_at), >32 fields, >16 facets, or >500-byte query_guidance are errors. Re-declaring bumps the schema version; exact-match queries then follow the new contract.

Body

application/json
categorystringrequired

Category this contract describes (may not be a reserved category)

fieldsArray<object>required

1-32 typed fields. Values are read from each entity's top-level body_json keys at query time.

Show child attributes
facetbooleanfalse
namestringrequired
typestringscalarstring_listrequired
query_guidancestring

Advisory: how agents should query this category (returned by declared_query). Max 500 bytes.

Returns

categorystring
fieldsarray
okboolean
query_guidancestring
versioninteger
Declare Category Retrieval Contract
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_declared_schema_set",
    "arguments": {
        "category": "string",
        "fields": [
          {
            "facet": false,
            "name": "string",
            "type": "scalar"
          }
        ],
        "query_guidance": ""
      }
  }
}
const result = await client.callTool("perseus_vault_declared_schema_set", {
  "category": "string",
  "fields": [
    {
      "facet": false,
      "name": "string",
      "type": "scalar"
    }
  ],
  "query_guidance": ""
});
result = await session.call_tool("perseus_vault_declared_schema_set", arguments={
  "category": "string",
  "fields": [
    {
      "facet": false,
      "name": "string",
      "type": "scalar"
    }
  ],
  "query_guidance": ""
})
Request Body
{
  "category": "string",
  "fields": [
    {
      "facet": false,
      "name": "string",
      "type": "scalar"
    }
  ],
  "query_guidance": ""
}
Response
{
  "category": "string",
  "fields": [],
  "ok": true,
  "query_guidance": "string",
  "version": 0
}

Declared Exact-Match Query

TOOLperseus_vault_declared_query

#923: deterministic exact-match retrieval over a declared category — the no-ranking arm. Filters are AND-combined exact-equality checks against the category's declared schema: scalar fields match by exact string equality, string_list fields by array membership. Results come back in deterministic order (created_at ASC, id ASC). Facet counts are truthful and bounded (top 50 distinct values per facet, remainder rolled into 'other'). Fail-closed: undeclared categories, unknown fields, malformed filters, or non-facet facet requests are errors — never degraded to fuzzy recall.

Parameters

categorystringrequiredargument

Category with a declared schema (perseus_vault_declared_schema_set)

facetsArray<string>argument

Facet-eligible fields to count (top 50 distinct values + 'other' bucket)

filtersobjectargument

Exact-equality filters (AND-combined). Scalar field: string value to equal. String-list field: array of strings, any of which must be present.

limitinteger10argument
offsetinteger0argument
requesting_agent_idstringargument

Transport-stamped requester identity used for item and facet visibility enforcement.

workspace_hashstringargument

Returns

categorystring
facet_countsobject
itemsarray
okboolean
schemaobject
total_matchesinteger
truncatedboolean
Declared Exact-Match Query
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_declared_query",
    "arguments": {
        "category": "string",
        "facets": [
          "string"
        ],
        "filters": {},
        "limit": 10,
        "offset": 0,
        "requesting_agent_id": "string",
        "workspace_hash": ""
      }
  }
}
const result = await client.callTool("perseus_vault_declared_query", {
  "category": "string",
  "facets": [
    "string"
  ],
  "filters": {},
  "limit": 10,
  "offset": 0,
  "requesting_agent_id": "string",
  "workspace_hash": ""
});
result = await session.call_tool("perseus_vault_declared_query", arguments={
  "category": "string",
  "facets": [
    "string"
  ],
  "filters": {},
  "limit": 10,
  "offset": 0,
  "requesting_agent_id": "string",
  "workspace_hash": ""
})
Response
{
  "category": "string",
  "facet_counts": {},
  "items": [],
  "ok": true,
  "schema": {},
  "total_matches": 0,
  "truncated": true
}

Detect Conflicting Entities

TOOLperseus_vault_conflicts

Detect conflicting entities in the same category — pairs with low trigram similarity in their body_json. Flags potential contradictions, duplicate-but-divergent entries, and stale-overwritten facts. Read-only by default. Opt in with resolve=true to actively invalidate the lower-certainty side of clear conflicts (superseding it into history, reversible + time-travelable via perseus_vault_as_of); that path defaults to dry_run=true so you preview first, and never resolves pairs whose certainties are within certainty_margin.

Parameters

categorystringgeneralrequiredargument

Category to scan for conflicts

certainty_marginnumber0.2argument

Minimum certainty gap to auto-resolve; closer pairs are skipped as ambiguous

dry_runbooleantrueargument

When resolve=true, only report what would be invalidated unless set false

limitinteger10argument

Maximum number of conflicts to return / resolve

offsetinteger0argument

Number of entities to skip for pagination

resolvebooleanfalseargument

Opt-in: invalidate the lower-certainty side of clear conflicts instead of only reporting them

thresholdnumber0.4argument

Similarity threshold — pairs below this are flagged as conflicts

Returns

conflictsArray<object>

Conflict pairs with similarity scores (detection mode)

invalidationsArray<object>

Winner/loser pairs invalidated or previewed (resolve mode)

Detect Conflicting Entities
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_conflicts",
    "arguments": {
        "category": "general",
        "certainty_margin": 0.2,
        "dry_run": true,
        "limit": 10,
        "offset": 0,
        "resolve": false,
        "threshold": 0.4
      }
  }
}
const result = await client.callTool("perseus_vault_conflicts", {
  "category": "general",
  "certainty_margin": 0.2,
  "dry_run": true,
  "limit": 10,
  "offset": 0,
  "resolve": false,
  "threshold": 0.4
});
result = await session.call_tool("perseus_vault_conflicts", arguments={
  "category": "general",
  "certainty_margin": 0.2,
  "dry_run": true,
  "limit": 10,
  "offset": 0,
  "resolve": false,
  "threshold": 0.4
})
Response
{
  "conflicts": [
    {}
  ],
  "invalidations": [
    {}
  ]
}

perseus_vault_maintenance_status

TOOLperseus_vault_maintenance_status

#952: read-only maintenance/serving isolation observability. Reports the off-peak maintenance window (configured value, whether it is open now, parse errors), the live-recall SLO budget (PERSEUS_VAULT_MAINTENANCE_P95_BUDGET_MS, last probe latency), the execution-slot state (one maintenance run at a time; held = an operator-explicit run is executing), and lifetime counters (runs started / refused by the gate / mid-run SLO pauses). Maintenance is serialized, never reserved (a disabled mode consumes zero capacity), and gated by window+budget unless force:true — see docs/specs/maintenance-serving-isolation.md.

Returns

countersobject

Lifetime counters: runs_started, runs_refused (gate refusals), slo_pauses (mid-run pauses).

lockobject

Execution slot: held (bool) and the operation holding it, if any.

sloobject

Live-recall SLO budget ms (PERSEUS_VAULT_MAINTENANCE_P95_BUDGET_MS; null = guard off) and the last measured recall probe latency.

windowobject

Configured off-peak window (PERSEUS_VAULT_MAINTENANCE_WINDOW, UTC HH:MM-HH:MM), whether it is open now, and any parse error (malformed config fails closed).

perseus_vault_maintenance_status
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_maintenance_status",
    "arguments": {}
  }
}
const result = await client.callTool("perseus_vault_maintenance_status", {});
result = await session.call_tool("perseus_vault_maintenance_status", arguments={})
Response
{
  "counters": {},
  "lock": {},
  "slo": {},
  "window": {}
}

Consolidate Overlapping Facts into Observations

TOOLperseus_vault_consolidate

Merge overlapping/duplicative entities in the same category into durable, evidence-tracked 'observations' — the mirror image of perseus_vault_conflicts, which flags dissimilar (contradictory) pairs. Groups entities whose pairwise trigram similarity meets similarity_threshold, then creates one new entity per group (category='observation') whose body carries a summary (the highest-certainty source's content), exact-quote evidence refs (source id + verbatim quote, capped by quote_cap_chars), the full list of source entity ids as evidence, a proof_count, updated_at, a staleness flag, and (on contradiction) a preserved journey in history. The observation links back to each source (relationship='evidence_for') for full audit. #884: with refine_existing (default true), new evidence FOLDS into the best-matching existing observation (proof_count grows, no duplicates) and contradictions reconcile into its journey — 'was React, switched to Vue' — with raw facts intact for trace-back; fold/refine writes go through the audited re-assert path (entity_history snapshot). A staleness refresh pass marks observations stale when newer unconsolidated facts exist. By default sources stay live; set archive_sources=true to retire merged sources of FRESHLY CREATED observations only ('local dreaming' — verified or importance-floored sources are never archived), and cold_first=true to target the memories decay is about to claim. perseus_vault_autocohere runs a bounded cold_first+archive_sources pass automatically. Read-only preview with dry_run=true.

Parameters

archive_sourcesbooleanfalseargument

Archive merged source entities after the observation is created (archive_reason names the observation; reversible). Verified or importance-floored sources are never archived.

categorystringrequiredargument

Category to scan for overlapping/duplicative entities to consolidate

cold_firstbooleanfalseargument

Scan the COLDEST entities first (longest since last access) instead of the most recent — compress memories that are fading anyway, before decay archives them individually

dry_runbooleanfalseargument

Preview which observations would be created without writing anything

globalbooleanfalseargument

#854 explicit cross-workspace mode for deliberate whole-vault consolidation. Capability-gated (memory.maintenance.global) when the caller carries a host identity. Mutually exclusive with workspace_hash.

limitinteger50argument

Maximum number of observations to create

offsetinteger0argument

Number of entities to skip for pagination

quote_cap_charsinteger[64, 4096]512argument

#884: cap for exact-quote evidence refs (chars). Quotes are each source's note verbatim, truncated at the cap with an ellipsis marker.

refine_existingbooleantrueargument

#884: fold new evidence into existing observations instead of creating duplicates. Near-duplicate clusters/singletons update the matched observation (proof_count, quotes, updated_at); contradictions are reconciled into its journey (history) rather than blindly overwritten. Folded evidence is never archived.

requesting_agent_idstringargument

Host identity stamped by the MCP transport. Used for global-mode authorization and stamped as author on derived observations.

similarity_thresholdnumber0.6argument

Trigram similarity threshold at or above which two entities are considered overlapping enough to merge

workspace_hashstringargument

#854 workspace scope for this run. Scans, clusters, evidence links, and archive operations are strictly restricted to this workspace, and derived observations inherit it. Mutually exclusive with global=true. One of workspace_hash or global is required.

Returns

categorystring
dry_runboolean
entities_examinedinteger

Number of entities scanned in this category

globalboolean

#854 true when this run deliberately crossed all workspaces

observationsArray<object>

The observations created (or previewed), each with entity_id, key, summary, source_ids, proof_count, certainty

observations_createdinteger

Number of new observation entities created (or would be, in dry-run)

source_entities_mergedinteger

Total count of source entities folded into the created observations

sources_archivedinteger

Sources archived because archive_sources was set (verified/importance-floored sources are exempt)

workspace_hashstring | null

#854 effective scope: the workspace this run operated in (null when global=true)

Consolidate Overlapping Facts into Observations
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_consolidate",
    "arguments": {
        "archive_sources": false,
        "category": "string",
        "cold_first": false,
        "dry_run": false,
        "global": false,
        "limit": 50,
        "offset": 0,
        "quote_cap_chars": 512,
        "refine_existing": true,
        "requesting_agent_id": "",
        "similarity_threshold": 0.6,
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_consolidate", {
  "archive_sources": false,
  "category": "string",
  "cold_first": false,
  "dry_run": false,
  "global": false,
  "limit": 50,
  "offset": 0,
  "quote_cap_chars": 512,
  "refine_existing": true,
  "requesting_agent_id": "",
  "similarity_threshold": 0.6,
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_consolidate", arguments={
  "archive_sources": false,
  "category": "string",
  "cold_first": false,
  "dry_run": false,
  "global": false,
  "limit": 50,
  "offset": 0,
  "quote_cap_chars": 512,
  "refine_existing": true,
  "requesting_agent_id": "",
  "similarity_threshold": 0.6,
  "workspace_hash": "string"
})
Response
{
  "category": "string",
  "dry_run": true,
  "entities_examined": 0,
  "global": true,
  "observations": [
    {}
  ],
  "observations_created": 0,
  "source_entities_merged": 0,
  "sources_archived": 0,
  "workspace_hash": "string"
}

Sleep-Cycle Consolidation (Proposal-Only Pass)

TOOLperseus_vault_sleep

#1002: bounded sleep-cycle consolidation without an LLM (CogniCore SleepProcessor borrow). One bounded scan of a category (max_entities, #952 window discipline + maintenance gate) produces PROPOSALS, never silent changes: (1) dedup — pairs at/above similarity_threshold become merge proposals; (2) contradiction — pairs with token overlap PLUS a negation word ('X works' vs 'X does not work') become conflict proposals; (3) optional compression — delegates to perseus_vault_consolidate (cold_first) so fading memories are compressed into evidence-linked observations (the only auto-committed artifact; verified/scored sources exempt). Proposals persist under sleep_proposal.* state keys and surface as the 'sleep' lane of perseus_vault_operator_review for explicit operator decisions. dry_run=true performs the identical work with zero writes.

Parameters

categorystringrequiredargument

Category to scan. The curated mental_model category is refused (curated-only).

dry_runbooleanfalseargument

Preview: identical scan and report, zero persisted proposals, zero compression writes

forcebooleanfalseargument

#952: explicit operator trigger — bypasses the maintenance off-peak window and the live-recall SLO start gate (mid-run pauses still apply).

globalbooleanfalseargument

#854 deliberate whole-vault mode, capability-gated. Mutually exclusive with workspace_hash.

include_compressionbooleanfalseargument

Also run the delegated cold_first consolidate pass over the same category (its own maintenance slot; results reported under 'compression')

max_entitiesinteger200argument

Scan budget: most-recently-accessed entities examined (clamped 1..=2000)

max_proposalsinteger50argument

Proposal budget: cap on merge+conflict proposals per run (clamped 1..=200)

requesting_agent_idstringargument

Host identity stamped by the MCP transport; used for global-mode authorization.

similarity_thresholdnumber0.75argument

Trigram similarity at or above which two entities are dedup candidates (merge proposal)

workspace_hashstringargument

#854 workspace scope. Mutually exclusive with global=true. One of workspace_hash or global is required.

Returns

categorystring
compressionany

Delegated consolidate report, or null when include_compression is false

conflict_proposalsinteger

Negation-shaped conflict proposals found (kind=conflict)

dedup_proposalsinteger

Merge proposals found (kind=merge)

dry_runboolean
maintenance_guardany

#952 maintenance-window status for this run

proposalsArray<object>
scannedinteger

Entities examined in this run

Sleep-Cycle Consolidation (Proposal-Only Pass)
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_sleep",
    "arguments": {
        "category": "string",
        "dry_run": false,
        "force": false,
        "global": false,
        "include_compression": false,
        "max_entities": 200,
        "max_proposals": 50,
        "requesting_agent_id": "",
        "similarity_threshold": 0.75,
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_sleep", {
  "category": "string",
  "dry_run": false,
  "force": false,
  "global": false,
  "include_compression": false,
  "max_entities": 200,
  "max_proposals": 50,
  "requesting_agent_id": "",
  "similarity_threshold": 0.75,
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_sleep", arguments={
  "category": "string",
  "dry_run": false,
  "force": false,
  "global": false,
  "include_compression": false,
  "max_entities": 200,
  "max_proposals": 50,
  "requesting_agent_id": "",
  "similarity_threshold": 0.75,
  "workspace_hash": "string"
})
Response
{
  "category": "string",
  "conflict_proposals": 0,
  "dedup_proposals": 0,
  "dry_run": true,
  "proposals": [
    {}
  ],
  "scanned": 0
}

Dream: LLM Consolidation of Episodic Memory into Semantic Insights

TOOLperseus_vault_dream

Sleep-time LLM consolidation: batch clusters of related cold/episodic memories, reflect over each cluster via the configured LLM endpoint, and write back durable higher-order SEMANTIC insights (category='insight', semantic layer) — 'given these N memories, what stable pattern/preference/fact do they collectively imply?'. Each written insight carries evidence_for links to every source entity (full provenance), a certainty blended from LLM confidence and evidence coverage, and derivation='dream' so it is auditable and reversible. Idempotent: insights are keyed by an evidence-set hash, so re-dreaming an unchanged cluster never spawns duplicates. Contradictory sources surface as a flagged 'contradiction' insight, never a silent merge. Never fabricates: clusters that support no durable generalization are a no-op. Requires --llm-endpoint (fully local via Ollama); returns a clean error without it unless fallback_consolidate=true, which runs the non-LLM perseus_vault_consolidate pass instead. Bounded by max_entities/max_clusters budgets. Preview with dry_run=true.

Parameters

archive_sourcesbooleanfalseargument

Archive source entities once an insight citing them is written (archive_reason names the insight; reversible). Verified or importance-floored sources are never archived; contradiction sources always stay live.

categorystringargument

Category to dream over. Omit to scan all categories (derived categories — insight, observation, synthesis, memories — are always skipped) until the entity budget is exhausted.

cold_firstbooleantrueargument

Scan the COLDEST entities first (longest since last access) — consolidate fading memories into durable semantic insights before decay claims them.

dry_runbooleanfalseargument

Report candidate insights and their evidence sets without writing anything.

fallback_consolidatebooleanfalseargument

When no --llm-endpoint is configured, run the mechanical (non-LLM) perseus_vault_consolidate cold_first pass instead of returning an error.

max_clustersinteger5argument

Budget cap: maximum clusters sent to the LLM per run (= max LLM calls).

max_entitiesinteger100argument

Budget cap: maximum entities scanned per run (across categories).

min_cluster_sizeinteger2argument

Minimum memories a cluster needs before it is worth dreaming over.

similarity_thresholdnumber0.3argument

Trigram similarity threshold for grouping RELATED memories into one cluster. Lower than consolidate's 0.6 on purpose: dreaming wants thematic neighborhoods, not near-duplicates.

topic_pathstringargument

Optional topic_path prefix filter applied to the scan.

Returns

categories_scannedArray<string>
clusters_dreamedinteger

Clusters actually sent to the LLM this run

contradictions_flaggedinteger

Insights flagged as contradictions among their sources

dry_runboolean
entities_examinedinteger

Number of entities scanned across all categories this run

fallbackstring

Present only when fallback_consolidate ran (no LLM endpoint): always "consolidate". The report then has this union shape — categories_scanned, entities_examined, observations_created, sources_archived, dry_run — instead of the LLM dream counters.

globalboolean

#854 true when this run deliberately crossed all workspaces

insightsArray<object>

The insights written (or previewed), each with entity_id, key, summary, insight_type, confidence, source_ids, category, contradiction, deduped

insights_dedupedinteger

Insights skipped because the identical evidence set was already dreamed

insights_writteninteger

Semantic insights written (or that would be, in dry-run)

notestring

Fallback-only explanation of why the mechanical pass ran

observations_createdinteger

Fallback-only: observations created by the mechanical consolidate pass

sources_archivedinteger

Sources archived because archive_sources was set (verified/importance-floored sources are exempt)

workspace_hashstring | null

#854 effective scope: the workspace this run operated in (null when global=true)

Dream: LLM Consolidation of Episodic Memory into Semantic Insights
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_dream",
    "arguments": {
        "archive_sources": false,
        "category": "string",
        "cold_first": true,
        "dry_run": false,
        "fallback_consolidate": false,
        "max_clusters": 5,
        "max_entities": 100,
        "min_cluster_size": 2,
        "similarity_threshold": 0.3,
        "topic_path": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_dream", {
  "archive_sources": false,
  "category": "string",
  "cold_first": true,
  "dry_run": false,
  "fallback_consolidate": false,
  "max_clusters": 5,
  "max_entities": 100,
  "min_cluster_size": 2,
  "similarity_threshold": 0.3,
  "topic_path": "string"
});
result = await session.call_tool("perseus_vault_dream", arguments={
  "archive_sources": false,
  "category": "string",
  "cold_first": true,
  "dry_run": false,
  "fallback_consolidate": false,
  "max_clusters": 5,
  "max_entities": 100,
  "min_cluster_size": 2,
  "similarity_threshold": 0.3,
  "topic_path": "string"
})
Response
{
  "categories_scanned": [
    "string"
  ],
  "clusters_dreamed": 0,
  "contradictions_flagged": 0,
  "dry_run": true,
  "entities_examined": 0,
  "fallback": "string",
  "global": true,
  "insights": [
    {}
  ],
  "insights_deduped": 0,
  "insights_written": 0,
  "note": "string",
  "observations_created": 0,
  "sources_archived": 0,
  "workspace_hash": "string"
}

Seal: Tamper Evidence for Persisted Memory

TOOLperseus_vault_seal

Record a seal (SHA-256 commitment) over a live entity's stored content — hash + label only, never the content itself. Compare-on-recall and perseus_vault_tamper_scan surface any later mismatch as a tamper event naming the entity, so a tampered store is never served silently. Integrity != truth: a seal proves unchanged-since-sealed, never true-when-written.

Parameters

agent_idstringargument

Sealing agent identity for the audit trail.

labelstringargument

Human-readable label recorded with the seal.

target_idstringrequiredargument

Entity id to seal.

workspace_hashstringargument

Workspace of the entity (optional; empty = global).

Returns

agent_idstring
created_at_unix_msinteger
labelstring
scopestring
seal_idstring
sha256string

SHA-256 over the sealed content (hash only — no content leak).

target_idstring
workspace_hashstring
Seal: Tamper Evidence for Persisted Memory
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_seal",
    "arguments": {
        "agent_id": "string",
        "label": "string",
        "target_id": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_seal", {
  "agent_id": "string",
  "label": "string",
  "target_id": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_seal", arguments={
  "agent_id": "string",
  "label": "string",
  "target_id": "string",
  "workspace_hash": "string"
})
Response
{
  "agent_id": "string",
  "created_at_unix_ms": 0,
  "label": "string",
  "scope": "string",
  "seal_id": "string",
  "sha256": "string",
  "target_id": "string",
  "workspace_hash": "string"
}

Seal Verification: Tamper Evidence Scan

read-only
TOOLperseus_vault_tamper_scan

Verify every seal (entity + export) against the live content. Returns mismatches and journals each as a tamper event naming the target. Integrity != truth: seals detect unchanged-since-sealed violations, not truth at write time.

Returns

okboolean
seals_checkedinteger
tamperedArray<object>
Show child attributes
actual_sha256string
detected_at_unix_msinteger
expected_sha256string
labelstring
scopestring
seal_idstring
target_idstring
Seal Verification: Tamper Evidence Scan
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_tamper_scan",
    "arguments": {}
  }
}
const result = await client.callTool("perseus_vault_tamper_scan", {});
result = await session.call_tool("perseus_vault_tamper_scan", arguments={})
Response
{
  "ok": true,
  "seals_checked": 0,
  "tampered": [
    {
      "actual_sha256": "string",
      "detected_at_unix_ms": 0,
      "expected_sha256": "string",
      "label": "string",
      "scope": "string",
      "seal_id": "string",
      "target_id": "string"
    }
  ]
}

Typed Provenance Projection: Evidence vs Execution

read-only
TOOLperseus_vault_provenance_projection

Evidence-vs-execution provenance projection over the typed link graph (#1064). mode=evidence walks supports/contradicts/invalidates/updates/authorized_by edges with classified kinds; mode=execution lists journal events referencing the entity plus blocked/denied authorized-action receipts (intent + failure receipt extended into the graph). Provenance != authorization != truth.

Parameters

depthintegerargument

BFS depth bound for evidence mode (1-10, default 3).

modestringargument

evidence (typed edge graph) or execution (journal events + blocked action receipts). Default: evidence.

seed_idstringrequiredargument

Entity id to project from.

Returns

blocked_actionsarray
depthinteger
edgesarray
modestring
nodesarray
seed_idstring
Typed Provenance Projection: Evidence vs Execution
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_provenance_projection",
    "arguments": {
        "depth": 0,
        "mode": "string",
        "seed_id": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_provenance_projection", {
  "depth": 0,
  "mode": "string",
  "seed_id": "string"
});
result = await session.call_tool("perseus_vault_provenance_projection", arguments={
  "depth": 0,
  "mode": "string",
  "seed_id": "string"
})
Response
{
  "blocked_actions": [],
  "depth": 0,
  "edges": [],
  "mode": "string",
  "nodes": [],
  "seed_id": "string"
}

Parameter-Level Lineage for High-Risk Arguments

TOOLperseus_vault_param_lineage

Parameter-level lineage for high-risk tool arguments (Agent-Sentry pattern, #1064): record or query where a specific parameter value came from. Query validates every source — a dangling source_ref is returned with resolved=false, surfaced rather than trusted.

Parameters

actionstringrequiredargument

set (record a lineage row) or query (list rows).

agent_idstringargument
entity_idstringrequiredargument
param_pathstringargument
source_kindstringargument
source_refstringargument

Optional producing entity id; validated at query time.

workspace_hashstringargument

Returns

entity_idstring
lineagearray
lineage_idstring
okboolean
Parameter-Level Lineage for High-Risk Arguments
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_param_lineage",
    "arguments": {
        "action": "string",
        "agent_id": "string",
        "entity_id": "string",
        "param_path": "string",
        "source_kind": "string",
        "source_ref": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_param_lineage", {
  "action": "string",
  "agent_id": "string",
  "entity_id": "string",
  "param_path": "string",
  "source_kind": "string",
  "source_ref": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_param_lineage", arguments={
  "action": "string",
  "agent_id": "string",
  "entity_id": "string",
  "param_path": "string",
  "source_kind": "string",
  "source_ref": "string",
  "workspace_hash": "string"
})
Response
{
  "entity_id": "string",
  "lineage": [],
  "lineage_id": "string",
  "ok": true
}

Intent-Aware Typed-Relational Traversal

TOOLperseus_vault_typed_traversal

Intent-aware typed-relational traversal (#1065, MAGMA pattern): routes the query to one relation view (temporal / causal / entity / semantic) via a deterministic classifier, runs that view's traversal policy, and returns the explainable selected path (steps carry the relation they were taken over) plus rejected distractors with reasons — with token accounting for the context-budget discipline. LLM-free and reproducible: identical query → identical route.

Parameters

limitintegerargument

Selected-path size bound (1-50, default 10).

querystringrequiredargument

Returns

intentstring
patharray
querystring
rejectedarray
run_idstring
tokens_rejectedinteger
tokens_selectedinteger
viewstring
Intent-Aware Typed-Relational Traversal
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_typed_traversal",
    "arguments": {
        "limit": 0,
        "query": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_typed_traversal", {
  "limit": 0,
  "query": "string"
});
result = await session.call_tool("perseus_vault_typed_traversal", arguments={
  "limit": 0,
  "query": "string"
})
Response
{
  "intent": "string",
  "path": [],
  "query": "string",
  "rejected": [],
  "run_id": "string",
  "tokens_rejected": 0,
  "tokens_selected": 0,
  "view": "string"
}

Typed-Traversal Ablation Report

read-only
TOOLperseus_vault_traversal_ablation

Per-relation-view ablation report over recorded typed traversals (#1065): mean selected/rejected tokens and distractor ratio per view — auditable evidence for whether each relation view earns its token cost.

Returns

viewsarray
Typed-Traversal Ablation Report
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_traversal_ablation",
    "arguments": {}
  }
}
const result = await client.callTool("perseus_vault_traversal_ablation", {});
result = await session.call_tool("perseus_vault_traversal_ablation", arguments={})
Response
{
  "views": []
}

Model-Upgrade Inheritance Receipt

TOOLperseus_vault_model_inheritance

Model-upgrade inheritance receipt (#1066, identity/vessel split): record a source-state snapshot for a subject identity and the replacement model identity, run the compatibility report, and (after policy-gated approval) stamp the approved handoff as a queryable inheritance receipt in the provenance graph. depart is a governed transition that preserves a tombstone; replay samples representative memories as hash-only digests (no content leak). Memory survives the model — now the handoff is auditable.

Parameters

actionstringrecordapprovequerydepartreplayrequiredargument
approverstringargument
new_modelstringargument
old_modelstringargument
reasonstringargument
sample_countintegerargument
subject_idstringrequiredargument

Returns

okboolean
receiptobject
replayobject
Model-Upgrade Inheritance Receipt
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_model_inheritance",
    "arguments": {
        "action": "record",
        "approver": "string",
        "new_model": "string",
        "old_model": "string",
        "reason": "string",
        "sample_count": 0,
        "subject_id": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_model_inheritance", {
  "action": "record",
  "approver": "string",
  "new_model": "string",
  "old_model": "string",
  "reason": "string",
  "sample_count": 0,
  "subject_id": "string"
});
result = await session.call_tool("perseus_vault_model_inheritance", arguments={
  "action": "record",
  "approver": "string",
  "new_model": "string",
  "old_model": "string",
  "reason": "string",
  "sample_count": 0,
  "subject_id": "string"
})
Response
{
  "ok": true,
  "receipt": {},
  "replay": {}
}

Export Vault to Files

destructive
TOOLperseus_vault_vault_export

Export all non-archived entities to .md files with YAML frontmatter in a vault directory. Files are human-readable, git-trackable, and Obsidian-compatible. Use this for backup, transfer between workspaces, or offline review.

Parameters

requesting_agent_idstringargument

Transport-stamped requester identity used for visibility enforcement.

vault_dirstring~/.perseus-vault/vaultargument

Directory path to write .md files. Created if it doesn't exist. Use ~ for home directory.

Returns

completed_at_unix_msinteger

Completion timestamp

errorsArray<string>

Any errors encountered during export

files_createdinteger

Number of new .md files created

files_updatedinteger

Number of existing .md files updated

vault_dirstring

Absolute path to the vault directory

Export Vault to Files
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_vault_export",
    "arguments": {
        "requesting_agent_id": "string",
        "vault_dir": "~/.perseus-vault/vault"
      }
  }
}
const result = await client.callTool("perseus_vault_vault_export", {
  "requesting_agent_id": "string",
  "vault_dir": "~/.perseus-vault/vault"
});
result = await session.call_tool("perseus_vault_vault_export", arguments={
  "requesting_agent_id": "string",
  "vault_dir": "~/.perseus-vault/vault"
})
Response
{
  "completed_at_unix_ms": 0,
  "errors": [
    "string"
  ],
  "files_created": 0,
  "files_updated": 0,
  "vault_dir": "string"
}

perseus_vault_derived_export

TOOLperseus_vault_derived_export

Compile durable knowledge into a deterministic, provenance-rich Markdown surface. The export is derived and read-only; SQLite remains the source of truth.

Parameters

output_pathstringrequiredargument

Markdown file path to write.

requesting_agent_idstringargument

Transport-stamped requester identity used for visibility enforcement.

workspace_hashstringargument

Optional exact workspace scope.

Returns

Returns MCP content array (text, image, or embedded resource).

perseus_vault_derived_export
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_derived_export",
    "arguments": {
        "output_path": "string",
        "requesting_agent_id": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_derived_export", {
  "output_path": "string",
  "requesting_agent_id": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_derived_export", arguments={
  "output_path": "string",
  "requesting_agent_id": "string",
  "workspace_hash": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

perseus_vault_markdown_import

TOOLperseus_vault_markdown_import

Import one Markdown file as explicitly non-authoritative, provenance-labeled draft evidence. Duplicate source content is idempotently detected.

Parameters

pathstringrequiredargument

Markdown file path to import.

source_systemstringargument

Provenance source label; defaults to markdown.

workspace_hashstringargument

Returns

Returns MCP content array (text, image, or embedded resource).

perseus_vault_markdown_import
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_markdown_import",
    "arguments": {
        "path": "string",
        "source_system": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_markdown_import", {
  "path": "string",
  "source_system": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_markdown_import", arguments={
  "path": "string",
  "source_system": "string",
  "workspace_hash": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

perseus_vault_structured_index_anchor

TOOLperseus_vault_structured_index_anchor

Represent an upstream structured-index record as a refetchable anchor, or import it explicitly as low-confidence non-authoritative draft evidence.

Parameters

contentstringargument

Required only for mode=import.

index_typestringrequiredargument

Structured index kind, e.g. ide_symbol or domain_fact_map.

index_uristringrequiredargument

Stable index locator for later refetch.

modestringreferenceimportreferenceargument
observed_at_unix_msintegerargument
record_idstringrequiredargument

Stable record identity inside the index.

revisionstringargument

Optional upstream revision/ETag for refetch verification.

source_systemstringargument
workspace_hashstringargument

Returns

Returns MCP content array (text, image, or embedded resource).

perseus_vault_structured_index_anchor
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_structured_index_anchor",
    "arguments": {
        "content": "string",
        "index_type": "string",
        "index_uri": "string",
        "mode": "reference",
        "observed_at_unix_ms": 0,
        "record_id": "string",
        "revision": "string",
        "source_system": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_structured_index_anchor", {
  "content": "string",
  "index_type": "string",
  "index_uri": "string",
  "mode": "reference",
  "observed_at_unix_ms": 0,
  "record_id": "string",
  "revision": "string",
  "source_system": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_structured_index_anchor", arguments={
  "content": "string",
  "index_type": "string",
  "index_uri": "string",
  "mode": "reference",
  "observed_at_unix_ms": 0,
  "record_id": "string",
  "revision": "string",
  "source_system": "string",
  "workspace_hash": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Import Vault from Files

destructive
TOOLperseus_vault_vault_import

Import .md files from a vault directory into the database. Reads YAML frontmatter for metadata and markdown body for content. Idempotent — re-running on the same vault won't duplicate entities. Pass shadow_workspace to run a shadow import: every entity is forced into that scratch workspace and the live bank is never touched, so you can compare recall before cutting over (see perseus_vault_shadow_compare / _promote / _rollback). Pair with perseus_vault_vault_export for transfer.

Parameters

shadow_workspacestringargument

#951 shadow import: when set, every imported entity is forced into this workspace regardless of frontmatter. Zero writes to the live bank; rerunnable with zero new identities.

vault_dirstring~/.perseus-vault/vaultargument

Directory path to read .md files from. Use ~ for home directory.

Returns

completed_at_unix_msinteger

Completion timestamp

errorsArray<string>

Any errors encountered during import

files_createdinteger

Number of new entities created from files

files_updatedinteger

Number of existing entities updated

vault_dirstring

Absolute path of the vault directory read

Import Vault from Files
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_vault_import",
    "arguments": {
        "shadow_workspace": "string",
        "vault_dir": "~/.perseus-vault/vault"
      }
  }
}
const result = await client.callTool("perseus_vault_vault_import", {
  "shadow_workspace": "string",
  "vault_dir": "~/.perseus-vault/vault"
});
result = await session.call_tool("perseus_vault_vault_import", arguments={
  "shadow_workspace": "string",
  "vault_dir": "~/.perseus-vault/vault"
})
Response
{
  "completed_at_unix_ms": 0,
  "errors": [
    "string"
  ],
  "files_created": 0,
  "files_updated": 0,
  "vault_dir": "string"
}

Compare Live vs Shadow Recall

read-only
TOOLperseus_vault_shadow_compare

#951: recall comparison between the live workspace and a shadow workspace over a fixed query set. Deterministic (Fts5 mode), side-effect-free, machine-readable — the gate for deciding whether a shadow import clears cutover.

Parameters

limitinteger5argument

Recall limit per query (1..=100).

live_workspacestringargument

Live workspace to compare against; omit for the unscoped bank.

queriesArray<string>requiredargument

Fixed query set to run in both workspaces (1..=500).

shadow_workspacestringrequiredargument

The scratch workspace holding the shadow import.

Returns

Returns MCP content array (text, image, or embedded resource).

Compare Live vs Shadow Recall
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_shadow_compare",
    "arguments": {
        "limit": 5,
        "live_workspace": "string",
        "queries": [
          "string"
        ],
        "shadow_workspace": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_shadow_compare", {
  "limit": 5,
  "live_workspace": "string",
  "queries": [
    "string"
  ],
  "shadow_workspace": "string"
});
result = await session.call_tool("perseus_vault_shadow_compare", arguments={
  "limit": 5,
  "live_workspace": "string",
  "queries": [
    "string"
  ],
  "shadow_workspace": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Promote Shadow Import to Live

destructive
TOOLperseus_vault_shadow_promote

#951: promote — move every non-archived entity from the shadow workspace into the target workspace in ONE atomic operation, journaling the moved ids so perseus_vault_shadow_rollback can undo the cutover in one operation. dry_run previews the count without writing.

Parameters

dry_runbooleanfalseargument

Preview the move (count only — nothing written, no journal).

shadow_workspacestringrequiredargument

The scratch workspace to promote from.

target_workspacestringargument

Target workspace (default: the unscoped live bank).

Returns

Returns MCP content array (text, image, or embedded resource).

Promote Shadow Import to Live
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_shadow_promote",
    "arguments": {
        "dry_run": false,
        "shadow_workspace": "string",
        "target_workspace": ""
      }
  }
}
const result = await client.callTool("perseus_vault_shadow_promote", {
  "dry_run": false,
  "shadow_workspace": "string",
  "target_workspace": ""
});
result = await session.call_tool("perseus_vault_shadow_promote", arguments={
  "dry_run": false,
  "shadow_workspace": "string",
  "target_workspace": ""
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Roll Back Shadow Promote

destructive
TOOLperseus_vault_shadow_rollback

#951: rollback — one operation returns every promoted id to its pre-promote workspace, using the shadow_promote_last journal. dry_run previews the journal without writing.

Parameters

dry_runbooleanfalseargument

Preview the journal (nothing written, journal kept).

Returns

Returns MCP content array (text, image, or embedded resource).

Roll Back Shadow Promote
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_shadow_rollback",
    "arguments": {
        "dry_run": false
      }
  }
}
const result = await client.callTool("perseus_vault_shadow_rollback", {
  "dry_run": false
});
result = await session.call_tool("perseus_vault_shadow_rollback", arguments={
  "dry_run": false
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Recalculate Decay Scores

destructive
TOOLperseus_vault_decay

Recalculate Ebbinghaus decay scores for all entities based on time since last access. Auto-archives entities that have fully decayed (score < 0.05). Run periodically to keep memory fresh — decayed entities surface less often in recall results.

Returns

auto_archivedinteger

Entities auto-archived because decay fell below 0.05

completed_at_unix_msinteger

Completion timestamp

entities_checkedinteger

Total entities evaluated

entities_updatedinteger

Entities whose stored decay score was actually rewritten (rows whose recomputed score changed). A steady-state tick reports ~0: unchanged rows are evaluated but not written.

Recalculate Decay Scores
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_decay",
    "arguments": {}
  }
}
const result = await client.callTool("perseus_vault_decay", {});
result = await session.call_tool("perseus_vault_decay", arguments={})
Response
{
  "auto_archived": 0,
  "completed_at_unix_ms": 0,
  "entities_checked": 0,
  "entities_updated": 0
}

Rebuild Search Index

destructive
TOOLperseus_vault_reindex

Rebuild the FTS5 search index from the entities table. Repairs index drift — e.g. after a direct SQLite write, an interrupted archive, or a legacy database written before the atomic prune/forget fixes — so archived entities stop surfacing in recall/search. Returns the number of entities reindexed.

Returns

reindexedinteger

Number of non-archived entities indexed into FTS5

Rebuild Search Index
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_reindex",
    "arguments": {}
  }
}
const result = await client.callTool("perseus_vault_reindex", {});
result = await session.call_tool("perseus_vault_reindex", arguments={})
Response
{
  "reindexed": 0
}

List Workspace Categories

read-only
TOOLperseus_vault_workspace_list

List all distinct entity categories present in the database. Use this to discover what knowledge domains exist before querying with perseus_vault_recall or perseus_vault_context.

Returns

categoriesArray<string>

All distinct categories in the database

totalinteger

Number of categories

List Workspace Categories
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_workspace_list",
    "arguments": {}
  }
}
const result = await client.callTool("perseus_vault_workspace_list", {});
result = await session.call_tool("perseus_vault_workspace_list", arguments={})
Response
{
  "categories": [
    "string"
  ],
  "total": 0
}

Proactive Recall by Context

read-only
TOOLperseus_vault_recall_when

Search entities whose recall_when triggers match a given context. Use this for proactive just-in-time memory injection — before writing code, before plans, at session start. Pass the current task description as context and get back memories that declared they should be recalled in similar situations.

Parameters

contextstringrequiredargument

The current task or context description to match against recall_when triggers

limitinteger10argument

Maximum entities to return (default 10, max 100)

session_idstringargument

Session id for preload usage telemetry (#875): served entities are attributed to this session for precision/recall resolution. Omit or leave empty when unknown.

workspace_hashstringargument

Workspace scope filter (v1.2.0). When set, only entities with a matching workspace_hash can fire. Omit for no workspace filtering — in a federated vault that lets one workspace's triggers inject into another's turns.

Returns

contextstring
itemsArray<object>
totalinteger
Proactive Recall by Context
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_recall_when",
    "arguments": {
        "context": "string",
        "limit": 10,
        "session_id": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_recall_when", {
  "context": "string",
  "limit": 10,
  "session_id": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_recall_when", arguments={
  "context": "string",
  "limit": 10,
  "session_id": "string",
  "workspace_hash": "string"
})
Response
{
  "context": "string",
  "items": [
    {}
  ],
  "total": 0
}

Run Coherence Grooming

destructive
TOOLperseus_vault_cohere

Run an autonomous coherence grooming pass over the memory. Promotes buffer entities to working layer, applies decay, auto-links related entities, and archives stale ones below the decay threshold. Use dry_run=true to preview without making changes.

Parameters

archive_thresholdnumber0.05argument

Decay score below which entities are auto-archived (default 0.05)

cross_scope_kinteger3argument

Minimum distinct workspaces before a recurring fact is promoted (default 3, minimum 2)

cross_scope_promotebooleanfalseargument

#486: also run cross-scope promotion — a fact independently observed in >= cross_scope_k distinct workspaces is promoted to one global-scope entity with promoted_from links back to the per-scope evidence. Off by default; re-runs are idempotent (the global scope's dedup absorbs them); undo by forgetting the promoted entity.

cross_scope_similaritynumber0.7argument

Trigram similarity treating two bodies as the same fact across scopes (default 0.7, matching write-time dedup)

dry_runbooleanfalseargument

If true, count what would be done without making changes

max_linksinteger20argument

Maximum auto-links to create (default 20, max 100)

promote_thresholdinteger3argument

Retrieval count threshold for buffer to working promotion (default 3)

Returns

archivedinteger

Number of entities archived due to low decay

completed_at_unix_msinteger
cross_scope_clustersinteger

#486: clusters found spanning >= cross_scope_k workspaces (0 unless cross_scope_promote)

cross_scope_promotedinteger

#486: new global-scope entities created by cross-scope promotion

cross_scope_skipped_existinginteger

#486: qualifying clusters already represented at the global scope (idempotent re-run)

decayedinteger

Number of entities whose decay score was reduced

dry_runboolean
entities_examinedinteger

Total non-archived entities examined

linkedinteger

Number of auto-links created

promotedinteger

Number of entities promoted from buffer to working

Run Coherence Grooming
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_cohere",
    "arguments": {
        "archive_threshold": 0.05,
        "cross_scope_k": 3,
        "cross_scope_promote": false,
        "cross_scope_similarity": 0.7,
        "dry_run": false,
        "max_links": 20,
        "promote_threshold": 3
      }
  }
}
const result = await client.callTool("perseus_vault_cohere", {
  "archive_threshold": 0.05,
  "cross_scope_k": 3,
  "cross_scope_promote": false,
  "cross_scope_similarity": 0.7,
  "dry_run": false,
  "max_links": 20,
  "promote_threshold": 3
});
result = await session.call_tool("perseus_vault_cohere", arguments={
  "archive_threshold": 0.05,
  "cross_scope_k": 3,
  "cross_scope_promote": false,
  "cross_scope_similarity": 0.7,
  "dry_run": false,
  "max_links": 20,
  "promote_threshold": 3
})
Response
{
  "archived": 0,
  "completed_at_unix_ms": 0,
  "cross_scope_clusters": 0,
  "cross_scope_promoted": 0,
  "cross_scope_skipped_existing": 0,
  "decayed": 0,
  "dry_run": true,
  "entities_examined": 0,
  "linked": 0,
  "promoted": 0
}

Share Entity to Workspace

destructive
TOOLperseus_vault_share

Share an entity to another workspace. Copies the entity (by category + key) from its current workspace into the target workspace, preserving content and metadata while generating a new ID. The original entity is unchanged. Use this for controlled cross-workspace knowledge transfer.

Parameters

categorystringrequiredargument

Entity category to share

keystringrequiredargument

Entity key to share

to_workspacestringrequiredargument

Target workspace hash to copy the entity into

Returns

actionstring

'created' or 'updated'

from_workspacestring

Source workspace the entity was copied from

shared_idstring

ID of the new shared copy

to_workspacestring

Target workspace the entity was copied to

Share Entity to Workspace
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_share",
    "arguments": {
        "category": "string",
        "key": "string",
        "to_workspace": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_share", {
  "category": "string",
  "key": "string",
  "to_workspace": "string"
});
result = await session.call_tool("perseus_vault_share", arguments={
  "category": "string",
  "key": "string",
  "to_workspace": "string"
})
Response
{
  "action": "string",
  "from_workspace": "string",
  "shared_id": "string",
  "to_workspace": "string"
}

Capture Agent Correction

destructive
TOOLperseus_vault_correct

Capture a user correction to the agent. Stores what went wrong, what the user said, and the lesson learned — as both a 'correction' entity and a journal entry. Use this every time the user corrects your approach. Enables the self-improving feedback loop: the agent learns from mistakes across sessions.

Body

application/json
agent_idstring

Agent that authored the correction (stamped on the tombstone).

categorystringcorrection

Entity category (default: 'correction')

evidenceobject

Write-time audit envelope for the correction's source evidence. capture_mode distinguishes snapshot, hash_only, pointer_only, not_requested, capture_failed, and legacy_unknown; a missing value is never interpreted implicitly.

Show child attributes
capture_modestringsnapshothash_onlypointer_onlynot_requestedcapture_failedlegacy_unknownrequired
captured_at_unix_msintegerrequired
content_sha256string

64-hex SHA-256 of the resolved value or source bytes

replayablebooleanrequired
resolved_valueany

Resolved source value retained at write time when capture_mode=snapshot

source_refstring
source_systemstring
requesting_agent_idstring

#855 host identity (stamped by the MCP transport). When present, it is authoritative: the correction entity, journal event, and tombstone attribute the host, not any model-supplied agent_id.

session_idstring

Session identifier for traceability

tagsArray<string>

Tags for categorization

task_contextstringrequired

What task was being attempted when the correction occurred

user_correctionstringrequired

What the user said to correct the agent (the right way)

valid_from_unix_msinteger

Application-time period start (#363): when the corrected fact was actually true in the world. Set in the past for retroactive corrections. Default: transaction time.

valid_to_unix_msinteger

Application-time period end (#363, exclusive). Omit for 'still true'.

visibilitystringworkspace

Visibility: 'private', 'workspace', or 'public'

workspace_hashstring

Workspace scope for the rejection tombstone (#849). Empty means global.

wrong_approachstringrequired

What the agent did that was wrong (the mistaken approach)

Returns

agent_idstring

#855 agent attribution persisted on the entity and journal event (host identity when the transport stamped one)

categorystring
created_at_unix_msinteger
entity_idstring

Created correction entity ID

journal_idstring

Created journal entry ID

keystring
workspace_hashstring

#855 workspace scope persisted on the entity and journal event. Empty = global/legacy.

Capture Agent Correction
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_correct",
    "arguments": {
        "agent_id": "",
        "category": "correction",
        "evidence": {
          "capture_mode": "snapshot",
          "captured_at_unix_ms": 0,
          "content_sha256": "string",
          "replayable": true,
          "source_ref": "string",
          "source_system": "string"
        },
        "requesting_agent_id": "",
        "session_id": "",
        "tags": [
          "string"
        ],
        "task_context": "string",
        "user_correction": "string",
        "valid_from_unix_ms": 0,
        "valid_to_unix_ms": 0,
        "visibility": "workspace",
        "workspace_hash": "",
        "wrong_approach": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_correct", {
  "agent_id": "",
  "category": "correction",
  "evidence": {
    "capture_mode": "snapshot",
    "captured_at_unix_ms": 0,
    "content_sha256": "string",
    "replayable": true,
    "source_ref": "string",
    "source_system": "string"
  },
  "requesting_agent_id": "",
  "session_id": "",
  "tags": [
    "string"
  ],
  "task_context": "string",
  "user_correction": "string",
  "valid_from_unix_ms": 0,
  "valid_to_unix_ms": 0,
  "visibility": "workspace",
  "workspace_hash": "",
  "wrong_approach": "string"
});
result = await session.call_tool("perseus_vault_correct", arguments={
  "agent_id": "",
  "category": "correction",
  "evidence": {
    "capture_mode": "snapshot",
    "captured_at_unix_ms": 0,
    "content_sha256": "string",
    "replayable": true,
    "source_ref": "string",
    "source_system": "string"
  },
  "requesting_agent_id": "",
  "session_id": "",
  "tags": [
    "string"
  ],
  "task_context": "string",
  "user_correction": "string",
  "valid_from_unix_ms": 0,
  "valid_to_unix_ms": 0,
  "visibility": "workspace",
  "workspace_hash": "",
  "wrong_approach": "string"
})
Request Body
{
  "agent_id": "",
  "category": "correction",
  "evidence": {
    "capture_mode": "snapshot",
    "captured_at_unix_ms": 0,
    "content_sha256": "string",
    "replayable": true,
    "source_ref": "string",
    "source_system": "string"
  },
  "requesting_agent_id": "",
  "session_id": "",
  "tags": [
    "string"
  ],
  "task_context": "string",
  "user_correction": "string",
  "valid_from_unix_ms": 0,
  "valid_to_unix_ms": 0,
  "visibility": "workspace",
  "workspace_hash": "",
  "wrong_approach": "string"
}
Response
{
  "agent_id": "string",
  "category": "string",
  "created_at_unix_ms": 0,
  "entity_id": "string",
  "journal_id": "string",
  "key": "string",
  "workspace_hash": "string"
}

Synthesize Session Lessons

destructive
TOOLperseus_vault_synthesize

LLM-driven session synthesis. Reviews a session transcript and extracts structured lessons: what worked (success), what failed (failure), what was corrected (correction), what was abandoned (dead_end), and key decisions made (decision). Each lesson becomes an entity linked to a synthesis journal entry. Requires --llm-endpoint to be configured. This is the Perplexity-Brain-style overnight synthesis loop for agent self-improvement.

Parameters

session_contentstringrequiredargument

Full session transcript to synthesize lessons from

session_idstringargument

Session identifier for traceability

tagsArray<string>argument

Tags applied to all synthesized entities

visibilitystringworkspaceargument

Visibility for synthesized entities

Returns

completed_at_unix_msinteger
dry_runboolean
entities_createdinteger

Number of lesson entities created

journal_idstring
lessonsArray<object>

Extracted lessons with type, summary, evidence, and confidence

Show child attributes
confidencenumber
evidencestring
lesson_typestring
summarystring
Synthesize Session Lessons
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_synthesize",
    "arguments": {
        "session_content": "string",
        "session_id": "",
        "tags": [
          "string"
        ],
        "visibility": "workspace"
      }
  }
}
const result = await client.callTool("perseus_vault_synthesize", {
  "session_content": "string",
  "session_id": "",
  "tags": [
    "string"
  ],
  "visibility": "workspace"
});
result = await session.call_tool("perseus_vault_synthesize", arguments={
  "session_content": "string",
  "session_id": "",
  "tags": [
    "string"
  ],
  "visibility": "workspace"
})
Response
{
  "completed_at_unix_ms": 0,
  "dry_run": true,
  "entities_created": 0,
  "journal_id": "string",
  "lessons": [
    {
      "confidence": 0,
      "evidence": "string",
      "lesson_type": "string",
      "summary": "string"
    }
  ]
}

Record Benchmark

destructive
TOOLperseus_vault_bench

Record a performance benchmark data point. Tracks task metrics (turns taken, tokens used, success) alongside whether memory recall was used — enabling measurement of Perseus Vault's impact on agent performance. Aggregate with perseus_vault_recall to analyze trends.

Parameters

memory_recall_usedbooleanrequiredargument

Whether memory recall (perseus_vault_recall) was used during this task

recall_countinteger0argument

How many times memory was recalled during this task

session_idstringargument

Session identifier for traceability

tagsArray<string>argument

Tags for categorization

task_descriptionstringrequiredargument

Description of the task being measured

task_successbooleanfalseargument

Whether the task completed successfully

tokens_usedintegerrequiredargument

Total tokens consumed by the task

turns_takenintegerrequiredargument

Number of conversation turns the task took

Returns

created_at_unix_msinteger
entity_idstring

Created benchmark entity ID

Record Benchmark
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_bench",
    "arguments": {
        "memory_recall_used": true,
        "recall_count": 0,
        "session_id": "",
        "tags": [
          "string"
        ],
        "task_description": "string",
        "task_success": false,
        "tokens_used": 0,
        "turns_taken": 0
      }
  }
}
const result = await client.callTool("perseus_vault_bench", {
  "memory_recall_used": true,
  "recall_count": 0,
  "session_id": "",
  "tags": [
    "string"
  ],
  "task_description": "string",
  "task_success": false,
  "tokens_used": 0,
  "turns_taken": 0
});
result = await session.call_tool("perseus_vault_bench", arguments={
  "memory_recall_used": true,
  "recall_count": 0,
  "session_id": "",
  "tags": [
    "string"
  ],
  "task_description": "string",
  "task_success": false,
  "tokens_used": 0,
  "turns_taken": 0
})
Response
{
  "created_at_unix_ms": 0,
  "entity_id": "string"
}

Atomic Coherence Pass

destructive
TOOLperseus_vault_autocohere

Run a full atomic grooming pass. When capture_text is supplied, capture runs first and must succeed before cohere, decay, compact, consolidation, or retention can compress source context. Returns a summary report. Use dry_run=true to preview without writing.

Parameters

capture_agent_idstringargument

Agent attribution for pre-compaction captured facts

capture_max_entitiesintegerargument

Maximum durable notes extracted from capture_text (1-20)

capture_textstringargument

Optional raw transcript/insight payload persisted before every compaction-like stage. Capture failure aborts the pass.

capture_workspace_hashstringargument

Workspace scope for pre-compaction captured facts

dry_runbooleanfalseargument

If true, preview changes without writing

globalbooleanfalseargument

#854 explicit whole-vault consolidation mode (capability-gated with a host identity). Mutually exclusive with workspace_hash.

requesting_agent_idstringargument

Host identity stamped by the MCP transport. Used for global-mode authorization and consolidation author attribution.

workspace_hashstringargument

#854 workspace scope for the consolidation step. When set, only that workspace's entities are consolidated and the observations inherit the scope. Omit for the whole-vault pass.

Returns

archived_entitiesinteger

Entities archived (cohere + compact)

compact_archived_countinteger

Entities archived during compact step

consolidate_sources_archivedinteger

Sources archived by the consolidation step (verified/importance-floored exempt)

db_size_delta_bytesinteger

Change in SQLite file size in bytes

decay_auto_archivedinteger

Entities decay auto-archived during this pass (#490; 0 under dry_run)

decay_updatesinteger

Entities whose decay score was updated

dry_runboolean
globalboolean

#854 true when the consolidation step deliberately crossed all workspaces

history_bytes_evictedinteger

Stored history body bytes evicted (#398)

history_rows_evictedinteger

entity_history rows evicted by the retention policy (#398; 0 while no PERSEUS_VAULT_HISTORY_* knob is set)

history_tombstones_writteninteger

Compaction tombstones written (#398)

links_createdinteger

Auto-links created during cohere

observations_createdinteger

Observations created by the consolidation step

precompact_captureobject

Capture barrier report. stage=completed means capture persisted before all lifecycle compression stages; stage=skipped means no capture_text was supplied.

promoted_entitiesinteger

Entities promoted during cohere

workspace_hashstring | null

#854 effective consolidation scope: the workspace the consolidate step operated in (null = whole-vault pass)

Atomic Coherence Pass
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_autocohere",
    "arguments": {
        "capture_agent_id": "string",
        "capture_max_entities": 0,
        "capture_text": "string",
        "capture_workspace_hash": "string",
        "dry_run": false,
        "global": false,
        "requesting_agent_id": "",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_autocohere", {
  "capture_agent_id": "string",
  "capture_max_entities": 0,
  "capture_text": "string",
  "capture_workspace_hash": "string",
  "dry_run": false,
  "global": false,
  "requesting_agent_id": "",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_autocohere", arguments={
  "capture_agent_id": "string",
  "capture_max_entities": 0,
  "capture_text": "string",
  "capture_workspace_hash": "string",
  "dry_run": false,
  "global": false,
  "requesting_agent_id": "",
  "workspace_hash": "string"
})
Response
{
  "archived_entities": 0,
  "compact_archived_count": 0,
  "consolidate_sources_archived": 0,
  "db_size_delta_bytes": 0,
  "decay_auto_archived": 0,
  "decay_updates": 0,
  "dry_run": true,
  "global": true,
  "history_bytes_evicted": 0,
  "history_rows_evicted": 0,
  "history_tombstones_written": 0,
  "links_created": 0,
  "observations_created": 0,
  "precompact_capture": {},
  "promoted_entities": 0,
  "workspace_hash": "string"
}

Supersede Entity

destructive
TOOLperseus_vault_supersede

Create a 'supersedes' relationship from a new fact to an old one, setting the old entity's status to 'deprecated'. Use this when a newer entity makes an older one obsolete.

Parameters

from_categorystringrequiredargument

Category of the OLD entity being superseded

from_keystringrequiredargument

Key of the OLD entity being superseded

reasonstringargument

Reason for superseding (recorded in archive_reason)

relationshipstringsupersedesargument

Link relationship type (default: 'supersedes')

to_categorystringrequiredargument

Category of the NEW entity that supersedes

to_keystringrequiredargument

Key of the NEW entity that supersedes

valid_to_unix_msintegerargument

When the OLD fact stopped being true in the world (#363, unix ms). Defaults to transaction time (now). Closes the old entity's application-time period so perseus_vault_valid_at stops returning it from that instant on. Must be after the fact's valid_from, and may only TIGHTEN an already-closed period (a fact that ended cannot be retroactively extended); violations are rejected before any mutation.

Returns

from_entity_categorystring
from_entity_idstring

ID of the old (superseded) entity

from_entity_keystring
from_valid_to_unix_msinteger

The instant the old fact's validity was closed at (#363)

relationshipstring
status_updatedstring

New status of the old entity (always 'deprecated')

to_entity_categorystring
to_entity_idstring

ID of the new (superseding) entity

to_entity_keystring
Supersede Entity
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_supersede",
    "arguments": {
        "from_category": "string",
        "from_key": "string",
        "reason": "",
        "relationship": "supersedes",
        "to_category": "string",
        "to_key": "string",
        "valid_to_unix_ms": 0
      }
  }
}
const result = await client.callTool("perseus_vault_supersede", {
  "from_category": "string",
  "from_key": "string",
  "reason": "",
  "relationship": "supersedes",
  "to_category": "string",
  "to_key": "string",
  "valid_to_unix_ms": 0
});
result = await session.call_tool("perseus_vault_supersede", arguments={
  "from_category": "string",
  "from_key": "string",
  "reason": "",
  "relationship": "supersedes",
  "to_category": "string",
  "to_key": "string",
  "valid_to_unix_ms": 0
})
Response
{
  "from_entity_category": "string",
  "from_entity_id": "string",
  "from_entity_key": "string",
  "from_valid_to_unix_ms": 0,
  "relationship": "string",
  "status_updated": "string",
  "to_entity_category": "string",
  "to_entity_id": "string",
  "to_entity_key": "string"
}

Consistency Audit (court of record)

TOOLperseus_vault_consistency_audit

Read-only court-of-record self-audit (#940): scans the category for contradiction pairs, recommends a deterministic winner per pair (importance → source-authority → recency → id), surfaces pairs with an existing active ruling, lists supersession lag (deprecated entities without a live successor), and reports the pending keystone suggestion count. NEVER mutates: run before ruling, decide with perseus_vault_audit_ruling.

Parameters

categorystringfactsargument

Category to audit (default: facts)

limitinteger50argument

Max contradiction pairs to scan (clamped 1-200, default 50)

Returns

findingsarray

Per-pair: recommendation {winner_id, winner_key, decided_by} or already_ruled {ruling_id, winner_id}

keystone_pendinginteger
read_onlyboolean

Always true — the audit never mutates

supersession_lagarray
Consistency Audit (court of record)
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_consistency_audit",
    "arguments": {
        "category": "facts",
        "limit": 50
      }
  }
}
const result = await client.callTool("perseus_vault_consistency_audit", {
  "category": "facts",
  "limit": 50
});
result = await session.call_tool("perseus_vault_consistency_audit", arguments={
  "category": "facts",
  "limit": 50
})
Response
{
  "findings": [],
  "keystone_pending": 0,
  "read_only": true,
  "supersession_lag": []
}

Audit Ruling (court of record)

TOOLperseus_vault_audit_ruling

Idempotent operator ruling over a consistency finding (#940): accept compiles the recommended winner into the supersede guard (winner→loser link, loser valid-period closed, status deprecated); override compiles an explicit winner; reverse reopens a ruled pair for re-litigation (the compiled guard remains). Rulings are recorded + journaled (court_ruling_set/court_ruling_reversed); an active ruling with a different winner is refused until reversed.

Parameters

actionstringacceptoverridereverserequiredargument

accept = compile the ladder-recommended winner; override = compile an explicit winner; reverse = reopen a ruled pair

categorystringfactsargument

Category of entity_a/entity_b (default: facts)

decided_bystringoperatorargument

Who decided (default: operator)

entity_a_keystringargument

Key of the first contested entity (accept/override)

entity_b_keystringargument

Key of the second contested entity (accept/override)

rationalestringargument

Optional ruling rationale (recorded verbatim)

ruling_idstringargument

Reverse only: id of the active ruling to reopen

winner_categorystringargument

Override only: category of the explicit winner

winner_keystringargument

Override only: key of the explicit winner

Returns

Returns MCP content array (text, image, or embedded resource).

Audit Ruling (court of record)
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_audit_ruling",
    "arguments": {
        "action": "accept",
        "category": "facts",
        "decided_by": "operator",
        "entity_a_key": "string",
        "entity_b_key": "string",
        "rationale": "",
        "ruling_id": "string",
        "winner_category": "string",
        "winner_key": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_audit_ruling", {
  "action": "accept",
  "category": "facts",
  "decided_by": "operator",
  "entity_a_key": "string",
  "entity_b_key": "string",
  "rationale": "",
  "ruling_id": "string",
  "winner_category": "string",
  "winner_key": "string"
});
result = await session.call_tool("perseus_vault_audit_ruling", arguments={
  "action": "accept",
  "category": "facts",
  "decided_by": "operator",
  "entity_a_key": "string",
  "entity_b_key": "string",
  "rationale": "",
  "ruling_id": "string",
  "winner_category": "string",
  "winner_key": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Run Database Maintenance

destructive
TOOLperseus_vault_maintenance

Database maintenance operations: deduplicate entities with identical (category, key), detect orphan journal entries and links, vacuum (reclaim disk space), reindex FTS5, and enforce the entity_history retention policy (#398 — no-op unless PERSEUS_VAULT_HISTORY_* env knobs are set). Set dry_run=true to preview. Use 'all' to run everything.

Parameters

allbooleanfalseargument

Run all maintenance operations (dedup, orphans, vacuum, reindex, history retention)

dedupbooleanfalseargument

Find duplicate (category, key) entities and archive the oldest

dry_runbooleanfalseargument

If true, preview changes without writing

historybooleanfalseargument

Enforce the entity_history retention policy from PERSEUS_VAULT_HISTORY_* env knobs (#398; no-op while none are set)

orphansbooleanfalseargument

Detect journal entries and links pointing to non-existent entities

reindexbooleanfalseargument

Rebuild the FTS5 search index from entities table

vacuumbooleanfalseargument

Run SQLite VACUUM to reclaim disk space

Returns

dedup_archivedinteger

Number of duplicate entities archived

dry_runboolean
errorsArray<string>

Errors encountered during maintenance

history_bytes_evictedinteger

Stored history body bytes evicted (#398)

history_rows_evictedinteger

entity_history rows evicted by the retention policy (#398)

history_tombstones_writteninteger

Compaction tombstones written for evicted runs (#398)

orphan_journal_entries_foundinteger

Orphan journal entries detected

orphan_links_foundinteger

Orphan links detected

reindex_rows_affectedinteger

Rows reindexed into FTS5

vacuum_reclaimed_bytesinteger

Disk space reclaimed by VACUUM

Run Database Maintenance
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_maintenance",
    "arguments": {
        "all": false,
        "dedup": false,
        "dry_run": false,
        "history": false,
        "orphans": false,
        "reindex": false,
        "vacuum": false
      }
  }
}
const result = await client.callTool("perseus_vault_maintenance", {
  "all": false,
  "dedup": false,
  "dry_run": false,
  "history": false,
  "orphans": false,
  "reindex": false,
  "vacuum": false
});
result = await session.call_tool("perseus_vault_maintenance", arguments={
  "all": false,
  "dedup": false,
  "dry_run": false,
  "history": false,
  "orphans": false,
  "reindex": false,
  "vacuum": false
})
Response
{
  "dedup_archived": 0,
  "dry_run": true,
  "errors": [
    "string"
  ],
  "history_bytes_evicted": 0,
  "history_rows_evicted": 0,
  "history_tombstones_written": 0,
  "orphan_journal_entries_found": 0,
  "orphan_links_found": 0,
  "reindex_rows_affected": 0,
  "vacuum_reclaimed_bytes": 0
}

Detect Link-Graph Communities

idempotent
TOOLperseus_vault_communities

GraphRAG community detection: partition the entity link graph (built via perseus_vault_link) into communities using deterministic label propagation or greedy modularity ('louvain'). Persists the result with an extractive summary per community; community ids are derived from the member set, so re-detection after membership changes yields new ids. Local-first — no LLM or network required.

Parameters

algorithmstringlabel_proplouvainlabel_propargument

Detection algorithm: 'label_prop' (deterministic label propagation, default) or 'louvain' (greedy one-level modularity optimization).

min_sizeinteger2argument

Minimum member count for a community to be kept (minimum 2 — isolated entities never form communities).

workspace_hashstringargument

Workspace scope for the graph. Empty = global/unscoped entities.

Returns

algorithmstring
communitiesArray<object>
Show child attributes
idstring

Community id ('com-' + member-set digest)

member_idsArray<string>
sizeinteger
summarystring

Extractive summary (top members by in-community degree), capped in size

edge_countinteger

Undirected edges in the graph

generated_at_unix_msinteger
modularitynumber

Newman modularity of the detected partition

node_countinteger

Entities considered as graph nodes

stale_summaries_archivedinteger

Stale community_summary entities archived because membership changed

workspace_hashstring
Detect Link-Graph Communities
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_communities",
    "arguments": {
        "algorithm": "label_prop",
        "min_size": 2,
        "workspace_hash": ""
      }
  }
}
const result = await client.callTool("perseus_vault_communities", {
  "algorithm": "label_prop",
  "min_size": 2,
  "workspace_hash": ""
});
result = await session.call_tool("perseus_vault_communities", arguments={
  "algorithm": "label_prop",
  "min_size": 2,
  "workspace_hash": ""
})
Response
{
  "algorithm": "string",
  "communities": [
    {
      "id": "string",
      "member_ids": [
        "string"
      ],
      "size": 0,
      "summary": "string"
    }
  ],
  "edge_count": 0,
  "generated_at_unix_ms": 0,
  "modularity": 0,
  "node_count": 0,
  "stale_summaries_archived": 0,
  "workspace_hash": "string"
}

Get Community Summary

idempotent
TOOLperseus_vault_community_summary

Return (and materialize) the summary of one detected community. Default is the extractive summary (top representative members); set use_llm=true for an optional LLM polish that degrades back to extractive when no LLM endpoint is configured. The summary is stored as a 'community_summary' entity carrying evidence_for links to its members, and cached while membership is unchanged.

Parameters

community_idstringrequiredargument

Community id from perseus_vault_communities, e.g. 'com-1a2b3c4d5e6f7a8b'

refreshbooleanfalseargument

Force regeneration even when a cached summary entity exists.

use_llmbooleanfalseargument

Polish the summary with the configured LLM (--llm-endpoint). Never required: falls back to the extractive summary on error or when disabled.

Returns

cachedboolean

True when an existing summary entity was reused (membership unchanged)

community_idstring
llm_usedboolean
member_countinteger
summarystring
summary_entity_idstring

entities.id of the materialized community_summary entity

Get Community Summary
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_community_summary",
    "arguments": {
        "community_id": "string",
        "refresh": false,
        "use_llm": false
      }
  }
}
const result = await client.callTool("perseus_vault_community_summary", {
  "community_id": "string",
  "refresh": false,
  "use_llm": false
});
result = await session.call_tool("perseus_vault_community_summary", arguments={
  "community_id": "string",
  "refresh": false,
  "use_llm": false
})
Response
{
  "cached": true,
  "community_id": "string",
  "llm_used": true,
  "member_count": 0,
  "summary": "string",
  "summary_entity_id": "string"
}

Global Recall (GraphRAG)

TOOLperseus_vault_global_recall

GraphRAG global search: answer a broad 'what does the vault know about X, holistically' query by scoring it against community summaries first (breadth), then drilling into the best communities' member entities (depth). Cites entities across multiple communities instead of returning only the single nearest cluster like flat recall. Detects communities automatically on first use. Local-first and deterministic; optional use_llm synthesizes the final answer.

Parameters

auto_detectbooleantrueargument

Run community detection automatically when none are persisted yet

limitinteger10argument

Max member entities cited across all communities (round-robined so every matched community is represented)

querystringrequiredargument

The global question to answer across the whole memory graph

top_communitiesinteger3argument

How many best-matching communities to drill into

use_llmbooleanfalseargument

Synthesize the final answer with the configured LLM; degrades to the extractive answer on error or when disabled.

workspace_hashstringargument

Workspace scope. Empty = global/unscoped entities.

Returns

answerstring

Extractive (or LLM-synthesized) holistic answer citing entities across communities

communitiesArray<object>
Show child attributes
idstring
membersArray<object>
Show child attributes
categorystring
idstring
keystring
scorenumber
snippetstring
scorenumber

Distinct query-token hits in the community summary

sizeinteger
summarystring
communities_consideredinteger

Persisted communities scored in the breadth pass

llm_usedboolean
querystring
workspace_hashstring
Global Recall (GraphRAG)
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_global_recall",
    "arguments": {
        "auto_detect": true,
        "limit": 10,
        "query": "string",
        "top_communities": 3,
        "use_llm": false,
        "workspace_hash": ""
      }
  }
}
const result = await client.callTool("perseus_vault_global_recall", {
  "auto_detect": true,
  "limit": 10,
  "query": "string",
  "top_communities": 3,
  "use_llm": false,
  "workspace_hash": ""
});
result = await session.call_tool("perseus_vault_global_recall", arguments={
  "auto_detect": true,
  "limit": 10,
  "query": "string",
  "top_communities": 3,
  "use_llm": false,
  "workspace_hash": ""
})
Response
{
  "answer": "string",
  "communities": [
    {
      "id": "string",
      "members": [
        {
          "category": "string",
          "id": "string",
          "key": "string",
          "score": 0,
          "snippet": "string"
        }
      ],
      "score": 0,
      "size": 0,
      "summary": "string"
    }
  ],
  "communities_considered": 0,
  "llm_used": true,
  "query": "string",
  "workspace_hash": "string"
}

Set Keystone

TOOLperseus_vault_keystone_set

Author a Keystone — a mandatory policy rule that survives context compaction (#683). Unlike ordinary memories (retrieved when relevant), keystones are fetched deterministically at session start via perseus_vault_keystone_get, merged across scope, and are meant to be obeyed over any conflicting instruction (e.g. 'Every memory write MUST carry a retention class', 'Customer PII MUST NOT cross agent boundaries'). Higher weight wins on contradiction. Re-setting the same (scope, scope_id, content) updates it in place. Every mutation is appended to the cryptographic audit chain. Authoring is gated on trust tier: pass author_trust_tier (>= trust_tier_required, default 2). NOTE: until multi-agent trust tiers land (#684), author_trust_tier is caller-asserted; when omitted the write is allowed and the response flags that enforcement is pending.

Parameters

agent_idstringargument

Identity of the authoring agent, stamped on the keystone and its audit-chain event for provenance.

author_trust_tierintegerargument

The authoring agent's trust tier, checked against trust_tier_required. Caller-asserted until #684 wires per-agent trust + session identity.

contentstringrequiredargument

The policy rule text. Imperative, testable directives work best.

scopestringtenantargument

Merge scope: 'tenant' (org-wide), 'fleet' (a team), or 'agent' (an individual). Narrower scopes are layered on top of broader ones at get time.

scope_idstringargument

Identifier the keystone applies to within a non-tenant scope: the fleet_id ('fleet') or agent_id ('agent'). Omit/empty for tenant scope or 'all in scope'.

trust_tier_requiredinteger2argument

Minimum author trust tier permitted to set/modify this keystone. Defaults to 2 (per #684's tier model: tier 2 = write keystones).

weightnumber1argument

Conflict-resolution weight; on contradiction the higher-weight keystone wins. Also the merge/sort order returned by keystone_get.

workspace_hashstringargument

Optional workspace scope. Keystones with an empty workspace_hash are global (apply everywhere).

Returns

createdboolean

true if a new keystone was created, false if an existing one was updated

idstring
trust_enforcedboolean

false when author_trust_tier was omitted (enforcement pending #684)

Set Keystone
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_keystone_set",
    "arguments": {
        "agent_id": "string",
        "author_trust_tier": 0,
        "content": "string",
        "scope": "tenant",
        "scope_id": "string",
        "trust_tier_required": 2,
        "weight": 1,
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_keystone_set", {
  "agent_id": "string",
  "author_trust_tier": 0,
  "content": "string",
  "scope": "tenant",
  "scope_id": "string",
  "trust_tier_required": 2,
  "weight": 1,
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_keystone_set", arguments={
  "agent_id": "string",
  "author_trust_tier": 0,
  "content": "string",
  "scope": "tenant",
  "scope_id": "string",
  "trust_tier_required": 2,
  "weight": 1,
  "workspace_hash": "string"
})
Response
{
  "created": true,
  "id": "string",
  "trust_enforced": true
}

Get Keystones

TOOLperseus_vault_keystone_get

Fetch the merged Keystones (mandatory policy rules, #683) that apply at session start — the deterministic counterpart to recall. Returns rules ordered by weight (highest first, then scope tenant<fleet<agent, then id) so a renderer can inject them ahead of all other context and resolve contradictions by weight. Filter by scope/scope_id/workspace to get exactly the set an agent must obey. Read-only.

Parameters

scopestringargument

Optional: restrict to a single scope ('tenant' | 'fleet' | 'agent'). Omit to merge all scopes.

scope_idstringargument

Optional: with a non-tenant scope, restrict to this fleet_id/agent_id. Rules with an empty scope_id (scope-wide) are always included.

workspace_hashstringargument

Optional workspace scope. Global keystones (empty workspace_hash) are always included.

Returns

countinteger
keystonesArray<object>
Show child attributes
contentstring
idstring
scopestring
scope_idstring
weightnumber
Get Keystones
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_keystone_get",
    "arguments": {
        "scope": "string",
        "scope_id": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_keystone_get", {
  "scope": "string",
  "scope_id": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_keystone_get", arguments={
  "scope": "string",
  "scope_id": "string",
  "workspace_hash": "string"
})
Response
{
  "count": 0,
  "keystones": [
    {
      "content": "string",
      "id": "string",
      "scope": "string",
      "scope_id": "string",
      "weight": 0
    }
  ]
}

List Keystone Suggestions

TOOLperseus_vault_keystone_suggestions

List candidate directive/keystone suggestions (#889) extracted from correct captures by word-boundary-anchored patterns (en/de/ru/it/es). Suggestions are candidates only — never policy: promotion to the keystones table requires an explicit operator approve decision via perseus_vault_keystone_suggestion_decide. Each suggestion carries its source correction entity id for citation. Filter by status (pending/approved/rejected) and workspace; read-only.

Parameters

limitintegerargument

Max rows (1-1000). Default 50.

statusstringargument

Filter: '' (all), 'pending', 'approved', or 'rejected'. Default ''.

workspace_hashstringargument

Optional workspace scope filter.

Returns

countinteger
suggestionsArray<object>
List Keystone Suggestions
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_keystone_suggestions",
    "arguments": {
        "limit": 0,
        "status": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_keystone_suggestions", {
  "limit": 0,
  "status": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_keystone_suggestions", arguments={
  "limit": 0,
  "status": "string",
  "workspace_hash": "string"
})
Response
{
  "count": 0,
  "suggestions": [
    {}
  ]
}

Decide Keystone Suggestion

TOOLperseus_vault_keystone_suggestion_decide

Decide a keystone-suggestion candidate (#889): 'approve' promotes the suggestion's instruction into the keystones table (re-running the #683/#684 trust-tier gate — authoring requires tier >= trust_tier_required) and marks the suggestion approved; 'reject' marks it rejected and writes nothing. Extraction never writes policy — this explicit operator decision is the only promotion path.

Parameters

actionstringrequiredargument

'approve' (promote to keystone) or 'reject'.

agent_idstringargument

Author agent id (registry-backed tier wins when registered).

author_trust_tierintegerargument

Caller-asserted tier (used when the agent is not registry-registered).

idstringrequiredargument

Suggestion id (ksug-...).

scopestringargument

Keystone scope: 'tenant' | 'fleet' | 'agent'. Default 'agent'.

scope_idstringargument

Keystone scope_id; defaults to agent_id.

trust_tier_requiredintegerargument

Minimum authoring tier. Default 2.

weightnumberargument

Conflict-resolution weight. Default 1.0.

workspace_hashstringargument

Must match the suggestion's own workspace.

Returns

keystone_idstring
okboolean
suggestion_statusstring
Decide Keystone Suggestion
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_keystone_suggestion_decide",
    "arguments": {
        "action": "string",
        "agent_id": "string",
        "author_trust_tier": 0,
        "id": "string",
        "scope": "string",
        "scope_id": "string",
        "trust_tier_required": 0,
        "weight": 0,
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_keystone_suggestion_decide", {
  "action": "string",
  "agent_id": "string",
  "author_trust_tier": 0,
  "id": "string",
  "scope": "string",
  "scope_id": "string",
  "trust_tier_required": 0,
  "weight": 0,
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_keystone_suggestion_decide", arguments={
  "action": "string",
  "agent_id": "string",
  "author_trust_tier": 0,
  "id": "string",
  "scope": "string",
  "scope_id": "string",
  "trust_tier_required": 0,
  "weight": 0,
  "workspace_hash": "string"
})
Response
{
  "keystone_id": "string",
  "ok": true,
  "suggestion_status": "string"
}

Agent Registry

TOOLperseus_vault_agent

Register/update or look up an agent in the multi-agent registry (#684). Agents carry a trust tier (0-3) that gates sensitive ops (e.g. authoring keystones needs tier >= 2) and drives visibility enforcement on recall: tier 0 = read own only, 1 = fleet, 2 = read all + write keystones, 3 = admin. Pass trust_tier (and optionally name/fleet_id) to upsert; omit trust_tier to just look up. entities/journal already stamp agent_id (v1.2.0); this adds the identity + tier metadata. NOTE: an empty/unknown agent has no registry row — unknown identified agents resolve to tier 0, and a caller with no session identity is unscoped.

Parameters

agent_idstringrequiredargument

The agent's stable identifier (e.g. the MCP clientInfo name).

fleet_idstringargument

Fleet/team the agent belongs to (used for 'fleet' visibility). Upsert only.

namestringargument

Human-readable name (upsert only).

trust_tierintegerargument

Trust tier 0-3. Provide to upsert; omit to look up. Clamped to [0,3].

Returns

agentobject
Show child attributes
agent_idstring
fleet_idstring
namestring
trust_tierinteger
createdboolean

true if an upsert created a new registry row

foundboolean
Agent Registry
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_agent",
    "arguments": {
        "agent_id": "string",
        "fleet_id": "string",
        "name": "string",
        "trust_tier": 0
      }
  }
}
const result = await client.callTool("perseus_vault_agent", {
  "agent_id": "string",
  "fleet_id": "string",
  "name": "string",
  "trust_tier": 0
});
result = await session.call_tool("perseus_vault_agent", arguments={
  "agent_id": "string",
  "fleet_id": "string",
  "name": "string",
  "trust_tier": 0
})
Response
{
  "agent": {
    "agent_id": "string",
    "fleet_id": "string",
    "name": "string",
    "trust_tier": 0
  },
  "created": true,
  "found": true
}

Set Action Authority

TOOLperseus_vault_authority_set

Create a versioned authority manifest for a registered agent.

Parameters

agent_idstringrequiredargument
allowed_capabilitiesArray<string>requiredargument
allowed_inbound_principalsArray<string>argument
approval_required_capabilitiesArray<string>argument
approver_principalsArray<string>argument
author_agent_idstringargument
capability_constraints_jsonstring{}argument
expires_at_unix_msintegerargument
max_parallel_actionsinteger1argument
modestringshadowargument
permitted_external_ref_prefixesArray<string>argument
scope_anchorsArray<string>requiredargument
workspace_hashstringrequiredargument

Returns

Returns MCP content array (text, image, or embedded resource).

Set Action Authority
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_authority_set",
    "arguments": {
        "agent_id": "string",
        "allowed_capabilities": [
          "string"
        ],
        "allowed_inbound_principals": [
          "string"
        ],
        "approval_required_capabilities": [
          "string"
        ],
        "approver_principals": [
          "string"
        ],
        "author_agent_id": "string",
        "capability_constraints_json": "{}",
        "expires_at_unix_ms": 0,
        "max_parallel_actions": 1,
        "mode": "shadow",
        "permitted_external_ref_prefixes": [
          "string"
        ],
        "scope_anchors": [
          "string"
        ],
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_authority_set", {
  "agent_id": "string",
  "allowed_capabilities": [
    "string"
  ],
  "allowed_inbound_principals": [
    "string"
  ],
  "approval_required_capabilities": [
    "string"
  ],
  "approver_principals": [
    "string"
  ],
  "author_agent_id": "string",
  "capability_constraints_json": "{}",
  "expires_at_unix_ms": 0,
  "max_parallel_actions": 1,
  "mode": "shadow",
  "permitted_external_ref_prefixes": [
    "string"
  ],
  "scope_anchors": [
    "string"
  ],
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_authority_set", arguments={
  "agent_id": "string",
  "allowed_capabilities": [
    "string"
  ],
  "allowed_inbound_principals": [
    "string"
  ],
  "approval_required_capabilities": [
    "string"
  ],
  "approver_principals": [
    "string"
  ],
  "author_agent_id": "string",
  "capability_constraints_json": "{}",
  "expires_at_unix_ms": 0,
  "max_parallel_actions": 1,
  "mode": "shadow",
  "permitted_external_ref_prefixes": [
    "string"
  ],
  "scope_anchors": [
    "string"
  ],
  "workspace_hash": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Get Action Authority

TOOLperseus_vault_authority_get

Get the active authority manifest for an agent and workspace.

Parameters

agent_idstringrequiredargument
include_revokedbooleanfalseargument
workspace_hashstringrequiredargument

Returns

Returns MCP content array (text, image, or embedded resource).

Get Action Authority
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_authority_get",
    "arguments": {
        "agent_id": "string",
        "include_revoked": false,
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_authority_get", {
  "agent_id": "string",
  "include_revoked": false,
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_authority_get", arguments={
  "agent_id": "string",
  "include_revoked": false,
  "workspace_hash": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Revoke Action Authority

TOOLperseus_vault_authority_revoke

Revoke an authority manifest.

Parameters

actor_agent_idstringargument
manifest_idstringrequiredargument
reasonstringargument

Returns

Returns MCP content array (text, image, or embedded resource).

Revoke Action Authority
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_authority_revoke",
    "arguments": {
        "actor_agent_id": "string",
        "manifest_id": "string",
        "reason": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_authority_revoke", {
  "actor_agent_id": "string",
  "manifest_id": "string",
  "reason": "string"
});
result = await session.call_tool("perseus_vault_authority_revoke", arguments={
  "actor_agent_id": "string",
  "manifest_id": "string",
  "reason": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Load Signed Authority Profile

TOOLperseus_vault_authority_set_signed

Load a signed, distributable policy/authority profile (Ed25519 sigstore-style attestation); verification failure grants no authority (fail closed) and the verification result lands in the ledger journal.

Parameters

author_agent_idstringrequiredargument
profile_jsonstringrequiredargument
trusted_public_key_b64stringrequiredargument

Returns

Returns MCP content array (text, image, or embedded resource).

Load Signed Authority Profile
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_authority_set_signed",
    "arguments": {
        "author_agent_id": "string",
        "profile_json": "string",
        "trusted_public_key_b64": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_authority_set_signed", {
  "author_agent_id": "string",
  "profile_json": "string",
  "trusted_public_key_b64": "string"
});
result = await session.call_tool("perseus_vault_authority_set_signed", arguments={
  "author_agent_id": "string",
  "profile_json": "string",
  "trusted_public_key_b64": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Record Action Intent

TOOLperseus_vault_action_intent

Record a fail-closed authorized action intent.

Body

application/json
action_keystringrequired
agent_idstringrequired
capabilitystringrequired
external_refstringrequired
intent_hashstringrequired
justification_entity_idsArray<string>

#1029: entity ids this action cites as grounding (must reference existing rows; the supersession impact index flags PENDING actions whose cited facts later changed)

lineageobject

#1134: versioned hash-only task/action-lineage transition; continuation is explicit

Show child attributes
action_classstringreadexternal_sendwritedeleteotherrequired
budget_costinteger[0, 1000000]required
continuationobject
Show child attributes
agent_idstringrequired
authority_manifest_versioninteger>= 1required
continuation_state_digeststringrequired
lineage_idstringrequired
parent_head_digeststringrequired
policy_versionstringrequired
schema_versionintegerrequired
workspace_hashstringrequired
impact_unitsinteger[0, 1000000]required
schema_versionintegerrequired
transitionstringcontinuenew_authorizationrequired
resource_constraints_jsonstring{}
scope_anchorstringrequired
workspace_hashstringrequired

Returns

Returns MCP content array (text, image, or embedded resource).

Record Action Intent
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_action_intent",
    "arguments": {
        "action_key": "string",
        "agent_id": "string",
        "capability": "string",
        "external_ref": "string",
        "intent_hash": "string",
        "justification_entity_ids": [
          "string"
        ],
        "lineage": {
          "action_class": "read",
          "budget_cost": 0,
          "continuation": {
            "agent_id": "string",
            "authority_manifest_version": 1,
            "continuation_state_digest": "string",
            "lineage_id": "string",
            "parent_head_digest": "string",
            "policy_version": "string",
            "schema_version": 1,
            "workspace_hash": "string"
          },
          "impact_units": 0,
          "schema_version": 1,
          "transition": "continue"
        },
        "resource_constraints_json": "{}",
        "scope_anchor": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_action_intent", {
  "action_key": "string",
  "agent_id": "string",
  "capability": "string",
  "external_ref": "string",
  "intent_hash": "string",
  "justification_entity_ids": [
    "string"
  ],
  "lineage": {
    "action_class": "read",
    "budget_cost": 0,
    "continuation": {
      "agent_id": "string",
      "authority_manifest_version": 1,
      "continuation_state_digest": "string",
      "lineage_id": "string",
      "parent_head_digest": "string",
      "policy_version": "string",
      "schema_version": 1,
      "workspace_hash": "string"
    },
    "impact_units": 0,
    "schema_version": 1,
    "transition": "continue"
  },
  "resource_constraints_json": "{}",
  "scope_anchor": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_action_intent", arguments={
  "action_key": "string",
  "agent_id": "string",
  "capability": "string",
  "external_ref": "string",
  "intent_hash": "string",
  "justification_entity_ids": [
    "string"
  ],
  "lineage": {
    "action_class": "read",
    "budget_cost": 0,
    "continuation": {
      "agent_id": "string",
      "authority_manifest_version": 1,
      "continuation_state_digest": "string",
      "lineage_id": "string",
      "parent_head_digest": "string",
      "policy_version": "string",
      "schema_version": 1,
      "workspace_hash": "string"
    },
    "impact_units": 0,
    "schema_version": 1,
    "transition": "continue"
  },
  "resource_constraints_json": "{}",
  "scope_anchor": "string",
  "workspace_hash": "string"
})
Request Body
{
  "action_key": "string",
  "agent_id": "string",
  "capability": "string",
  "external_ref": "string",
  "intent_hash": "string",
  "justification_entity_ids": [
    "string"
  ],
  "lineage": {
    "action_class": "read",
    "budget_cost": 0,
    "continuation": {
      "agent_id": "string",
      "authority_manifest_version": 1,
      "continuation_state_digest": "string",
      "lineage_id": "string",
      "parent_head_digest": "string",
      "policy_version": "string",
      "schema_version": 1,
      "workspace_hash": "string"
    },
    "impact_units": 0,
    "schema_version": 1,
    "transition": "continue"
  },
  "resource_constraints_json": "{}",
  "scope_anchor": "string",
  "workspace_hash": "string"
}
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Decide Action Approval

TOOLperseus_vault_action_approve

Grant or deny an approval-requested action.

Parameters

action_idstringrequiredargument
approver_principalstringrequiredargument
decisionstringgranteddeniedrequiredargument

Returns

Returns MCP content array (text, image, or embedded resource).

Decide Action Approval
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_action_approve",
    "arguments": {
        "action_id": "string",
        "approver_principal": "string",
        "decision": "granted"
      }
  }
}
const result = await client.callTool("perseus_vault_action_approve", {
  "action_id": "string",
  "approver_principal": "string",
  "decision": "granted"
});
result = await session.call_tool("perseus_vault_action_approve", arguments={
  "action_id": "string",
  "approver_principal": "string",
  "decision": "granted"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Complete Authorized Action

TOOLperseus_vault_action_complete

Record an executed, failed, cancelled, or denied action outcome by hash.

Parameters

action_idstringrequiredargument
actor_agent_idstringrequiredargument
outcomestringexecutedfailedcancelleddeniedrequiredargument
outcome_hashstringrequiredargument

Returns

Returns MCP content array (text, image, or embedded resource).

Complete Authorized Action
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_action_complete",
    "arguments": {
        "action_id": "string",
        "actor_agent_id": "string",
        "outcome": "executed",
        "outcome_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_action_complete", {
  "action_id": "string",
  "actor_agent_id": "string",
  "outcome": "executed",
  "outcome_hash": "string"
});
result = await session.call_tool("perseus_vault_action_complete", arguments={
  "action_id": "string",
  "actor_agent_id": "string",
  "outcome": "executed",
  "outcome_hash": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Resolve Approval Timeout

TOOLperseus_vault_action_resolve_timeout

Resolve a pending approval to deny once its window has expired (timeout defaults to deny).

Parameters

action_idstringrequiredargument
approval_timeout_msintegerrequiredargument

Returns

Returns MCP content array (text, image, or embedded resource).

Resolve Approval Timeout
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_action_resolve_timeout",
    "arguments": {
        "action_id": "string",
        "approval_timeout_ms": 0
      }
  }
}
const result = await client.callTool("perseus_vault_action_resolve_timeout", {
  "action_id": "string",
  "approval_timeout_ms": 0
});
result = await session.call_tool("perseus_vault_action_resolve_timeout", arguments={
  "action_id": "string",
  "approval_timeout_ms": 0
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Get Action Receipt

TOOLperseus_vault_action_receipt_get

Get durable action receipt metadata and hashes.

Parameters

action_idstringrequiredargument

Returns

Returns MCP content array (text, image, or embedded resource).

Get Action Receipt
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_action_receipt_get",
    "arguments": {
        "action_id": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_action_receipt_get", {
  "action_id": "string"
});
result = await session.call_tool("perseus_vault_action_receipt_get", arguments={
  "action_id": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Acquire Action Lease

TOOLperseus_vault_action_lease_acquire

Acquire the single active lease for an action key.

Parameters

action_idstringrequiredargument
holder_idstringrequiredargument
ttl_secondsinteger1argument

Returns

Returns MCP content array (text, image, or embedded resource).

Acquire Action Lease
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_action_lease_acquire",
    "arguments": {
        "action_id": "string",
        "holder_id": "string",
        "ttl_seconds": 1
      }
  }
}
const result = await client.callTool("perseus_vault_action_lease_acquire", {
  "action_id": "string",
  "holder_id": "string",
  "ttl_seconds": 1
});
result = await session.call_tool("perseus_vault_action_lease_acquire", arguments={
  "action_id": "string",
  "holder_id": "string",
  "ttl_seconds": 1
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Release Action Lease

TOOLperseus_vault_action_lease_release

Release an action lease held by its owner.

Parameters

holder_idstringrequiredargument
lease_idstringrequiredargument

Returns

Returns MCP content array (text, image, or embedded resource).

Release Action Lease
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_action_lease_release",
    "arguments": {
        "holder_id": "string",
        "lease_id": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_action_lease_release", {
  "holder_id": "string",
  "lease_id": "string"
});
result = await session.call_tool("perseus_vault_action_lease_release", arguments={
  "holder_id": "string",
  "lease_id": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Validate Runtime Stage Trace

TOOLperseus_vault_stage_trace_validate

Validate a versioned hash-only runtime stage trace and optionally compare replay semantics. Raw prompts, memory bodies, credentials, and tool payloads are not accepted.

Parameters

replay_ofobjectargument

Optional second trace to compare by replay fingerprint

traceobjectrequiredargument

perseus-vault-stage-trace/v1 structured trace

Returns

Returns MCP content array (text, image, or embedded resource).

Validate Runtime Stage Trace
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_stage_trace_validate",
    "arguments": {
        "replay_of": {},
        "trace": {}
      }
  }
}
const result = await client.callTool("perseus_vault_stage_trace_validate", {
  "replay_of": {},
  "trace": {}
});
result = await session.call_tool("perseus_vault_stage_trace_validate", arguments={
  "replay_of": {},
  "trace": {}
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Validate Context Transform

TOOLperseus_vault_context_transform_validate

#1106: validate a versioned context-transformer proposal at the provider boundary. Returns only a hash-only receipt, bounded changed-span metadata, explicit outcome/lossiness, and replay/original references; raw messages, prompts, memory bodies, credentials, and tool payloads are not returned.

Body

application/json
proposed_outputArray<object>required

Transient proposed provider messages; never returned in the response

proposed_output_tokensinteger>= 0
requestobjectrequired

perseus-vault-context-transformer/v1 request metadata and transient input_messages

Returns

Returns MCP content array (text, image, or embedded resource).

Validate Context Transform
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_context_transform_validate",
    "arguments": {
        "proposed_output": [
          {}
        ],
        "proposed_output_tokens": 0,
        "request": {}
      }
  }
}
const result = await client.callTool("perseus_vault_context_transform_validate", {
  "proposed_output": [
    {}
  ],
  "proposed_output_tokens": 0,
  "request": {}
});
result = await session.call_tool("perseus_vault_context_transform_validate", arguments={
  "proposed_output": [
    {}
  ],
  "proposed_output_tokens": 0,
  "request": {}
})
Request Body
{
  "proposed_output": [
    {}
  ],
  "proposed_output_tokens": 0,
  "request": {}
}
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Reject Value

TOOLperseus_vault_reject_value

Record a scoped digest-only rejected-value tombstone. Equivalent values remain rejected across new entity keys and writer paths until the tombstone expires or is explicitly superseded.

Parameters

author_agent_idstringargument
evidence_refstringargument
expires_at_unix_msintegerargument
predicatestringrequiredargument
reasonstringargument
subjectstringrequiredargument
valuestringrequiredargument

Normalized only for matching; the value is not stored.

workspace_hashstringrequiredargument

Workspace scope; empty means global.

Returns

Returns MCP content array (text, image, or embedded resource).

Reject Value
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_reject_value",
    "arguments": {
        "author_agent_id": "string",
        "evidence_ref": "string",
        "expires_at_unix_ms": 0,
        "predicate": "string",
        "reason": "string",
        "subject": "string",
        "value": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_reject_value", {
  "author_agent_id": "string",
  "evidence_ref": "string",
  "expires_at_unix_ms": 0,
  "predicate": "string",
  "reason": "string",
  "subject": "string",
  "value": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_reject_value", arguments={
  "author_agent_id": "string",
  "evidence_ref": "string",
  "expires_at_unix_ms": 0,
  "predicate": "string",
  "reason": "string",
  "subject": "string",
  "value": "string",
  "workspace_hash": "string"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Audit Extraction Loss (Residual Spans)

TOOLperseus_vault_span_audit

Extraction-loss net (#1048): audit an entity for fact-bearing sentences its extracted claims missed, retaining them verbatim as residual spans with provenance (embedding-first similarity, token fallback — no extra LLM call). Append-only; re-audits never duplicate. Spans are regular, decay/hygiene-subject memory state — never auto-served into recall.

Parameters

coverage_thresholdnumber0.55argument

Max claim-similarity below which a sentence is residual

entity_idstringrequiredargument

Entity id to audit

min_charsinteger12argument

Minimum sentence length in chars to consider

modestringautoargument

Similarity backend: auto | embedding | token

Returns

claimsinteger
entity_idstring
mode_usedstring
spansArray<object>
spans_ninteger
Audit Extraction Loss (Residual Spans)
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_span_audit",
    "arguments": {
        "coverage_threshold": 0.55,
        "entity_id": "string",
        "min_chars": 12,
        "mode": "auto"
      }
  }
}
const result = await client.callTool("perseus_vault_span_audit", {
  "coverage_threshold": 0.55,
  "entity_id": "string",
  "min_chars": 12,
  "mode": "auto"
});
result = await session.call_tool("perseus_vault_span_audit", arguments={
  "coverage_threshold": 0.55,
  "entity_id": "string",
  "min_chars": 12,
  "mode": "auto"
})
Response
{
  "claims": 0,
  "entity_id": "string",
  "mode_used": "string",
  "spans": [
    {}
  ],
  "spans_n": 0
}

Report Refusal (Retry Payload)

TOOLperseus_vault_report_refusal

Extraction-loss net (#1048): an answerer's refusal over a served payload is evidence. Re-scores the served entities' residual spans against the original query and returns a retry payload (spans whose query-similarity beats the entity's own by a margin — the anomaly rule). Units with no retry material accumulate lossy marks; at the threshold they are flagged for repair-on-touch.

Parameters

querystringrequiredargument

The query the answerer could not answer

reasonstringargument

Optional refusal reason (kept for the journal)

served_idsArray<string>requiredargument

Entity ids that were in the served payload

Returns

lossy_flaggedArray<object>
marginnumber
retryArray<object>
retry_ninteger
Report Refusal (Retry Payload)
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_report_refusal",
    "arguments": {
        "query": "string",
        "reason": "string",
        "served_ids": [
          "string"
        ]
      }
  }
}
const result = await client.callTool("perseus_vault_report_refusal", {
  "query": "string",
  "reason": "string",
  "served_ids": [
    "string"
  ]
});
result = await session.call_tool("perseus_vault_report_refusal", arguments={
  "query": "string",
  "reason": "string",
  "served_ids": [
    "string"
  ]
})
Response
{
  "lossy_flagged": [
    {}
  ],
  "margin": 0,
  "retry": [
    {}
  ],
  "retry_n": 0
}

Report Success (Confirm Query Key)

TOOLperseus_vault_report_success

Extraction-loss net (#1048): confirm a retry payload answered the query. Attaches a provisional query key (query fingerprint to entity ids) so an identical repeat query serves first-pass; served spans become confirmed; lossy units are cleared to repaired. The binding is durable until superseded by another report_success for the same query.

Parameters

entity_idsArray<string>requiredargument

Entity ids that carried the answer

querystringrequiredargument

The query that was answered

Returns

confirmedboolean
entity_idsArray<string>
query_fingerprintstring
spans_confirmedinteger
Report Success (Confirm Query Key)
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_report_success",
    "arguments": {
        "entity_ids": [
          "string"
        ],
        "query": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_report_success", {
  "entity_ids": [
    "string"
  ],
  "query": "string"
});
result = await session.call_tool("perseus_vault_report_success", arguments={
  "entity_ids": [
    "string"
  ],
  "query": "string"
})
Response
{
  "confirmed": true,
  "entity_ids": [
    "string"
  ],
  "query_fingerprint": "string",
  "spans_confirmed": 0
}

Dependency-Guided Rollback Repair

TOOLperseus_vault_rollback_repair

#1084 (arXiv:2608.10502): dependency-guided rollback repair for poisoned/stale memories. Builds a typed memory→action dependency graph from runtime provenance, preserves dependents with independent trusted support, tombstones unsupported state (quarantine — never deletes), and reports a scoped selective-replay proposal. Every step is journal-receipted and the repair is reversible (reverse_repair_id).

Parameters

dry_runbooleanfalseargument

Report the plan without writing

faulty_idsArray<string>requiredargument

Diagnosed faulty entity ids

replaybooleanfalseargument

Include a scoped selective-replay proposal (dry-run consolidation over the affected category/workspace)

reverse_repair_idstringargument

When set, reverse this previously recorded repair instead of running a new one

workspace_hashstringargument

Optional workspace scope hint

Returns

dry_runboolean
faultyArray<string>
preservedArray<object>
repair_idstring
replayobject
rollbackobject
tombstonedArray<string>
Dependency-Guided Rollback Repair
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_rollback_repair",
    "arguments": {
        "dry_run": false,
        "faulty_ids": [
          "string"
        ],
        "replay": false,
        "reverse_repair_id": "string",
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_rollback_repair", {
  "dry_run": false,
  "faulty_ids": [
    "string"
  ],
  "replay": false,
  "reverse_repair_id": "string",
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_rollback_repair", arguments={
  "dry_run": false,
  "faulty_ids": [
    "string"
  ],
  "replay": false,
  "reverse_repair_id": "string",
  "workspace_hash": "string"
})
Response
{
  "dry_run": true,
  "faulty": [
    "string"
  ],
  "preserved": [
    {}
  ],
  "repair_id": "string",
  "replay": {},
  "rollback": {},
  "tombstoned": [
    "string"
  ]
}

Set Signer Epoch Key

TOOLperseus_vault_signer_epoch_set

#1080 (MutMem): register or replace the Ed25519 signing key for a signer epoch — the authorization root for signed transitions. The seed (32 raw bytes, base64) is stored at rest alongside the database (same trust domain as the AES key file) and never echoed back. Ops scope.

Parameters

epochinteger>= 1requiredargument

Signer epoch number (key generation era)

seed_b64stringrequiredargument

Raw 32-byte Ed25519 seed, base64-encoded

Returns

registered_epochinteger
signer_fingerprintstring
Set Signer Epoch Key
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_signer_epoch_set",
    "arguments": {
        "epoch": 1,
        "seed_b64": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_signer_epoch_set", {
  "epoch": 1,
  "seed_b64": "string"
});
result = await session.call_tool("perseus_vault_signer_epoch_set", arguments={
  "epoch": 1,
  "seed_b64": "string"
})
Response
{
  "registered_epoch": 0,
  "signer_fingerprint": "string"
}

Set Poison Label

TOOLperseus_vault_poison_label

#1080 (MutMem): set or revise a SIGNED poison label on a stored entity. Poison-likely content is retained (never silently deleted); recall consumes the label as trust evidence (poison_likely −90% effective score, suspect −50%, clean = restored). Every label write commits as a signed transition — fails closed when no signer epoch is registered.

Parameters

entity_idstringrequiredargument

Entity to label

levelstringpoison_likelysuspectcleanrequiredargument
reasonstringargument

Attribution for the label (recorded in the signed transition)

Returns

entity_idstring
levelstring
reasonstring
transitionobject
Set Poison Label
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_poison_label",
    "arguments": {
        "entity_id": "string",
        "level": "poison_likely",
        "reason": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_poison_label", {
  "entity_id": "string",
  "level": "poison_likely",
  "reason": "string"
});
result = await session.call_tool("perseus_vault_poison_label", arguments={
  "entity_id": "string",
  "level": "poison_likely",
  "reason": "string"
})
Response
{
  "entity_id": "string",
  "level": "string",
  "reason": "string",
  "transition": {}
}

Audit Signed Transition Chain

read-only
TOOLperseus_vault_transition_audit

#1080 (MutMem): replay the signed-transition chain end to end — every record must verify against its epoch key, link to the previous chain hash (no forks), and reproduce its own chain hash. Reports record count, verified count, chain head, and the first divergence (if any).

Returns

chain_headstring
divergenceobject
notestring
recordsinteger
verifiedinteger
Audit Signed Transition Chain
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_transition_audit",
    "arguments": {}
  }
}
const result = await client.callTool("perseus_vault_transition_audit", {});
result = await session.call_tool("perseus_vault_transition_audit", arguments={})
Response
{
  "chain_head": "string",
  "divergence": {},
  "note": "string",
  "records": 0,
  "verified": 0
}

Define Retrieval Skill

TOOLperseus_vault_skill_set

#1090 (ERSkill, arXiv:2608.12720): define or version a retrieval skill — a validated parameterization of recall primitives (mode, typed filters, trust/content weights, recency). New versions always enter the expansion frontier (double-frontier deployment): they never affect routing until a governed advancement.

Parameters

namestringargument
profileobjectargument

Router affinity weights: base/recent/negation/question/type_hint/long_query

skill_idstringrequiredargument
templateobjectrequiredargument

Skill template: mode (fts5|dense|hybrid|fused), limit 1..50, optional category/type_filter/layer/epistemic_state/weights

versioninteger>= 1requiredargument

Returns

definedboolean
frontierstring
receiptstring
skill_idstring
versioninteger
Define Retrieval Skill
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_skill_set",
    "arguments": {
        "name": "string",
        "profile": {},
        "skill_id": "string",
        "template": {},
        "version": 1
      }
  }
}
const result = await client.callTool("perseus_vault_skill_set", {
  "name": "string",
  "profile": {},
  "skill_id": "string",
  "template": {},
  "version": 1
});
result = await session.call_tool("perseus_vault_skill_set", arguments={
  "name": "string",
  "profile": {},
  "skill_id": "string",
  "template": {},
  "version": 1
})
Response
{
  "defined": true,
  "frontier": "string",
  "receipt": "string",
  "skill_id": "string",
  "version": 0
}

Route Retrieval Query

TOOLperseus_vault_skill_route

#1090 (ERSkill): deterministic per-query routing over the SERVING frontier only — feature-based scoring, ties break by skill id. With serve=true the chosen skill executes (recall with its template) and the explored path is logged into the experience trie (skill id × query fingerprint × outcome).

Parameters

querystringrequiredargument
servebooleanfalseargument

Returns

entitiesArray<object>
scorenumber
servedboolean
skill_idstring
skill_versioninteger
Route Retrieval Query
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_skill_route",
    "arguments": {
        "query": "string",
        "serve": false
      }
  }
}
const result = await client.callTool("perseus_vault_skill_route", {
  "query": "string",
  "serve": false
});
result = await session.call_tool("perseus_vault_skill_route", arguments={
  "query": "string",
  "serve": false
})
Response
{
  "entities": [
    {}
  ],
  "score": 0,
  "served": true,
  "skill_id": "string",
  "skill_version": 0
}

Advance Retrieval Skill Frontier

TOOLperseus_vault_skill_advance

#1090 (ERSkill): governed double-frontier transition. advance (expansion→serving) REQUIRES non-regression evidence (wins/losses/ties + recall_delta) and is refused fail-closed on regression; demote (serving→expansion) is the governed rollback. Every transition is receipt-anchored and bumps the serving version.

Parameters

directionstringadvancedemoterequiredargument
evidenceobjectargument

eval_ref, wins, losses, ties, recall_delta

skill_idstringrequiredargument

Returns

acceptedboolean
frontierstring
reasonstring
receiptstring
serving_versioninteger
skill_idstring
Advance Retrieval Skill Frontier
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_skill_advance",
    "arguments": {
        "direction": "advance",
        "evidence": {},
        "skill_id": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_skill_advance", {
  "direction": "advance",
  "evidence": {},
  "skill_id": "string"
});
result = await session.call_tool("perseus_vault_skill_advance", arguments={
  "direction": "advance",
  "evidence": {},
  "skill_id": "string"
})
Response
{
  "accepted": true,
  "frontier": "string",
  "reason": "string",
  "receipt": "string",
  "serving_version": 0,
  "skill_id": "string"
}

Audit Retrieval Skills

read-only
TOOLperseus_vault_skill_audit

#1090 (ERSkill): read-only audit of the skill registry — definitions by frontier, serving version, experience-trie stats per skill, and the receipt trail (definitions, advancements, refusals).

Returns

experience_statsobject
receiptsArray<object>
serving_versionobject
skillsArray<object>
Audit Retrieval Skills
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_skill_audit",
    "arguments": {}
  }
}
const result = await client.callTool("perseus_vault_skill_audit", {});
result = await session.call_tool("perseus_vault_skill_audit", arguments={})
Response
{
  "experience_stats": {},
  "receipts": [
    {}
  ],
  "serving_version": {},
  "skills": [
    {}
  ]
}

Audit Temporal Decay

read-only
TOOLperseus_vault_decay_audit

#1091 (ScrubJay-MEM, arXiv:2608.04746): audit type-conditioned temporal decay — the deterministic perishability/utility-horizon profile table per memory type plus population aggregates (count, mean decay, mean age, past-horizon rows excluded from default recall).

Returns

generated_at_unix_msinteger
notestring
populationArray<object>
profilesArray<object>
Audit Temporal Decay
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_decay_audit",
    "arguments": {}
  }
}
const result = await client.callTool("perseus_vault_decay_audit", {});
result = await session.call_tool("perseus_vault_decay_audit", arguments={})
Response
{
  "generated_at_unix_ms": 0,
  "note": "string",
  "population": [
    {}
  ],
  "profiles": [
    {}
  ]
}

Segment-Level Consolidation

TOOLperseus_vault_segment_consolidate

#1088 (LycheeMemory V2, arXiv:2608.12990): semantic segment-level consolidation — batch entities into semantic segments via deterministic boundary detection (inter-arrival gap + adjacent trigram discontinuity, never fixed windows), then run ONE bounded consolidate pass per finalized segment (>=2 members). Construction frequency is segment-count-bound, not write-count-bound. Segment plans are indexed under state keys segment_plan..

Parameters

categorystringrequiredargument

Category to consolidate

dry_runbooleanfalseargument

Report plans without writing

gap_msinteger>= 021600000argument

Inter-arrival gap in ms that starts a new segment

max_entitiesinteger[1, 5000]1000argument

Scan cap

sim_floornumber[0, 1]0.25argument

Adjacent trigram similarity below which a new segment starts

workspace_hashstringrequiredargument

Workspace scope (required — ordinary runs are workspace-scoped)

Returns

categorystring
consolidatedinteger
consolidationsArray<object>
dry_runboolean
plansArray<object>
scannedinteger
segmentsinteger
skipped_singletonsinteger
workspace_hashstring
Segment-Level Consolidation
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_segment_consolidate",
    "arguments": {
        "category": "string",
        "dry_run": false,
        "gap_ms": 21600000,
        "max_entities": 1000,
        "sim_floor": 0.25,
        "workspace_hash": "string"
      }
  }
}
const result = await client.callTool("perseus_vault_segment_consolidate", {
  "category": "string",
  "dry_run": false,
  "gap_ms": 21600000,
  "max_entities": 1000,
  "sim_floor": 0.25,
  "workspace_hash": "string"
});
result = await session.call_tool("perseus_vault_segment_consolidate", arguments={
  "category": "string",
  "dry_run": false,
  "gap_ms": 21600000,
  "max_entities": 1000,
  "sim_floor": 0.25,
  "workspace_hash": "string"
})
Response
{
  "category": "string",
  "consolidated": 0,
  "consolidations": [
    {}
  ],
  "dry_run": true,
  "plans": [
    {}
  ],
  "scanned": 0,
  "segments": 0,
  "skipped_singletons": 0,
  "workspace_hash": "string"
}

Audit State Staleness

TOOLperseus_vault_state_audit

#1093 (STALE/StateAuditor, arXiv:2608.01619): audit state-table entries for implicit stale-dependency drift (sleep proposals whose entities vanished, experience-stats drift, cached entity-count drift, shadow-promote records) and repair by state-to-draft demotion — originals preserved verbatim under state_draft.*, live keys marked stale, journal receipts anchored. dry_run=true only reports.

Parameters

dry_runbooleanfalseargument

Report only; make no writes

Returns

dry_runboolean
found_staleArray<object>
repairedArray<object>
scannedinteger
stale_countinteger
Audit State Staleness
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "perseus_vault_state_audit",
    "arguments": {
        "dry_run": false
      }
  }
}
const result = await client.callTool("perseus_vault_state_audit", {
  "dry_run": false
});
result = await session.call_tool("perseus_vault_state_audit", arguments={
  "dry_run": false
})
Response
{
  "dry_run": true,
  "found_stale": [
    {}
  ],
  "repaired": [
    {}
  ],
  "scanned": 0,
  "stale_count": 0
}