Protocol

  • Transport: STDIO (stdin/stdout)
  • Protocol version: 2025-11-25
  • Server name: zpm
  • Server version: 0.4.0

Server Capabilities

After initialization, the server advertises:

CapabilitySupportedDetails
ToolsyeslistChanged: true
ResourcesnoDeferred to future features
PromptsnoDeferred to future features

Lifecycle

  1. Client sends initialize request with protocol version and client info
  2. Server responds with InitializeResult containing server info and capabilities
  3. Client sends notifications/initialized
  4. Server enters active state and accepts tools/list and tools/call requests
  5. On STDIO EOF, server exits with code 0

Tool Discovery

Clients discover available tools by sending a tools/list request after the initialize handshake:

json
{"jsonrpc":"2.0","id":2,"method":"tools/list"}

Memory Parameter

Most knowledge and reasoning tools accept an optional memory parameter that targets a specific named memory segment. When omitted, the default memory is used (backward compatible).

json
{
  "name": "remember_fact",
  "arguments": {
    "fact": "task_done(login)",
    "memory": "feature_auth"
  }
}

Mutation tools (remember_fact, define_rule, forget_fact, etc.) return an error if the target memory is mounted read-only. The following tools support the memory parameter: remember_fact, upsert_fact, assume_fact, forget_fact, update_fact, rename_predicate, query_logic, define_rule, explain_why, trace_dependency, retract_assumption, retract_assumptions, list_assumptions, get_belief_status, get_justification, verify_consistency, clear_context, get_knowledge_schema, find_predicate_references, save_snapshot, restore_snapshot, list_snapshots.

Excluded tools: echo (no knowledge base interaction), get_persistence_status (reports global persistence layer status), and get_kb_overview (pending memory-aware inventory exception: its output combines selected-memory and global information, so the scope of a memory selector needs a separate decision).

Each tool in the supported list advertises memory as an optional JSON Schema string in tools/list. The query_logic, explain_why, trace_dependency, verify_consistency, get_belief_status, get_justification, save_snapshot, restore_snapshot, list_assumptions, get_knowledge_schema, and list_snapshots schemas use the description Target memory segment (optional, defaults to default memory). Other tools retain their tool-specific descriptions; see each Input Schema below. Omitting memory preserves default-memory behavior.

Overview

This document describes the tools available through the zpm MCP server. Each tool is exposed as a JSON-RPC method that can be called via the tools/call request.

Echo Tool

Name: echo

Description: Echoes back a message string. Useful for testing server connectivity and tool invocation.

Annotations:

  • Read-only: ✓
  • Idempotent: ✓
  • Non-destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "echo",
    "arguments": {
      "message": "Hello, world!"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "message": {
      "type": "string",
      "description": "The message to echo"
    }
  },
  "required": ["message"]
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Hello, world!"
      }
    ]
  }
}

Response (Error)

If the message argument is missing or null:

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

Remember Fact Tool

Name: remember_fact

Description: Assert a Prolog fact into the knowledge base. Facts persist in-memory for the duration of the engine session.

Annotations:

  • Read-only: ✗
  • Idempotent: ✗
  • Non-destructive: ✗

Request

json
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "remember_fact",
    "arguments": {
      "fact": "human(socrates)"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "fact": {
      "type": "string",
      "description": "A Prolog fact to assert (e.g. \"human(socrates)\")"
    }
  },
  "required": ["fact"]
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Asserted: human(socrates)"
      }
    ]
  }
}

Response (Error)

If the fact argument is missing, null, or empty:

json
{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

Define Rule Tool

Name: define_rule

Description: Assert a Prolog rule into the knowledge base. Constructs a rule from head and body (Head :- Body), validates syntax (including balanced parentheses), and inserts via assertz/1.

Annotations:

  • Read-only: ✗
  • Idempotent: ✗
  • Non-destructive: ✗

Request

json
{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {
    "name": "define_rule",
    "arguments": {
      "head": "mortal(X)",
      "body": "human(X)"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "head": {
      "type": "string",
      "description": "The rule head (e.g. \"mortal(X)\")"
    },
    "body": {
      "type": "string",
      "description": "The rule body (e.g. \"human(X)\")"
    }
  },
  "required": ["head", "body"]
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Asserted rule: mortal(X) :- human(X)"
      }
    ]
  }
}

Response (Error)

If head or body is missing, null, or empty:

json
{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

If the rule has invalid Prolog syntax (e.g. unbalanced parentheses):

json
{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Invalid Prolog syntax in rule: unbalanced parentheses",
        "isError": true
      }
    ]
  }
}

Query Logic Tool

Name: query_logic

Description: Execute a Prolog goal and return all variable bindings as JSON. Evaluates a deterministic Prolog query against the knowledge base and returns all solutions with their variable bindings.

Annotations:

  • Read-only: ✓
  • Idempotent: ✓
  • Non-destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "tools/call",
  "params": {
    "name": "query_logic",
    "arguments": {
      "goal": "fruit(X)"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "goal": {
      "type": "string",
      "description": "A Prolog goal to query (e.g. \"fruit(X)\", \"parent(john, Y)\")"
    },
    "memory": {
      "type": "string",
      "description": "Target memory segment (optional, defaults to default memory)"
    }
  },
  "required": ["goal"]
}

Response (Success with Results)

json
{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "[{\"X\":\"apple\"},{\"X\":\"banana\"}]"
      }
    ]
  }
}

Response (Success with No Results)

json
{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "[]"
      }
    ]
  }
}

Response (Error)

If the goal argument is missing, null, or empty:

json
{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

Trace Dependency Tool

Name: trace_dependency

Description: Trace transitive dependencies from a start node using path/2 rules. Queries the knowledge base for all nodes reachable from a given start node through dependency chains, useful for exploring graph-like structures in logical knowledge bases.

Annotations:

  • Read-only: ✓
  • Idempotent: ✓
  • Non-destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 6,
  "method": "tools/call",
  "params": {
    "name": "trace_dependency",
    "arguments": {
      "start_node": "a"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "start_node": {
      "type": "string",
      "description": "The starting node to trace dependencies from (e.g. \"a\", \"module_a\")"
    },
    "memory": {
      "type": "string",
      "description": "Target memory segment (optional, defaults to default memory)"
    }
  },
  "required": ["start_node"]
}

Response (Success with Dependencies)

Requires path/2 rule defined in the knowledge base (typically via define_rule):

json
{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "[\"b\",\"c\"]"
      }
    ]
  }
}

Response (Success with No Dependencies)

json
{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "[]"
      }
    ]
  }
}

Response (Error)

If the start_node argument is missing, null, or empty:

