Persome

Local-first Personal Model Runtime for macOS

View the Project on GitHub Intuition-Lab/personal-model

MCP

Persome exposes local capture context, durable personal memory, model structure, and explicit correction through the Model Context Protocol. MCP runs either in the daemon over streamable HTTP or as a per-client stdio process.

Start

persome start
# http://127.0.0.1:8742/mcp

# or
persome mcp

The daemon endpoint requires Authorization: Bearer <PERSOME_LOCAL_API_TOKEN>. The token is provisioned in the owner-only Runtime env file. Stdio does not need or copy that bearer. Stdio also skips construction of the daemon-only REST/Chat application and never runs database recovery, keeping per-client cold starts bounded to MCP tools. Integrity recovery remains a daemon-start and maintenance responsibility.

Stdio processes are shared-database clients: they can read and apply explicit row-level memory writes, but they do not create or migrate schema and they disable per-connection WAL auto-checkpoints. Onboarding normally initializes the database already; for a brand-new or externally upgraded data root, run persome start once before connecting stdio clients. While the daemon is live, it pre-initializes every registered store schema, publishes an exact revision and schema fingerprint, keeps the schema-owner connection, and performs WAL maintenance. A stdio client rejects a missing, stale, future, or mismatched receipt, and its SQLite authorizer rejects any schema-changing statement that escapes the client-safe store helpers.

Example stdio client configuration:

{
  "mcpServers": {
    "persome": {
      "command": "persome",
      "args": ["mcp"]
    }
  }
}

Core tools

Tool Purpose
list_memories List durable Markdown memory files.
read_memory Read one memory file with time, tag, and tail filters.
search Search durable memory with BM25 and optional dense retrieval.
read_receipt Resolve a memory entry to its provenance.
related_events Retrieve time-adjacent context around one memory entry: overlapping timeline blocks plus nearest captures, anchored on parseable occurred_at else write time. Context is observed data, not evidence for the entry.
resolve_evidence Resolve model, memory, activity, and capture references through one progressive evidence contract.
recent_activity Read recent durable event entries.
behavior_patterns Read modeled behavioral patterns plus evidence-backed observed workflow playbooks.
get_model_snapshot Return a bounded model overview or one paged Point/Line/Face/Volume/Root/receipt section.
entity_graph Read the entity/relation graph; retained as a compatibility model view.
verify_fact Check a claim’s freshness and explain existing open contradiction ledger rows.
remember Append an explicit, auditable memory.
correct_memory Supersede or revoke memory through the correction workflow.
process_pending_model_work Process a bounded number of pending sessions with the connected client’s model allowance through MCP Sampling.
get_pending_model_work Inspect the semantic session backlog without invoking a model.

Capture and state tools

Tool Purpose
current_context Return recent capture headlines/full text and model-eligible timeline blocks; each block includes normalization_status.
search_captures Search the local capture index.
read_recent_capture Read an exact returned file_stem or nearest recent capture, with screenshot opt-in.
attention_trajectory Read the derived attention path used by state formation.
get_schema Return the Markdown memory schema.

search_captures degrades explicitly: while the daemon’s index-health report is degraded or stale, its JSON payload carries an index_health object (status, index, capture_state, index_backlog, note), and a corrupt capture index raises an actionable tool error rather than returning silently partial results.

Wearable tools

Tool Purpose
query_health_metrics Query owner-authorized wearable observations by metric, provider, time range, and limit.

Wearable results are raw consumer-device observations with source and import timestamps. Clients must not present them as medical diagnoses.

resolve_evidence returns explicit stored lineage in sources and time-adjacent capture clues in context. Consumers must not present context as direct proof. Display label as the human-readable card title and keep reference as the stable technical handle. Point predecessor/successor links are returned separately in history. Follow each returned reference to move down one layer; a retained receipt whose payload is no longer available returns status=missing.

behavior_patterns includes only active skill files with a current evidence-backed observed-pattern entry. Later trigger echoes do not replace the playbook. A playbook can guide personalization and imitation, but it never grants a client permission to execute the observed actions.

verify_fact remains a deterministic read: it does not judge whether a claim is true. When a recalled entry participates in an open contradiction ledger row, the result includes the recorded reason and bounded competing claim. Resolved or dismissed rows are not replayed.

Bounded model projection

