MCP Tools

Pensyve exposes an MCP server over stdio. Connect it to any MCP-compatible client (Claude Desktop, Claude Code, Cursor, etc.).

# Run the MCP server
cargo run -p pensyve-mcp

The MCP server uses the rmcp crate with stdio transport. All logging goes to stderr — stdout is reserved for the MCP protocol.


Configuration

The server reads these environment variables on startup:

VariableDefaultPurpose
PENSYVE_PATH~/.pensyve/defaultSQLite storage directory
PENSYVE_NAMESPACE"default"Memory namespace

On startup the server attempts to load embedding models in order:

  1. GTE (Alibaba-NLP/gte-base-en-v1.5, 768 dims) — preferred, highest quality
  2. MiniLM (all-MiniLM-L6-v2, 384 dims) — fallback if GTE unavailable
  3. Mock (768 dims, zero vectors) — last resort, disables semantic similarity

Do not switch between embedders after storing memories. Embedding dimensions must match — mixing GTE (768d) and MiniLM (384d) will break vector search. If you need to change embedders, delete the existing store and re-ingest.


Tools

pensyve_recall

Search memories by semantic similarity and text matching. Returns ranked results from episodic, semantic, and procedural memory.

Parameters:

NameTypeRequiredDescription
querystringyesSearch query text
entitystringnoEntity name to filter by
typesstring[]noMemory types to include: "episodic", "semantic", "procedural"
limitintegernoMax results (default: 5)

Returns: JSON array of memory objects, each with _type and _score fields. Embeddings are stripped from the output.

Example call:

{
  "name": "pensyve_recall",
  "arguments": {
    "query": "deployment process",
    "entity": "my-agent",
    "types": ["procedural"],
    "limit": 10
  }
}

Example response:

[
  {
    "_type": "semantic",
    "_score": 0.87,
    "id": "a1b2c3d4-...",
    "subject": "550e8400-...",
    "predicate": "deploys",
    "object": "via GitHub Actions CI pipeline",
    "confidence": 0.95
  }
]

pensyve_remember

Store an explicit fact about an entity as a semantic memory.

Parameters:

NameTypeRequiredDescription
entitystringyesEntity name
factstringyesThe fact to store
confidencenumbernoConfidence in [0, 1] (default: 1.0)

The fact is split on the first whitespace into predicate and object. An embedding is generated and stored alongside the memory.

Returns: The stored memory object (embedding stripped).

Example call:

{
  "name": "pensyve_remember",
  "arguments": {
    "entity": "alice",
    "fact": "prefers dark mode in all editors",
    "confidence": 0.9
  }
}

Example response:

{
  "id": "a1b2c3d4-...",
  "namespace_id": "...",
  "subject": "550e8400-...",
  "predicate": "prefers",
  "object": "dark mode in all editors",
  "confidence": 0.9,
  "stability": 1.0
}

pensyve_episode_start

Begin tracking an interaction episode with named participants.

Parameters:

NameTypeRequiredDescription
participantsstring[]yesEntity names of participants

Creates entities that don't exist yet (as agent kind).

Returns: Episode ID, participant list, and start timestamp.

Example call:

{
  "name": "pensyve_episode_start",
  "arguments": {
    "participants": ["alice", "my-agent"]
  }
}

Example response:

{
  "episode_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "participants": ["alice", "my-agent"],
  "started_at": "2026-03-19T12:00:00Z"
}

pensyve_episode_end

Close an episode and extract memories.

Parameters:

NameTypeRequiredDescription
episode_idstringyesEpisode ID from pensyve_episode_start
outcomestringno"success", "failure", or "partial" (default: "success")

Returns: Episode ID, memory count, outcome, and end timestamp.

Example call:

{
  "name": "pensyve_episode_end",
  "arguments": {
    "episode_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "outcome": "success"
  }
}

Example response:

{
  "episode_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "memories_created": 0,
  "outcome": "success",
  "ended_at": "2026-03-19T12:05:00Z"
}