json
{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

Verify Consistency Tool

Name: verify_consistency

Description: Check the knowledge base for integrity violations by querying integrity_violation/N predicates. Returns all detected contradictions or constraint breaches with their variable bindings.

Annotations:

  • Read-only: ✓
  • Idempotent: ✓
  • Non-destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 7,
  "method": "tools/call",
  "params": {
    "name": "verify_consistency",
    "arguments": {}
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "scope": {
      "type": "string",
      "description": "Optional domain scope to filter integrity checks (e.g. \"deployment\")"
    },
    "memory": {
      "type": "string",
      "description": "Target memory segment (optional, defaults to default memory)"
    }
  },
  "required": []
}

Response (Success with Violations)

Requires integrity_violation/1 rules defined via define_rule:

json
{
  "jsonrpc": "2.0",
  "id": 7,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"violations\":[\"deploy_v3\"]}"
      }
    ]
  }
}

Response (Success with No Violations)

json
{
  "jsonrpc": "2.0",
  "id": 7,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"violations\":[]}"
      }
    ]
  }
}

Response (Error)

If the Prolog engine is unavailable:

json
{
  "jsonrpc": "2.0",
  "id": 7,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "ExecutionFailed",
        "isError": true
      }
    ]
  }
}

Explain Why Tool

Name: explain_why

Description: Trace the proof tree for a given fact and return a structured JSON explanation of how it was derived. Uses recursive clause/2 querying to reconstruct the deduction chain.

Annotations:

  • Read-only: ✓
  • Idempotent: ✓
  • Non-destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 8,
  "method": "tools/call",
  "params": {
    "name": "explain_why",
    "arguments": {
      "fact": "risky(deploy_v3)"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "fact": {
      "type": "string",
      "description": "The Prolog term to explain (e.g. \"risky(deploy_v3)\")"
    },
    "max_depth": {
      "type": "integer",
      "description": "Optional maximum proof tree depth (truncates deeper levels)"
    },
    "memory": {
      "type": "string",
      "description": "Target memory segment (optional, defaults to default memory)"
    }
  },
  "required": ["fact"]
}

Response (Success — Fact Proven)

json
{
  "jsonrpc": "2.0",
  "id": 8,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"fact\":\"risky(deploy_v3)\",\"proven\":true,\"proof_tree\":{\"goal\":\"risky(deploy_v3)\",\"rule_applied\":\"risky(X) :- untested(X), in_production(X)\",\"children\":[{\"goal\":\"untested(deploy_v3)\",\"rule_applied\":\"fact\",\"children\":[]},{\"goal\":\"in_production(deploy_v3)\",\"rule_applied\":\"fact\",\"children\":[]}]}}"
      }
    ]
  }
}

Response (Success — Fact Not Proven)

json
{
  "jsonrpc": "2.0",
  "id": 8,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"fact\":\"risky(deploy_v3)\",\"proven\":false,\"proof_tree\":null}"
      }
    ]
  }
}

Response (Error)

If the fact argument is missing, null, or empty:

json
{
  "jsonrpc": "2.0",
  "id": 8,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

Find Predicate References Tool

Name: find_predicate_references

Description: Locate all usage sites of a Prolog predicate within the knowledge base. Returns every clause body containing the target predicate, the count of direct facts matching the predicate’s functor/arity, TMS assumptions referencing the predicate, and module-qualified references from other memory segments. Essential for safe refactoring and understanding predicate dependencies.

Annotations:

  • Read-only: ✓
  • Idempotent: ✓
  • Non-destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 9,
  "method": "tools/call",
  "params": {
    "name": "find_predicate_references",
    "arguments": {
      "functor": "task_status",
      "arity": 2,
      "memory": "default"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "functor": {
      "type": "string",
      "description": "The predicate functor to search for (e.g. \"task_status\")"
    },
    "arity": {
      "type": "integer",
      "description": "The arity of the predicate (optional; when omitted, matches all arities of the functor)"
    },
    "memory": {
      "type": "string",
      "description": "Memory segment to search: a named segment, \"default\" for the default memory, or \"__all__\" to scan every mounted memory (default: \"default\")"
    },
    "include_cross_memory_refs": {
      "type": "boolean",
      "description": "Include module-qualified references from other memory segments in the response (default: true)"
    }
  },
  "required": ["functor"]
}

Response (Success — References Found)

json
{
  "jsonrpc": "2.0",
  "id": 9,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"target\":\"task_status/2\",\"memory\":\"default\",\"rules\":[{\"head\":\"active_work(X)\",\"body\":\"task_status(X, in_progress)\",\"memory\":\"default\"}],\"direct_facts_count\":2,\"facts_referenced_in_assumptions\":[{\"assumption\":\"sprint_planning\",\"fact\":\"task_status(f024, done)\",\"memory\":\"default\"}],\"cross_memory_refs\":[]}"
      }
    ]
  }
}

Response (Success — No References)

json
{
  "jsonrpc": "2.0",
  "id": 9,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"target\":\"nonexistent_predicate\",\"memory\":\"default\",\"rules\":[],\"direct_facts_count\":0,\"facts_referenced_in_assumptions\":[],\"cross_memory_refs\":[]}"
      }
    ]
  }
}

Response (Success — Cross-Memory References)

When memory: "__all__" and include_cross_memory_refs: true:

json
{
  "jsonrpc": "2.0",
  "id": 9,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"target\":\"task_status/2\",\"memory\":\"__all__\",\"rules\":[{\"head\":\"active_work(X)\",\"body\":\"task_status(X, in_progress)\",\"memory\":\"default\"},{\"head\":\"critical_tasks(X)\",\"body\":\"audit:task_status(X, critical)\",\"memory\":\"audit\"}],\"direct_facts_count\":3,\"facts_referenced_in_assumptions\":[],\"cross_memory_refs\":[{\"head\":\"check_external(X)\",\"body\":\"monitoring:task_status(X, blocked)\",\"memory\":\"reporting\",\"qualifier\":\"monitoring\"}]}"
      }
    ]
  }
}

Response Schema

Top-level fields in the embedded JSON:

FieldTypeDescription
targetstringThe search target formatted as "functor/arity" when arity is provided, or "functor" when omitted
memorystringThe requested memory scope: a segment name, "default", or "__all__"
rulesarrayOne entry per rule whose body contains the target predicate; each entry has head, body, and memory fields
rules[].headstringThe rule head as a Prolog term string
rules[].bodystringThe rule body as a Prolog term string
rules[].memorystringThe originating memory segment
direct_facts_countintegerCount of facts with the target functor/arity (facts have a trivial body of true)
facts_referenced_in_assumptionsarrayOne entry per TMS assumption referencing the target predicate; each entry has assumption, fact, and memory fields
facts_referenced_in_assumptions[].assumptionstringThe assumption label (hypothesis name)
facts_referenced_in_assumptions[].factstringThe assumed fact term as a Prolog term string
facts_referenced_in_assumptions[].memorystringThe originating memory segment
cross_memory_refsarrayOne entry per module-qualified reference (e.g., other_seg:predicate(...)) found in another memory segment; each entry has head, body, memory, and qualifier fields; empty unless include_cross_memory_refs: true
cross_memory_refs[].headstringThe rule head as a Prolog term string
cross_memory_refs[].bodystringThe rule body as a Prolog term string
cross_memory_refs[].memorystringThe memory segment that owns the referencing rule (the segment being scanned)
cross_memory_refs[].qualifierstringThe module name used in the cross-memory call (the segment being referenced, e.g. "default" in default:task_status(X, done))

Response (Error)

If the functor argument is missing or not a string:

json
{
  "jsonrpc": "2.0",
  "id": 9,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

If the functor contains invalid characters or is not a valid Prolog atom:

json
{
  "jsonrpc": "2.0",
  "id": 9,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

If the memory parameter names a segment that is not mounted:

json
{
  "jsonrpc": "2.0",
  "id": 9,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Memory not mounted: unknown_segment",
        "isError": true
      }
    ]
  }
}

If the arity argument is negative or not an integer:

json
{
  "jsonrpc": "2.0",
  "id": 9,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

Rename Predicate Tool

Name: rename_predicate

Description: Atomically rename a Prolog functor across all facts, rules, TMS justifications, and optionally cross-memory references in the knowledge base. A dry-run mode previews changes without mutation. Protects against self-renames, name collisions, ambiguous arities, and built-in functor corruption.

Annotations:

  • Read-only: ✗
  • Idempotent: ✗
  • Non-destructive: ✗

Request

json
{
  "jsonrpc": "2.0",
  "id": 10,
  "method": "tools/call",
  "params": {
    "name": "rename_predicate",
    "arguments": {
      "old_functor": "task_status",
      "new_functor": "feature_status",
      "arity": 2,
      "memory": "default",
      "dry_run": false,
      "propagate_cross_memory_refs": false
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "old_functor": {
      "type": "string",
      "description": "The current functor name to rename (must be a valid Prolog atom)"
    },
    "new_functor": {
      "type": "string",
      "description": "The new functor name (must be a valid Prolog atom and not already exist with the same arity)"
    },
    "arity": {
      "type": "integer",
      "description": "The arity of the functor to rename (required if multiple arities exist). If omitted and only one arity exists, that arity is used. If omitted and multiple arities exist, returns an error listing detected arities."
    },
    "memory": {
      "type": "string",
      "description": "The target memory segment (default: 'default'). Must be writable (not mounted read-only)."
    },
    "dry_run": {
      "type": "boolean",
      "description": "Preview mode: returns the full impact report without mutating the KB (default: false)"
    },
    "propagate_cross_memory_refs": {
      "type": "boolean",
      "description": "When true, rewrite qualified references (e.g., 'segment:old_functor/N') in all writable mounted memories (default: false). Cross-memory impact is always reported regardless of this flag."
    }
  },
  "required": ["old_functor", "new_functor"]
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 10,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"renamed_facts\": 2, \"rewritten_rule_bodies\": 1, \"affected_rule_ids\": [\"active_work(X)\"], \"cross_memory_impact\": {\"rewritten\": [], \"warnings\": [], \"skipped_readonly\": []}, \"is_error\": false}"
      }
    ]
  }
}

Response Fields

FieldTypeDescription
renamed_factsnumberCount of facts renamed from old_functor/arity to new_functor/arity
rewritten_rule_bodiesnumberCount of rule bodies that mentioned the old functor and were rewritten
affected_rule_idsarrayList of rule head identifiers (as strings) that were rewritten, e.g., ["active_work(X)", "completed(X)"]
cross_memory_impactobjectSummary of the rename’s impact across all mounted memories
cross_memory_impact.rewrittenarrayMemories where qualified refs were updated (only populated when propagate_cross_memory_refs=true)
cross_memory_impact.rewritten[].memorystringName of the rewritten memory segment
cross_memory_impact.rewritten[].rules_updatednumberCount of rules updated in this memory
cross_memory_impact.warningsarrayWritable memories with qualified refs that were NOT modified (only populated when propagate_cross_memory_refs=false)
cross_memory_impact.warnings[].memorystringName of the memory containing unmodified refs
cross_memory_impact.warnings[].refsnumberCount of unmodified qualified refs in this memory
cross_memory_impact.warnings[].reasonstringAlways "propagate_cross_memory_refs=false"
cross_memory_impact.skipped_readonlyarrayRead-only memories with qualified refs (always present, never modified)
cross_memory_impact.skipped_readonly[].memorystringName of the read-only memory
cross_memory_impact.skipped_readonly[].refsnumberCount of qualified refs in this memory
cross_memory_impact.skipped_readonly[].reasonstringAlways "read-only"
is_errorbooleanFalse on success; if true, refer to response text for error message (string)

Dry Run Example

bash
zpm rename-predicate --old_functor task_status --new_functor feature_status --arity 2 --dry_run true

Returns the same response shape as a real run (counts, affected rules, cross-memory impact) without modifying the KB. Verification: a subsequent query_logic for the old functor still returns results.

Cross-Memory Impact Example

When propagate_cross_memory_refs=true and multiple memories reference the renamed functor:

json
{
  "renamed_facts": 5,
  "rewritten_rule_bodies": 3,
  "affected_rule_ids": ["process_work(X)", "check_status(Y)"],
  "cross_memory_impact": {
    "rewritten": [
      {
        "memory": "audit",
        "rules_updated": 1
      },
      {
        "memory": "reporting",
        "rules_updated": 2
      }
    ],
    "warnings": [],
    "skipped_readonly": [
      {
        "memory": "archive",
        "refs": 3,
        "reason": "read-only"
      }
    ]
  },
  "is_error": false
}

Usage Examples

Basic Single-Memory Rename

bash
# Rename task_status/2 to feature_status/2 in the default memory
zpm rename-predicate \
  --old_functor task_status \
  --new_functor feature_status \
  --arity 2

Dry Run Before Applying

bash
# Preview the impact without modifying anything
zpm rename-predicate \
  --old_functor task_status \
  --new_functor feature_status \
  --arity 2 \
  --dry_run true

Rename in a Specific Memory

bash
# Rename within the 'audit_log' memory segment
zpm rename-predicate \
  --memory audit_log \
  --old_functor check_result \
  --new_functor test_result \
  --arity 2

