Odel
Polypack Memory

Polypack Memory

Local
@imattauPythonUpdated Yesterday

MCP server exposing Polypack as persistent adaptive memory

polypack-mcp

Persistent, adaptive memory for MCP clients.

An MCP server that exposes Polypack as persistent adaptive memory. MCP-specific tools live here; the database remains an independent dependency.

Install and run

The simplest installation is from PyPI:

python3 -m pip install 'polypack-mcp[polypack]'

For one MCP client, use the default stdio server configuration. For Claude and Codex sharing the same durable memory, install once and create a long-running user service:

polypack-mcp setup --store ~/.local/share/polypack-mcp

This starts a stateless Streamable HTTP server at http://127.0.0.1:8765/mcp/, restarts it after a failure, and prints client configuration snippets. The setup command uses systemd --user; on systems without systemd, start the server directly:

polypack-mcp --transport streamable-http --port 8765 --store ~/.local/share/polypack-mcp

In shared Streamable HTTP mode, configure both clients with the URL. Do not configure them with a command and --store, since that starts two processes competing for the same durable store.

Codex (~/.codex/config.toml):

[mcp_servers.polypack]
  url = "http://127.0.0.1:8765/mcp/"

Claude Desktop:

{
  "mcpServers": {
    "polypack": { "url": "http://127.0.0.1:8765/mcp/" }
  }
}

Debian package

The Debian package installs and starts a system-level polypack-mcp service automatically. It runs as the dedicated polypack user, stores data in /var/lib/polypack-mcp, and exposes the same local Streamable HTTP endpoint:

sudo apt install ./polypack-mcp_<version>_amd64.deb

After installation, point Claude and Codex at http://127.0.0.1:8765/mcp/. The default port can be changed in /etc/default/polypack-mcp, followed by a service restart. The service can be managed with:

sudo systemctl status polypack-mcp
sudo systemctl restart polypack-mcp

The PyPI installation remains user-managed and uses polypack-mcp setup to create a per-user service instead.

Optional semantic retrieval

The default installation uses Polypack's local graph, activation, and lexical retrieval without downloading an AI model. To enable local Qwen semantic retrieval, run:

sudo polypack-mcp embeddings setup qwen3 --system --store /var/lib/polypack-mcp

This creates a managed localhost helper, downloads Qwen once into the store's embedding cache, and reindexes existing memories. The model is not bundled in the Debian/RPM package.

The helper loads Qwen3-Embedding-0.6B in bfloat16 (~1GB resident once loaded, versus ~2.4GB in fp32) and unloads it after 15 minutes of inactivity, reloading automatically on the next request. memory_recall results include a semantic entry in scoreComponents whenever the helper is reachable, alongside lexical and activation — the three sum to the reported score. If the helper is stopped or errors, recall falls back to lexical + activation scoring automatically. Check or disable it with:

polypack-mcp embeddings status
sudo polypack-mcp embeddings disable --system --store /var/lib/polypack-mcp

For a PyPI user service, omit sudo --system and use the user store:

polypack-mcp embeddings setup qwen3

APT repository

The latest Debian package is also published to the public APT repository at https://imattau.github.io/polypack-mcp. Configure it with the repository's signing key, then install and update normally:

curl -fsSL https://imattau.github.io/polypack-mcp/gpg.key \
  | sudo gpg --dearmor -o /usr/share/keyrings/polypack-mcp.gpg
echo "deb [signed-by=/usr/share/keyrings/polypack-mcp.gpg] https://imattau.github.io/polypack-mcp stable main" \
  | sudo tee /etc/apt/sources.list.d/polypack-mcp.list
sudo apt update
sudo apt install polypack-mcp

The repository is updated automatically for each v*.*.* release tag. See docs/apt-repository.md for maintainer setup instructions.

RPM package

RPM-based distributions can install from the public RPM repository:

sudo rpm --import https://imattau.github.io/polypack-mcp/rpm/RPM-GPG-KEY-polypack-mcp
sudo tee /etc/yum.repos.d/polypack-mcp.repo >/dev/null <<'EOF'
[polypack-mcp]
name=Polypack MCP
baseurl=https://imattau.github.io/polypack-mcp/rpm/
enabled=1
gpgcheck=1
gpgkey=https://imattau.github.io/polypack-mcp/rpm/RPM-GPG-KEY-polypack-mcp
EOF
sudo dnf install polypack-mcp

The matching .rpm asset is also attached to the GitHub release:

sudo dnf install ./polypack-mcp-<version>-1.x86_64.rpm

The RPM package provides the same systemd service, store location, localhost Streamable HTTP endpoint, and Python 3.12 requirement as the Debian package.

Run manually

pip install -e '.[polypack]'
polypack-mcp --store ./polypack-data

The server exposes seventeen focused tools: memory_store, memory_get, memory_update, memory_list_contexts, memory_delete, memory_recall, memory_context, memory_feedback, memory_suppress, memory_supersede, memory_consolidate, memory_link, memory_unlink, memory_thread, memory_store_batch, memory_link_batch, and graph_query. It also publishes context, active-memory, schema, stats, and agent workflow guidance resources under polypack://.

Memory classes are entity, episodic, procedural, and semantic. Store project or user preferences as procedural memories; preference is not a separate memory class.

When using a durable Polypack store, mutating operations checkpoint immediately and the server flushes the store during shutdown.

Retrieval tools return {items, metadata}. Metadata includes candidate and excluded counts, context matches, score components, fallback behavior, the retrieval version, and selection statistics. memory_context uses estimated tokens (ceil(content characters / 4), minimum one) as its token_budget. An item is never returned if it would exceed the remaining budget; budgets less than or equal to zero are rejected. Context is a soft preference: matching memories are preferred and unscoped global memories may be used as fallback. Pass strict_context: true for isolation. An empty isolated result reports reason: "no_context_match" and the searched context.

memory_recall can optionally hydrate related graph memories in the same call:

{
  "query": "identity cache fix",
  "context": "cross-agent",
  "include_neighbors": true,
  "edge_types": ["RESPONDS_TO"],
  "depth": 2,
  "neighbor_limit": 3,
  "limit": 20,
  "token_budget": 4000
}

Neighbor traversal is opt-in and bounded. limit caps the total response and neighbor_limit caps hydrated neighbors; metadata reports moreNeighborsAvailable when additional eligible neighbors were found. Neighbor items include their distance and connecting relationship metadata. Use memory_link with the default RESPONDS_TO relationship for handoffs, reviews, and fixes that address an earlier memory. Graph edges are authoritative for relationships; use graph_query(operation="relationship_diagnostics") to find legacy provenance.responds_to values that are not backed by edges. See polypack://help/workflow for the agent-facing workflow.

Feedback is activation feedback: useful=true reinforces a memory and useful=false provides negative retrieval feedback. Responses expose activation before and after plus whether learned weights changed. Supersession and consolidation materialize SUPERSEDES, SUPERSEDED_BY, and CONSOLIDATED_FROM graph edges.

Use memory_get for exact ID lookup and memory_update for mutable fields (context, confidence, provenance, and metadata). Content changes should use memory_supersede so history remains intact. Use memory_unlink to correct a relationship and memory_list_contexts to discover namespaces. memory_delete is permanent, requires confirm=true, and supports an optional revision check; prefer memory_suppress when retaining history is useful.

Pass --store to open a durable Polypack directory. Without it, the server uses the in-memory reference backend, which is convenient for smoke tests. The polypack extra requires polypack-db>=3.3.1 and uses its native ActivationEngine.working_memory selector for context assembly.

Development

pip install -e '.[dev]'
pytest

The test suite includes an MCP client/server protocol smoke test covering tool discovery, memory storage, recall, and resource reads.

Documentation