-
Notifications
You must be signed in to change notification settings - Fork 0
Polypack MCP
Repository: imattau/polypack-mcp
Persistent, adaptive memory for MCP clients. polypack-mcp is a Model
Context Protocol (MCP) server that exposes polypack — specifically
its adaptive-memory layer — as memory tools an LLM agent
(Claude, Codex, or any other MCP client) can call directly. MCP-specific
tooling lives in this separate repo; the database itself remains an
independent dependency (polypack-db>=3.3.1 for the durable backend).
Simplest install, from PyPI:
python3 -m pip install 'polypack-mcp[polypack]'For a single MCP client, the default stdio server configuration is enough. To share one durable memory store between multiple clients (e.g. Claude and Codex on the same machine), run a long-lived Streamable HTTP service instead:
polypack-mcp setup --store ~/.local/share/polypack-mcpThis starts a stateless Streamable HTTP server at http://127.0.0.1:8765/mcp/
(via systemd --user where available), restarts it on failure, and prints
client configuration snippets. Point every client at that one URL — don't
also configure them with a command + --store, since that would start a
second process competing for the same store.
Debian/RPM packages install and start a system-level service in the same
shape, running as a dedicated polypack user with data in
/var/lib/polypack-mcp. See the
README for package
details, and the
docs directory
(getting started, operations, troubleshooting) for the rest.
Without --store, the server uses an in-memory reference backend —
convenient for smoke tests, but not durable.
Semantic retrieval is opt-in: sudo polypack-mcp embeddings setup qwen3 --system --store /var/lib/polypack-mcp runs a separate managed helper
(polypack-mcp-embedding.service) that serves Qwen3-Embedding-0.6B over
localhost HTTP. It loads in bfloat16 (~1GB resident vs. ~2.4GB in fp32) and
unloads itself after 15 minutes of inactivity, reloading on the next request
in a few seconds since weights stay cached locally. Without it — or if it's
stopped or errors — recall falls back to lexical and activation scoring
automatically; nothing breaks, retrieval just loses the semantic term. See
Vector search & embeddings for the underlying
EmbeddingProvider interface this helper implements.
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 the polypack:// URI scheme.
-
Memory classes are
entity,episodic,procedural, andsemantic— store project or user preferences asproceduralmemories (preferenceis not a separate class). These map onto polypack'sMemoryClass, each with its own default decay half-life. -
Retrieval (
memory_recall/memory_context) returns{items, metadata}. Metadata includes candidate/excluded counts, context matches, score components, fallback behavior, retrieval version, and selection statistics. With the optional Qwen helper (above) reachable, each item'sscoreis0.55 * semantic + 0.30 * lexical + 0.15 * activation, andscoreComponentsreports all three, summing toscore. Without it, scoring falls back tolexical + 0.25 * activationandscoreComponentsomitssemantic— its absence in a response tells you recall ran lexical-only. This blend is deliberately this server's retrieval policy rather than part of polypack itself: polypack supplies the primitives (similar_to, graph traversal, activation decay), and how they combine into one ranked result is an application choice — a different polypack-based consumer could reasonably weight them differently.memory_contexttreats itstoken_budgetas estimated tokens (ceil(content characters / 4), minimum one) and never returns an item that would exceed the remaining budget. Context is a soft preference by default — matching memories are preferred and unscoped global memories can fall back in; passstrict_context: truefor isolation (an empty isolated result reportsreason: "no_context_match"). -
Graph-hydrated recall —
memory_recallcan optionally hydrate related graph memories in the same call (include_neighbors,edge_types,depth,neighbor_limit), bounded and opt-in. Metadata reportsmoreNeighborsAvailablewhen eligible neighbors exceeded the cap.memory_link(default relationshipRESPONDS_TO) records handoffs, reviews, and fixes that address an earlier memory — graph edges, not free-text, are authoritative for relationships; usegraph_query(operation="relationship_diagnostics")to find legacyprovenance.responds_tovalues not backed by an edge. -
Feedback is activation feedback:
memory_feedback(useful=true)reinforces a memory,useful=falseprovides negative retrieval feedback — both surface the activation before/after and whether learned scoring weights changed (see pulse/recordFeedback). -
Supersession & consolidation (
memory_supersede,memory_consolidate) materializeSUPERSEDES,SUPERSEDED_BY, andCONSOLIDATED_FROMgraph edges — the same primitives as polypack'ssupersede/consolidate, exposed as MCP tools.memory_suppressexposes durable inhibition directly.
Mutating operations checkpoint immediately against a durable store, and the server flushes on shutdown.
pip install -e '.[dev]'
pytestThe test suite includes an MCP client/server protocol smoke test covering tool discovery, memory storage, recall, and resource reads.
Back to Home. See also Adaptive memory, the polypack feature this server exposes, and Four-Agents-Polypack, an experiment that uses this server as the shared memory for a multi-agent system.
polypack
By feature
- Property graph
- Query builder
- Vector search & embeddings
- Persistence
- Database core
- Schema migrations
- Adaptive memory
- Real-time sync
- React integration
Related projects
In the repo