Cross-Memory Propagation

bash
# Rename and rewrite qualified refs in all writable mounted memories
zpm rename-predicate \
  --old_functor task_status \
  --new_functor feature_status \
  --arity 2 \
  --propagate_cross_memory_refs true

Response (Error)

Ambiguous Arity (Multiple Arities Exist)

If old_functor exists with multiple arities and arity is not provided:

json
{
  "jsonrpc": "2.0",
  "id": 10,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Ambiguous arity for task_status; detected arities: 1, 2. Specify arity parameter.",
        "isError": true
      }
    ]
  }
}

Name Collision (Target Name Already Exists)

If new_functor/arity already exists:

json
{
  "jsonrpc": "2.0",
  "id": 10,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Cannot rename: feature_status/2 already exists in memory 'default'",
        "isError": true
      }
    ]
  }
}

Read-Only Memory

If the target memory is mounted read-only:

json
{
  "jsonrpc": "2.0",
  "id": 10,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Cannot rename in read-only memory: archive",
        "isError": true
      }
    ]
  }
}

Built-In Operator (Blacklisted Functor)

If attempting to rename a protected ISO Prolog operator:

json
{
  "jsonrpc": "2.0",
  "id": 10,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Cannot rename ISO operator: =/2",
        "isError": true
      }
    ]
  }
}

Invalid Arguments

If required arguments are missing or invalid:

json
{
  "jsonrpc": "2.0",
  "id": 10,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

Guarantees

  • Atomicity: All-or-nothing at the per-memory level. If any write fails, the engine state and WAL are rolled back for that memory.
  • TMS Preservation: Assumption identifiers remain unchanged; justifications referencing the old functor are automatically updated to the new functor.
  • Collision Detection: Rejects renames where the target name already exists (no silent merges).
  • Dry Run Byte-Identity: When dry_run=true, the KB and WAL file remain byte-identical before and after the call.
  • Cross-Memory Reporting: Impact across all mounted memories is always computed and reported, even when propagate_cross_memory_refs=false.

Blacklisted Operators (Cannot be Renamed)

The following ISO Prolog operators cannot be renamed, whether as old_functor or new_functor: =/2, ,/2, ;/2, is/2, ->/2, \=/2, ==/2, \==/2, =../2, @</2, @>/2, @=</2, @>=/2, </2, >/2, =</2, >=/2, +/2, -/2, */2, //2, :-/2, :-/1, \+/1, !/0

See Also

Get KB Overview Tool

Name: get_kb_overview

Description: Return a single-call JSON snapshot of the default knowledge base: file-loaded static and asserted user predicates (with functor, arity, kind, clause count, and sample clauses as Prolog term strings), the active assumptions, persisted snapshots metadata, persistence layer health, and mounted memory segments. Replaces the chained sequence of get_knowledge_schema + list_assumptions + list_snapshots + get_persistence_status + list_memories with one round-trip. Read-only; the tool has no memory selector.

Annotations:

  • Read-only: ✓
  • Idempotent: ✓
  • Non-destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 28,
  "method": "tools/call",
  "params": {
    "name": "get_kb_overview",
    "arguments": {
      "sample_size": 2
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "sample_size": {
      "type": "integer",
      "description": "Number of sample clauses per predicate (default: 2, max: 50)"
    }
  },
  "required": []
}

The sample_size argument is optional. Values below 0 are clamped to 0; values above 50 are clamped to 50. When omitted, defaults to 2.

Response (Success — Populated KB)

json
{
  "jsonrpc": "2.0",
  "id": 28,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"predicates\":[{\"functor\":\"parent\",\"arity\":2,\"kind\":\"fact\",\"count\":2,\"samples\":[\"parent(tom, bob)\",\"parent(bob, sue)\"]},{\"functor\":\"ancestor\",\"arity\":2,\"kind\":\"rule\",\"count\":1,\"samples\":[\"ancestor(X, Y) :- parent(X, Y)\"]}],\"assumptions\":{\"count\":1,\"names\":[\"infra_healthy\"]},\"snapshots\":{\"count\":1,\"latest\":\"before_refactor\",\"latest_at\":\"2026-05-17T10:42:11Z\"},\"persistence\":{\"wal_pending\":2,\"healthy\":true},\"mounts\":{\"available\":true,\"count\":1,\"items\":[{\"name\":\"default\",\"scope\":\"project\",\"mode\":\"rw\"}]},\"truncated\":false}"
      }
    ]
  }
}

Response (Success — Empty KB)

json
{
  "jsonrpc": "2.0",
  "id": 28,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"predicates\":[],\"assumptions\":{\"count\":0,\"names\":[]},\"snapshots\":{\"count\":0,\"latest\":null,\"latest_at\":null},\"persistence\":{\"wal_pending\":0,\"healthy\":false},\"mounts\":{\"available\":false,\"count\":0,\"items\":[]},\"truncated\":false}"
      }
    ]
  }
}

Response Schema

Top-level fields in the embedded JSON:

FieldTypeDescription
predicatesarrayOne entry per user-defined predicate with inspectable clauses in the default memory, including file-loaded static facts and rules; builtins and system predicates are excluded
predicates[].functorstringPredicate functor name
predicates[].arityintegerNumber of arguments
predicates[].kindstring"fact" — all clauses have a true body; "rule" — all clauses have a non-trivial body; "both" — predicate contains at least one fact and at least one rule
predicates[].countintegerTotal number of clauses
predicates[].samplesarray of stringUp to sample_size clauses, rendered as Prolog term strings (head for facts, head :- body for rules); empty when sample_size: 0
assumptions.countintegerNumber of active assumptions
assumptions.namesarray of stringSorted, deduplicated assumption identifiers
snapshots.countintegerNumber of persisted snapshots
snapshots.lateststring | nullMost recently created snapshot name (lexicographic ordering), or null if none
snapshots.latest_atstring | nullISO-8601 UTC timestamp of the latest snapshot file’s mtime, or null if none
persistence.wal_pendingintegerCount of unflushed WAL journal entries (best-effort scan)
persistence.healthybooleantrue when the persistence manager is active; false when degraded, disabled, or unavailable
mounts.availablebooleantrue when the memory registry is initialized; false when it is not yet set up
mounts.countintegerNumber of currently mounted memory segments
mounts.itemsarrayOne entry per mounted segment; empty when mounts.available is false or no segments are mounted
mounts.items[].namestringMount name (a valid Prolog atom)
mounts.items[].scopestring"project" — scoped to the current project; "global" — shared across projects
mounts.items[].modestring"rw" — read-write; "ro" — read-only
truncatedbooleantrue when the response exceeded the internal 64 KiB budget and samples were trimmed; the tool favors breadth (reducing samples across all predicates) over depth

