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:
MCP server exposing Polypack as persistent adaptive memory
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:
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.
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:
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:
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:
The RPM package provides the same systemd service, store location, localhost
Streamable HTTP endpoint, and Python 3.12 requirement as the Debian package.
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:
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.