Palimpsests / Integrations

Integrations · LiteLLM · MCP · OpenCode

Put your agent's tool calls on a tamper-evident record

Three adapters report tool calls from existing clients to a local palimpsests serve, which writes them into the PALA-1 chain — marked as reported by the client, so they are never confused with what the runtime observed itself.

Before you start

pip install 'palimpsests[serve]'
palimpsests serve        # http://127.0.0.1:11435 — local by default

The adapters post to the serve's ingestion endpoint, POST /v1/pala/events, available since 0.12. If the serve runs with --api-key, give the adapter the same key in PALIMPSESTS_SERVE_API_KEY. Arguments and outputs are sent to the serve, which stores only their digests — content never enters the chain.

What a reported record proves

RecordWhat the chain proves
wire-parsed pair — the serve mediated the loop itselfthe runtime observed the dispatch and the returned result
reported pair — marked reported-by-clientthe client asserted a call and a result; the serve recorded the assertion, its digests and when — not that the tool ran

A reported result binds to its call by sequence number and hash, exactly as a wire-parsed pair does.

LiteLLM

A one-file callback, standard library only. It sees every structured tool loop that passes through LiteLLM — as a client library or through the proxy — and reports the model's tool_calls and the role: tool results fed back. It never sees the tool run, so ok means a result re-entered generation, not that the action took effect.

import litellm
from palimpsests_audit import PalimpsestsAudit   # integrations/litellm/palimpsests_audit.py
litellm.callbacks = [PalimpsestsAudit()]

Status: exercised against a live serve with synthetic tool calls; no real-traffic run on record yet.

MCP (stdio servers)

A one-file proxy in front of any MCP server that speaks stdio. It sits between client and server, so it observes both halves of every tools/call — request and response — and reports outcomes ok, error or cancelled. It forwards every byte unchanged and never blocks or alters a call.

{"mcpServers": {"fs": {
  "command": "python3",
  "args": ["/path/to/palimpsests_audit_mcp.py", "--",
           "npx", "-y", "@modelcontextprotocol/server-filesystem", "/data"]}}}

Status: exercised against a live serve with synthetic calls; no real-traffic run on record yet.

OpenCode

A dependency-free plugin: copy palimpsests-audit.js into .opencode/plugins/ (one project) or ~/.config/opencode/plugins/ (all projects). It reports the tools OpenCode executes — including loops the model ran in text, which the serve on its own cannot see.

Status on OpenCode 1.18.31, from two maintainer traffic runs: one reported pair reached the chain — a failed read, correctly bound. The call arrived through tool.execute.before; tool.execute.after did not fire, and the result arrived through the plugin's fallback path. Delivery of a successful result through that path has not been observed yet. The first run recorded no pairs, and why is not yet explained.

Limits

  • A reported record proves the report, not the action.
  • Client hook surfaces change between versions. A surface checker probes each client's hook surface and reports it green, red or skipped; each adapter's README states the version its claims were observed on.
  • Each adapter's README carries a paste-ready prompt for a coding agent, and says what it sees and what it cannot.