Response (Error)

If the Prolog engine is not initialized:

json
{
  "jsonrpc": "2.0",
  "id": 28,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Prolog engine is not initialized",
        "isError": true
      }
    ]
  }
}

The tool never raises an error for null/missing arguments, an empty KB, missing snapshots, or a degraded persistence layer — it returns a valid envelope with zero counts and persistence.healthy: false instead.

Get Knowledge Schema Tool

Name: get_knowledge_schema

Description: Introspect the selected memory to discover file-loaded static and asserted user predicates, their arities, clause counts, and whether they are facts, rules, or both. Returns structural metadata only — no predicate content is exposed. Read-only mounts support discovery.

Annotations:

  • Read-only: ✓
  • Idempotent: ✓
  • Non-destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 9,
  "method": "tools/call",
  "params": {
    "name": "get_knowledge_schema",
    "arguments": {}
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "memory": {
      "type": "string",
      "description": "Target memory segment (optional, defaults to default memory)"
    }
  },
  "required": []
}

No arguments are required. The tool accepts empty or null arguments.

Response (Success with Predicates)

json
{
  "jsonrpc": "2.0",
  "id": 9,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"predicates\":[{\"name\":\"user_prefers\",\"arity\":1,\"type\":\"fact\",\"count\":2},{\"name\":\"depends_on\",\"arity\":2,\"type\":\"fact\",\"count\":3},{\"name\":\"path\",\"arity\":2,\"type\":\"both\",\"count\":4}],\"total\":3}"
      }
    ]
  }
}

Each predicate entry includes:

FieldTypeDescription
namestringPredicate functor name
arityintegerNumber of arguments
typestring"fact", "rule", or "both"
countintegerTotal number of clauses

The root-level total field indicates the number of user-defined predicates. Only predicates with inspectable clauses in the selected memory appear; builtins, operators, and ZPM helper predicates are excluded. An introspection failure is reported as ExecutionFailed rather than as an empty schema.

Response (Empty Knowledge Base)

json
{
  "jsonrpc": "2.0",
  "id": 9,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"predicates\":[],\"total\":0}"
      }
    ]
  }
}

Response (Error)

If predicate introspection fails:

json
{
  "jsonrpc": "2.0",
  "id": 9,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "ExecutionFailed",
        "isError": true
      }
    ]
  }
}

Forget Fact Tool

Name: forget_fact

Description: Remove a single fact from the knowledge base by retracting the first matching clause. Uses Prolog’s retract/1 semantics — when multiple identical facts exist, only one is removed per call.

Annotations:

  • Read-only: ✗
  • Idempotent: ✗
  • Non-destructive: ✗

Request

json
{
  "jsonrpc": "2.0",
  "id": 10,
  "method": "tools/call",
  "params": {
    "name": "forget_fact",
    "arguments": {
      "fact": "human(socrates)"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "fact": {
      "type": "string",
      "description": "A Prolog fact to retract (e.g. \"human(socrates)\")"
    }
  },
  "required": ["fact"]
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 10,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Retracted: human(socrates)"
      }
    ]
  }
}

Response (Error - Fact Not Found)

If the fact does not exist in the knowledge base:

json
{
  "jsonrpc": "2.0",
  "id": 10,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "No matching clause found for: human(socrates)",
        "isError": true
      }
    ]
  }
}

Response (Error - Invalid Arguments)

If the fact argument is missing, null, or empty:

json
{
  "jsonrpc": "2.0",
  "id": 10,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

Clear Context Tool

Name: clear_context

Description: Remove all facts from the knowledge base matching a given category or pattern. Uses Prolog’s retractall/1 semantics — clears all clauses matching the pattern in a single operation. The tool always succeeds, even when no matching facts exist (idempotent behavior).

Annotations:

  • Read-only: ✗
  • Idempotent: ✓
  • Non-destructive: ✗

Request

json
{
  "jsonrpc": "2.0",
  "id": 11,
  "method": "tools/call",
  "params": {
    "name": "clear_context",
    "arguments": {
      "category": "project(beta, _)"
    }
  }
}

Request with Memory Segment

To target a specific memory segment, pass the memory parameter:

json
{
  "jsonrpc": "2.0",
  "id": 12,
  "method": "tools/call",
  "params": {
    "name": "clear_context",
    "arguments": {
      "category": "task_status(_, _)",
      "memory": "feature_auth"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "category": {
      "type": "string",
      "description": "A Prolog pattern to match facts for bulk deletion (e.g. \"project(beta, _)\", \"role(_, _)\")"
    },
    "memory": {
      "type": "string",
      "description": "Target memory segment (optional, defaults to default memory)"
    }
  },
  "required": ["category"]
}

Response (Success - Matched Facts)

json
{
  "jsonrpc": "2.0",
  "id": 11,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Cleared all facts matching: project(beta, _)"
      }
    ]
  }
}

Response (Success - No Matches)

When no facts match the pattern (idempotent — still returns success):

json
{
  "jsonrpc": "2.0",
  "id": 11,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Cleared all facts matching: nonexistent(_, _)"
      }
    ]
  }
}

Response (Error - Invalid Arguments)

If the category argument is missing, null, or empty:

json
{
  "jsonrpc": "2.0",
  "id": 11,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

Update Fact Tool

Name: update_fact

Description: Atomically replace an existing Prolog fact in the knowledge base (retract old_fact, assert new_fact). Returns an error if old_fact is not found, leaving the knowledge base unchanged.

Annotations:

  • Read-only: ✗
  • Idempotent: ✗
  • Non-destructive: ✗

Request

json
{
  "jsonrpc": "2.0",
  "id": 12,
  "method": "tools/call",
  "params": {
    "name": "update_fact",
    "arguments": {
      "old_fact": "server(alpha, \"1.0\")",
      "new_fact": "server(alpha, \"2.0\")"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "old_fact": {
      "type": "string",
      "description": "The existing Prolog fact to retract (e.g. \"server(alpha, \\\"1.0\\\")\")"
    },
    "new_fact": {
      "type": "string",
      "description": "The new Prolog fact to assert in its place (e.g. \"server(alpha, \\\"2.0\\\")\")"
    }
  },
  "required": ["old_fact", "new_fact"]
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 12,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Updated: server(alpha, \"1.0\") -> server(alpha, \"2.0\")"
      }
    ]
  }
}

Response (Error - Fact Not Found)

If the old fact does not exist in the knowledge base:

json
{
  "jsonrpc": "2.0",
  "id": 12,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "No matching clause for: server(alpha, \"1.0\")",
        "isError": true
      }
    ]
  }
}