The canonical model snapshot contains every non-archived historical Point, evolution Line, and evidence receipt, so it grows with the audit history. MCP does not put that complete object in one result. get_model_snapshot defaults to an explicit overview envelope containing:

projection_schema_version, model_schema_version, section,
generated_at, build, model_stats, root, faces, volumes,
coverage, paging, full_export

Root, Face, and Volume objects retain their high-level meaning and evidence counts, while unbounded member/receipt arrays are summarized. Points, Lines, Faces, Volumes, Root, and receipt objects can be read with their section name, a maximum limit of 100. Subsequent pages use the returned opaque cursor. Pass up to 20 exact ids instead of a cursor for a focused selection. Set include_evidence_refs=true only when the full aggregate references are needed; the byte budget still applies.

Call a paged section without cursor for its first page, then pass that page’s opaque next_cursor as cursor for the next page. The overview does not return a page cursor. The JSON string in the MCP result’s content[0].text is capped at 64 KiB. JSON-RPC framing and escaping add transport bytes outside this payload budget. The server reduces the effective page before serialization and returns a small explicit error if one object by itself cannot fit. When later items remain, that error includes a resume_cursor that explicitly skips the oversized object. One call is transactionally stable, but a page sequence is not a frozen database revision; restart if a cursor is stale. Default redaction applies before projection.

To avoid rebuilding a large canonical object for every page, one redaction variant is retained in process memory for at most 15 seconds; explicit MCP memory/model writes clear it, and it is never written to another file.

Use the CLI for the complete schema-v1 object:

persome model export --out ./model-snapshot.json
persome model export --out ./model-snapshot.json --raw  # explicit local opt-out

section="full" returns a bounded export hint and never constructs an unbounded MCP response. CLI export and owner-local /model/graph retain the complete historical/audit contract.

v0.4.0 response migration

The bounded default is a breaking MCP response-contract change scheduled for the next minor release, v0.4.0, rather than a v0.3.x patch. In v0.3.x, get_model_snapshot(redact=...) returned the complete canonical schema_version: 1 snapshot. In v0.4.0, the same call returns the separately versioned section="overview" envelope.

Client integrations must detect projection_schema_version, treat omitted overview sections as omitted rather than empty, and request the required page explicitly. Integrations that need one complete canonical object must use persome model export; owner-local /model/graph and CLI export retain the canonical schema-v1 shape.

Transport

[mcp]
auto_start = true
transport = "streamable-http"
host = "127.0.0.1"
port = 8742

Security and privacy

Agent-funded modeling

There are two credential-owner-preserving routes:

  1. [agent_funding] invokes an authenticated Codex, Claude Code, or Cursor Agent CLI for normal background stages. Enable it explicitly with persome llm agent setup or an installer’s --fund-model flag. A durable per-day invocation cap, per-call timeout, and concurrency limit bound spend.
  2. process_pending_model_work borrows the originating MCP session for one explicit bounded batch and requires Sampling with tools.

The CLI bridge passes prompts on stdin with a scrubbed environment. It never opens ~/.codex/auth.json, Claude credentials, Cursor credentials, or another OAuth store. Codex runs ephemeral in a read-only sandbox with user MCP/config disabled; Claude disables built-in tools, MCP servers, settings, and session persistence. Cursor runs without --force in an empty private temporary directory because its current CLI does not expose equivalent isolation flags. Only enable any route for a trusted client account.

process_pending_model_work(max_sessions=1) is the provider-neutral path for using a model entitlement already available in Codex, Claude, or another MCP client. Persome negotiates the client’s sampling and sampling.tools capabilities. When supported, stage prompts run through sampling/createMessage; no subscription credential or OAuth token is read, copied, or persisted by Persome.

The operation must originate in a client tool call and is bounded to 1–10 sessions. Persome does not initiate MCP Sampling from its background daemon. Cancelling the originating tool call cancels any in-flight Sampling request; the per-call Sampling deadline does the same, and either path rejects further Sampling calls so no additional client allowance is spent. Clients that only implement MCP tools return client_missing_sampling_with_tools; use another compatible client, a local provider, a configured API provider, or the agent CLI bridge in that case. Scheduled writers use [agent_funding] when it is enabled and otherwise retain the configured provider route.

The same loopback ASGI app serves /model and the authenticated REST routes. Use persome model open for a one-time browser bootstrap.