pensyve_forget

Delete all memories associated with an entity.

Parameters:

NameTypeRequiredDescription
entitystringyesEntity name
hard_deletebooleannoPermanently delete (default: false)

Returns: Entity name, entity ID, and count of forgotten memories. Returns forgotten_count: 0 with a message if the entity is not found.

Example call:

{
  "name": "pensyve_forget",
  "arguments": {
    "entity": "alice",
    "hard_delete": true
  }
}

Example response:

{
  "entity": "alice",
  "entity_id": "550e8400-...",
  "forgotten_count": 12
}

pensyve_inspect

View all memories stored for an entity, optionally filtered by type.

Parameters:

NameTypeRequiredDescription
entitystringyesEntity name
memory_typestringnoFilter: "episodic", "semantic", or "procedural"
limitintegernoMax memories to return (default: 20)

Returns: Entity info, memory count, and array of memory objects (embeddings stripped).

Example call:

{
  "name": "pensyve_inspect",
  "arguments": {
    "entity": "alice",
    "memory_type": "semantic",
    "limit": 50
  }
}

Example response:

{
  "entity": "alice",
  "entity_id": "550e8400-...",
  "memory_count": 3,
  "memories": [
    {
      "_type": "semantic",
      "id": "...",
      "predicate": "prefers",
      "object": "dark mode",
      "confidence": 0.9
    }
  ]
}

pensyve_status

Get connection status, namespace info, and memory statistics. Free — not metered.

Parameters:

NameTypeRequiredDescription
entitystringnoGet stats for a specific entity

Returns: Mode (local/remote), namespace info, memory counts by type, entity count, vector index size, and health status.

Example response:

{
  "mode": "remote",
  "namespace": "default",
  "namespace_id": "550e8400-...",
  "stats": {
    "total_memories": 1247,
    "semantic": 847,
    "episodic": 400,
    "entities": 12,
    "vector_index_size": 1247
  },
  "health": "ok"
}

pensyve_account

Get account information. Free — not metered.

Parameters: None.

Returns: Mode and account context. In local mode, confirms unlimited self-hosted usage. In remote mode, directs to the Pensyve Cloud dashboard for plan and billing details.

Example response (local):

{
  "mode": "local",
  "message": "Local mode — no account or billing. Self-hosted with no usage limits."
}

Example response (remote):

{
  "mode": "remote",
  "message": "Account information available via the Pensyve Cloud dashboard.",
  "dashboard_url": "https://pensyve.com/settings/billing"
}

Production Behavior

Recall Engine

pensyve_recall uses 8-signal fusion for ranking: vector similarity, BM25 text matching, graph proximity, intent matching, recency, access frequency, confidence, and memory type boost. Key limits:

ParameterValueDescription
Default limit5Results returned per query
Max candidates100Internal candidate pool before ranking
Recall timeout5 secondsMaximum time for a single recall
Beam width10Graph traversal width
Max depth4Graph traversal depth

Entity Auto-Creation

pensyve_remember and pensyve_episode_start silently create entities (as agent kind) if they don't exist. There is no warning or confirmation — check pensyve_inspect to verify entity state.

Vector Index Rebuild

pensyve_forget rebuilds the entire in-memory vector index after deleting memories. With large stores, this can take a moment. The rebuild is necessary to remove stale entries and maintain search accuracy.

Namespace Isolation

Namespaces provide logical isolation within a shared SQLite database. Memories from one namespace are invisible to queries in another. Useful for separating dev/test/prod data or isolating per-agent memory.

Episode Memory Extraction

pensyve_episode_end closes the episode and returns memories_created: 0. Automatic memory extraction from episode content is planned but not yet implemented — memories should be stored explicitly via pensyve_remember during the episode.


Client Configuration

For full setup instructions across Claude Code, Claude Desktop, Cursor, and VS Code, see the MCP Setup Guide.