Response (Error - Rule Syntax)

If the new_fact contains rule syntax (:-):

json
{
  "jsonrpc": "2.0",
  "id": 12,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "new_fact must not contain rule syntax",
        "isError": true
      }
    ]
  }
}

Response (Error - Invalid Arguments)

If either argument is missing, null, or empty:

json
{
  "jsonrpc": "2.0",
  "id": 12,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

Upsert Fact Tool

Name: upsert_fact

Description: Insert or replace a Prolog fact in the knowledge base. Retracts all existing clauses matching the same functor and first argument, then asserts the new fact. Succeeds even if no prior fact exists.

Annotations:

  • Read-only: ✗
  • Idempotent: ✓
  • Non-destructive: ✗

Request

json
{
  "jsonrpc": "2.0",
  "id": 13,
  "method": "tools/call",
  "params": {
    "name": "upsert_fact",
    "arguments": {
      "fact": "deploy(prod, v2)"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "fact": {
      "type": "string",
      "description": "A Prolog fact to insert or replace (e.g. \"deploy(prod, v2)\")"
    }
  },
  "required": ["fact"]
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 13,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Upserted: deploy(prod, v2)"
      }
    ]
  }
}

Response (Error - Rule Syntax)

If the fact contains rule syntax (:-):

json
{
  "jsonrpc": "2.0",
  "id": 13,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "fact must not contain rule syntax",
        "isError": true
      }
    ]
  }
}

Response (Error - Invalid Arguments)

If the fact argument is missing, null, or empty:

json
{
  "jsonrpc": "2.0",
  "id": 13,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

Assume Fact Tool

Name: assume_fact

Description: Assert a Prolog fact under a named assumption for truth maintenance tracking. The assumption name must be lowercase alphanumeric with underscores. Mutations are journaled to the WAL.

Annotations:

  • Read-only: ✗
  • Idempotent: ✓
  • Non-destructive: ✗

Request

json
{
  "jsonrpc": "2.0",
  "id": 14,
  "method": "tools/call",
  "params": {
    "name": "assume_fact",
    "arguments": {
      "fact": "available(server_a)",
      "assumption": "infra_healthy"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "fact": {
      "type": "string",
      "description": "A Prolog fact to assert (e.g. \"available(server_a)\")"
    },
    "assumption": {
      "type": "string",
      "description": "The assumption name justifying this fact (e.g. \"infra_healthy\")"
    }
  },
  "required": ["fact", "assumption"]
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 14,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Assumed: available(server_a) under assumption 'infra_healthy'"
      }
    ]
  }
}

Response (Error)

If fact or assumption is missing, null, or empty:

json
{
  "jsonrpc": "2.0",
  "id": 14,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

Returns InvalidArguments if the assumption name is not a valid Prolog atom (lowercase letter followed by alphanumerics/underscores).


Get Belief Status Tool

Name: get_belief_status

Description: Query whether a belief is currently supported and which assumptions justify it. Returns the belief status (in or out), the list of justifying assumptions, and the fact source attribution (interactive, snapshot, journal, or unknown).

Annotations:

  • Read-only: ✓
  • Idempotent: ✓
  • Non-destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 15,
  "method": "tools/call",
  "params": {
    "name": "get_belief_status",
    "arguments": {
      "fact": "available(server_a)"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "fact": {
      "type": "string",
      "description": "The Prolog fact to check belief status for (e.g. \"available(server_a)\")"
    },
    "memory": {
      "type": "string",
      "description": "Target memory segment (optional, defaults to default memory)"
    }
  },
  "required": ["fact"]
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 15,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"status\":\"in\",\"justifications\":[\"infra_healthy\"],\"source\":\"interactive\"}"
      }
    ]
  }
}

Response (Error)

If the fact argument is missing, null, or empty:

json
{
  "jsonrpc": "2.0",
  "id": 15,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

Get Justification Tool

Name: get_justification

Description: Return all facts currently supported by a given assumption.

Annotations:

  • Read-only: ✓
  • Idempotent: ✓
  • Non-destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 16,
  "method": "tools/call",
  "params": {
    "name": "get_justification",
    "arguments": {
      "assumption": "infra_healthy"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "assumption": {
      "type": "string",
      "description": "The assumption name to query (e.g. \"infra_healthy\")"
    },
    "memory": {
      "type": "string",
      "description": "Target memory segment (optional, defaults to default memory)"
    }
  },
  "required": ["assumption"]
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 16,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"facts\":[\"available(server_a)\"]}"
      }
    ]
  }
}

Response (Error)

If the assumption argument is missing, null, or empty:

json
{
  "jsonrpc": "2.0",
  "id": 16,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

Returns InvalidArguments if the assumption name is not a valid Prolog atom (lowercase letter followed by alphanumerics/underscores).


List Assumptions Tool

Name: list_assumptions

Description: Return all named assumptions currently registered in the truth maintenance system. Returns a deduplicated list.

Annotations:

  • Read-only: ✓
  • Idempotent: ✓
  • Non-destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 17,
  "method": "tools/call",
  "params": {
    "name": "list_assumptions",
    "arguments": {}
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "memory": {
      "type": "string",
      "description": "Target memory segment (optional, defaults to default memory)"
    }
  },
  "required": []
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 17,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"assumptions\":[\"infra_healthy\",\"budget_approved\"]}"
      }
    ]
  }
}

Response (Empty)

json
{
  "jsonrpc": "2.0",
  "id": 17,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"assumptions\":[]}"
      }
    ]
  }
}

Retract Assumption Tool

Name: retract_assumption

Description: Retract a named assumption and remove all facts that have no remaining justifications. Mutations are journaled to the WAL. Returns an error if the assumption does not exist.

Annotations:

  • Read-only: ✗
  • Idempotent: ✓
  • Destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 18,
  "method": "tools/call",
  "params": {
    "name": "retract_assumption",
    "arguments": {
      "assumption": "infra_healthy"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "assumption": {
      "type": "string",
      "description": "The assumption name to retract (e.g. \"infra_healthy\")"
    },
    "memory": {
      "type": "string",
      "description": "Target memory segment (optional, defaults to default memory)"
    }
  },
  "required": ["assumption"]
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 18,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Retracted assumption 'infra_healthy': 2 fact(s) removed"
      }
    ]
  }
}

Response (Error - Invalid Arguments)

If the assumption argument is missing, null, or empty:

json
{
  "jsonrpc": "2.0",
  "id": 18,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

Returns InvalidArguments if the assumption name is not a valid Prolog atom (lowercase letter followed by alphanumerics/underscores).

Response (Error - Unknown Assumption)

If the assumption does not exist:

json
{
  "jsonrpc": "2.0",
  "id": 18,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Unknown assumption 'nonexistent'",
        "isError": true
      }
    ]
  }
}

Retract Assumptions Tool

Name: retract_assumptions

Description: Retract all assumptions matching a glob-style pattern with full propagation semantics. Each retracted assumption’s dependent facts are cleaned up. Mutations are journaled to the WAL.

Annotations:

  • Read-only: ✗
  • Idempotent: ✓
  • Destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 19,
  "method": "tools/call",
  "params": {
    "name": "retract_assumptions",
    "arguments": {
      "pattern": "infra_*"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "pattern": {
      "type": "string",
      "description": "A glob-style pattern to match assumption names (e.g. \"infra_*\")"
    },
    "memory": {
      "type": "string",
      "description": "Target memory segment (optional, defaults to default memory)"
    }
  },
  "required": ["pattern"]
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 19,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Retracted pattern 'infra_*': 3 assumption(s) removed"
      }
    ]
  }
}

Response (Error)

If the pattern argument is missing, null, or empty:

json
{
  "jsonrpc": "2.0",
  "id": 19,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

Returns InvalidArguments if the pattern contains characters outside the allowed glob charset (lowercase letters, digits, underscores, and the wildcards * and ?).


Save Snapshot Tool

Name: save_snapshot

Description: Persist the current Prolog knowledge base to a named snapshot file. The snapshot contains all facts, rules, and TMS metadata in valid Prolog source syntax. After a snapshot, the WAL journal is rotated.

Annotations:

  • Read-only: ✗
  • Idempotent: ✓
  • Non-destructive: ✗

Request

json
{
  "jsonrpc": "2.0",
  "id": 20,
  "method": "tools/call",
  "params": {
    "name": "save_snapshot",
    "arguments": {
      "name": "before_refactor"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "A name for the snapshot (e.g. \"before_refactor\")"
    },
    "memory": {
      "type": "string",
      "description": "Target memory segment (optional, defaults to default memory)"
    }
  },
  "required": ["name"]
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 20,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Snapshot 'before_refactor' saved successfully."
      }
    ]
  }
}

Response (Error)

If the name argument is missing, null, or empty:

json
{
  "jsonrpc": "2.0",
  "id": 20,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

Restore Snapshot Tool

Name: restore_snapshot

Description: Restore the Prolog knowledge base from a named snapshot file. This replaces the current knowledge base state entirely with the snapshot contents. All predicates in the snapshot are loaded as dynamic and are immediately queryable via query_logic and visible in get_knowledge_schema.

Annotations:

  • Read-only: ✗
  • Idempotent: ✗
  • Destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 21,
  "method": "tools/call",
  "params": {
    "name": "restore_snapshot",
    "arguments": {
      "name": "before_refactor"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "The snapshot name to restore from (e.g. \"before_refactor\")"
    },
    "memory": {
      "type": "string",
      "description": "Target memory segment (optional, defaults to default memory)"
    }
  },
  "required": ["name"]
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 21,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Snapshot 'before_refactor' restored successfully."
      }
    ]
  }
}

Response (Error - Not Found)

If the snapshot file does not exist:

json
{
  "jsonrpc": "2.0",
  "id": 21,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "ExecutionFailed",
        "isError": true
      }
    ]
  }
}

Response (Error - Invalid Arguments)

If the name argument is missing, null, or empty:

json
{
  "jsonrpc": "2.0",
  "id": 21,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

List Snapshots Tool

Name: list_snapshots

Description: List all available Prolog knowledge base snapshots.

Annotations:

  • Read-only: ✓
  • Idempotent: ✓
  • Non-destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 22,
  "method": "tools/call",
  "params": {
    "name": "list_snapshots",
    "arguments": {}
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "memory": {
      "type": "string",
      "description": "Target memory segment (optional, defaults to default memory)"
    }
  },
  "required": []
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 22,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Snapshots: [before_refactor, daily_backup]"
      }
    ]
  }
}

Response (Empty)

json
{
  "jsonrpc": "2.0",
  "id": 22,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Snapshots: []"
      }
    ]
  }
}

Get Persistence Status Tool

Name: get_persistence_status

Description: Query the health and status of the persistence subsystem, including operational mode, persistence directory, last snapshot, and journal size.

Annotations:

  • Read-only: ✓
  • Idempotent: ✓
  • Non-destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 23,
  "method": "tools/call",
  "params": {
    "name": "get_persistence_status",
    "arguments": {}
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {},
  "required": []
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 23,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "status: active\ndir: /tmp/zpm-persistence\nlast_snapshot: before_refactor\njournal_size: 1024 bytes"
      }
    ]
  }
}

Response (Error)

If the persistence manager is unavailable:

json
{
  "jsonrpc": "2.0",
  "id": 23,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "ExecutionFailed",
        "isError": true
      }
    ]
  }
}

Create Memory Tool

Name: create_memory

Description: Create a new named memory segment backed by a dedicated Prolog module. Creates the on-disk directory and knowledge.pl module header. Does not mount the memory.

Annotations:

  • Read-only: ✗
  • Idempotent: ✗
  • Non-destructive: ✗

Request

json
{
  "jsonrpc": "2.0",
  "id": 24,
  "method": "tools/call",
  "params": {
    "name": "create_memory",
    "arguments": {
      "name": "feature_auth",
      "scope": "project"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "A valid Prolog atom (snake_case) naming the memory segment"
    },
    "scope": {
      "type": "string",
      "description": "The scope of the memory segment: \"project\" (default) or \"global\""
    }
  },
  "required": ["name"]
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 24,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Created memory 'feature_auth' (project scope)"
      }
    ]
  }
}

Response (Error)

If the name argument is missing, null, empty, or not a valid Prolog atom:

json
{
  "jsonrpc": "2.0",
  "id": 24,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

If the memory name already exists:

json
{
  "jsonrpc": "2.0",
  "id": 24,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Memory 'feature_auth' already exists",
        "isError": true
      }
    ]
  }
}

Mount Memory Tool

Name: mount_memory

Description: Mount an existing memory segment, loading its snapshot and replaying its WAL. Once mounted, the memory can be targeted by knowledge tools via the memory parameter.

Annotations:

  • Read-only: ✗
  • Idempotent: ✗
  • Non-destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 25,
  "method": "tools/call",
  "params": {
    "name": "mount_memory",
    "arguments": {
      "name": "feature_auth",
      "mode": "rw"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "The name of the memory segment to mount"
    },
    "mode": {
      "type": "string",
      "description": "Mount mode: \"rw\" (default, read-write) or \"ro\" (read-only)"
    }
  },
  "required": ["name"]
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 25,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Mounted memory 'feature_auth' (rw)"
      }
    ]
  }
}

Response (Error)

If the name argument is missing, null, empty, or not a valid Prolog atom:

json
{
  "jsonrpc": "2.0",
  "id": 25,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

If the memory is already mounted or does not exist:

json
{
  "jsonrpc": "2.0",
  "id": 25,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Memory 'feature_auth' is already mounted",
        "isError": true
      }
    ]
  }
}

Unmount Memory Tool

Name: unmount_memory

Description: Unmount a mounted memory segment, flushing its WAL to disk and unloading the Prolog module. The default memory cannot be unmounted.

Annotations:

  • Read-only: ✗
  • Idempotent: ✗
  • Non-destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 26,
  "method": "tools/call",
  "params": {
    "name": "unmount_memory",
    "arguments": {
      "name": "feature_auth"
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "The name of the memory segment to unmount"
    }
  },
  "required": ["name"]
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 26,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Unmounted memory 'feature_auth'"
      }
    ]
  }
}

Response (Error)

If the name argument is missing, null, empty, or not a valid Prolog atom:

json
{
  "jsonrpc": "2.0",
  "id": 26,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "InvalidArguments",
        "isError": true
      }
    ]
  }
}

If the memory is not mounted or the name is “default”:

json
{
  "jsonrpc": "2.0",
  "id": 26,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Cannot unmount the default memory",
        "isError": true
      }
    ]
  }
}

List Memories Tool

Name: list_memories

Description: List all discoverable memory segments (mounted and unmounted) across project and global scopes. Returns name, scope, mount status, and mode for each memory.

Annotations:

  • Read-only: ✓
  • Idempotent: ✓
  • Non-destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 27,
  "method": "tools/call",
  "params": {
    "name": "list_memories",
    "arguments": {}
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {},
  "required": []
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 27,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"memories\":[{\"name\":\"default\",\"scope\":\"project\",\"mounted\":true,\"mode\":\"rw\"},{\"name\":\"feature_auth\",\"scope\":\"project\",\"mounted\":false,\"mode\":null}]}"
      }
    ]
  }
}

Each memory entry includes:

FieldTypeDescription
namestringMemory segment name
scopestring"project" or "global"
mountedbooleanWhether the memory is currently mounted
modestring or null"rw", "ro", or null if not mounted

Response (Error)

If discovery fails:

json
{
  "jsonrpc": "2.0",
  "id": 27,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "ExecutionFailed",
        "isError": true
      }
    ]
  }
}

Get KB Overview Tool

Name: get_kb_overview

Description: Return a single-call JSON snapshot of the default zpm knowledge base, including file-loaded static and asserted predicates with sample clauses, active assumptions, available snapshots, and persistence layer health. No memory selector is available.

Annotations:

  • Read-only: ✓
  • Idempotent: ✓
  • Non-destructive: ✓

Request

json
{
  "jsonrpc": "2.0",
  "id": 28,
  "method": "tools/call",
  "params": {
    "name": "get_kb_overview",
    "arguments": {
      "sample_size": 2
    }
  }
}

Input Schema

json
{
  "type": "object",
  "properties": {
    "sample_size": {
      "type": "integer",
      "description": "Number of sample clauses per predicate (default: 2, max: 50). Set to 0 to suppress samples."
    }
  },
  "required": []
}

Response (Success)

json
{
  "jsonrpc": "2.0",
  "id": 28,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"predicates\":[{\"name\":\"task_status\",\"arity\":2,\"kind\":\"fact\",\"count\":5,\"samples\":[\"task_status(f017, done)\",\"task_status(f020, pending)\"]},{\"name\":\"depends_on\",\"arity\":2,\"kind\":\"both\",\"count\":3,\"samples\":[\"depends_on(X, Y) :- task_status(X, active)\",\"depends_on(f017, f016)\"]}],\"assumptions\":[{\"name\":\"user_context\",\"facts\":[\"user_id(alice)\",\"session_token(xyz123)\"]},{\"name\":\"experiment_mode\",\"facts\":[\"debug_enabled(true)\"]}],\"snapshots\":[{\"name\":\"before_deploy\",\"timestamp\":1685678900},{\"name\":\"after_migration\",\"timestamp\":1685678950}],\"persistence\":{\"status\":\"active\",\"journal_size_bytes\":2048,\"last_snapshot\":\"after_migration\",\"last_checkpoint_epoch\":1685678950},\"truncated\":false}"
      }
    ]
  }
}

Response Fields

FieldTypeDescription
predicatesarrayUser-defined predicates with inspectable clauses in the default memory, including file-loaded static facts and rules
predicates[].namestringPredicate name (functor)
predicates[].aritynumberPredicate arity
predicates[].kindstring"fact", "rule", or "both"
predicates[].countnumberTotal number of clauses (facts + rules)
predicates[].samplesarrayUp to sample_size sample clauses (suppressed if sample_size: 0)
assumptionsarrayList of active assumptions in the truth maintenance system
assumptions[].namestringAssumption identifier
assumptions[].factsarrayFacts supported by this assumption
snapshotsarrayList of available knowledge base snapshots
snapshots[].namestringSnapshot name
snapshots[].timestampnumberUnix epoch timestamp of snapshot creation
persistenceobjectPersistence layer health status
persistence.statusstring"active", "degraded", or "offline"
persistence.journal_size_bytesnumberWrite-ahead journal size in bytes
persistence.last_snapshotstringName of the most recent snapshot (or null)
persistence.last_checkpoint_epochnumberUnix epoch of the last checkpoint
truncatedbooleanTrue if the response was truncated due to size limits (total output capped at 64 KB)

Usage Examples

Get overview with default samples (2 clauses per predicate)

bash
zpm get-kb-overview

Get overview with extended samples (5 clauses per predicate)

bash
zpm get-kb-overview --sample-size 5

Get overview without samples (for large knowledge bases)

bash
zpm get-kb-overview --sample-size 0

Response (Error)

If the Prolog engine is not initialized or unavailable:

json
{
  "jsonrpc": "2.0",
  "id": 28,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Prolog engine is not initialized",
        "isError": true
      }
    ]
  }
}

Notes

  • Built-in predicates (those starting with $, containing :, or named tms_justification, zpm_source, portray) are excluded from the overview.
  • Sample clauses are formatted as they appear in the knowledge base (facts as atoms, rules as Head :- Body).
  • The knowledge base is queried once, making this tool efficient even for large knowledge bases.
  • Output is truncated at 64 KB. Use sample_size: 0 to reduce output size for very large knowledge bases.