bantamkit — memory MCP server for Claude Code, Cursor, VS Code Copilot and Claude Desktop
Give your coding agent a memory that outlasts the session. bantamkit is an MCP server: the agent saves what is worth keeping — a preference you stated, a decision, the fix that worked — and recalls it next session instead of asking you again. It works with Claude Code, Claude Desktop, Cursor, GitHub Copilot in VS Code and any stdio MCP client. Install it once from npm or PyPI; after that it starts offline.
🚀 Quick start
npx -y bantamkit-mcp@latest --install claude # or claude-desktop, copilot, cursor
Then restart the host (in Claude Code, open a new session) and ask the agent to call
bantamkit_status. Prefer Python? pip install "bantamkit[mcp]" into a venv you keep, then
bantamkit-mcp --install claude. Every route and host is below.
✨ What you get
- Memory that persists. Facts are plain Markdown files under
.bantamkit/memory, deduped and held to a byte budget.memory_saveandmemory_recalldo the work;memory_compactandmemory_dreamkeep the store tidy. - Layered by default. Recall reads the project store, any stores you grant in
.bantamkit/config.yaml, and your profile store~/.bantamkit/memory. Saves go to the project store. - One command per host.
--installwrites the entry for Claude Code, Claude Desktop, Cursor or VS Code Copilot, backs up any file it edits, and never prompts. - Offline after one install. Both install routes record the server by absolute path, so no launch needs the network or your shell's PATH.
- Claude Code hooks, if you want them.
--install-hooksputs the memory index in front of each new session, surfaces matching facts on each prompt, and nudges a save at the end of a long session that saved nothing (docs/hooks.md). - More than memory. JSON Schema validation, a token ledger read off the host's transcripts, a skill-catalogue audit, and shift-work tools that plan and hand off multi-step jobs — the fifteen tools.
- Two runtimes, one store. Pure Node on npm and Python on PyPI read and write the same
files, and every surface is compared between both runtimes by a conformance suite
(
node tools/conformance/run.mjs --all). - A Python library for small models, too.
pip install bantamkitlifts small-model agents (~1B–8B, any OpenAI-compatible endpoint): malformed output, unreviewed answers, forgotten context and runaway loops are absorbed by code, and a bundled eval suite measures the uplift.
📑 Contents
📥 Install the MCP server
Two implementations of one server — Node on npm, Python on PyPI — share one memory store on disk. To just try it:
npx -y bantamkit-mcp --assets-root # Node, no Python required
pipx run --spec "bantamkit[mcp]" bantamkit-mcp --assets-root # Python
A host launches the server every session, so what matters is whether each launch needs the network. Pick one of the three ways below.
Install once, run offline (recommended)
npx -y bantamkit-mcp@latest --install claude # or claude-desktop, copilot, cursor
This runs npm install --prefix ~/.bantamkit/mcp once and records
<the node that ran it> ~/.bantamkit/mcp/node_modules/bantamkit-mcp/dist/cli.js, both absolute.
No later launch needs npx, the registry or your PATH, and it never downgrades a newer kept
install.
- The recorded node is one version of node. Switch away from it and re-run with
--force. - Replacing an old
npxentry needs--force(Claude Code:claude mcp removefirst). - Installing into another host while offline: plain
npx -yhangs before bantamkit starts. Usenpx --offline -y bantamkit-mcp@<version> --install <host>, or the kept install's own CLI:<node> ~/.bantamkit/mcp/node_modules/bantamkit-mcp/dist/cli.js --install <host>.
Measurements: docs/install.md → MCP server: measured install detail.
Run with npx at every launch
{"mcpServers": {"bantamkit": {"command": "npx", "args": ["-y", "bantamkit-mcp"]}}}
This asks the registry on every launch. Offline it fails silently: with a warm cache,
npx -y bantamkit-mcp, npx -y bantamkit-mcp@latest and a pinned version each hung to the 45 s
bound with 0 bytes on stdout, and the host reports only its own handshake timeout.
npx also caches what latest resolved to, so add @latest or pin a version
(why).
Install with Python (PyPI)
pip install "bantamkit[mcp]" # into a venv you keep, not a pipx run
bantamkit-mcp --install claude # or claude-desktop, copilot, cursor
--install records the venv's console script by absolute path with "args": [], so no launch
needs the network. With no network at all, pip download a wheelhouse on a machine with the
same OS, CPU architecture and Python version, then pip install --no-index --find-links:
steps.
🔌 Connect to a host
--install <host> (claude, claude-desktop, copilot, cursor) writes the entry. It backs
the file up first, refuses an entry that differs unless you pass --force, and never prompts —
so it behaves the same in a terminal, in CI and inside another agent. With Python, run
bantamkit-mcp --install <host> from your venv instead of the npx line.
Each host below has the same steps: 1 command, 2 file, 3 entry, 4 confirm,
5 undo or re-run. The entry's command and args depend on the install route:
For JSON hosts, a quick check of the recorded command: run it in a terminal — with nothing on
stdin it prints usage: bantamkit-mcp … and exits 0.
Connect to Claude Code
-
Command:
npx -y bantamkit-mcp@latest --install claude -
File: none edited directly — it runs
claude mcp add bantamkit -s user -- <command> <args>(user scope, every project), because~/.claude.jsonalso holds host state that is not MCP config. -
Entry: printed as
ran : claude mcp add bantamkit -s user -- <node> <cli.js>. -
Confirm:
claude mcp listprintsbantamkit: <node> <cli.js> - ✔ Connected(Claude Code 2.1.272; run it outside a project whose.mcp.jsonalso names bantamkit, or it prints[Conflicting scopes]). In a session, ask the agent to callbantamkit_status. -
Undo / re-run:
--forcedoes not reach Claude Code, and a second add fails withMCP server bantamkit already exists in user config. Remove first:claude mcp remove bantamkit -s user npx -y bantamkit-mcp@latest --install claude
Connect to Claude Desktop
-
Command:
npx -y bantamkit-mcp@latest --install claude-desktop -
File: macOS
~/Library/Application Support/Claude/claude_desktop_config.json· Windows%APPDATA%\Claude\claude_desktop_config.json· Linux~/.config/Claude/claude_desktop_config.json -
Entry (key
mcpServers):{"mcpServers": {"bantamkit": {"command": "/absolute/path/to/node", "args": ["/Users/you/.bantamkit/mcp/node_modules/bantamkit-mcp/dist/cli.js"]}}} -
Confirm: it prints
installed bantamkit into claude-desktopwith file, key and command. Fully quit and reopen Claude Desktop, then ask it to callbantamkit_status. -
Undo / re-run: there is no uninstall flag — delete the
bantamkitentry or restoreclaude_desktop_config.json.backup-<date>. A matching re-run printsbantamkit is already installed in claude-desktop and matches; a differing entry needs--force.
Connect to Cursor
-
Command:
npx -y bantamkit-mcp@latest --install cursor -
File:
~/.cursor/mcp.jsonon every OS (%USERPROFILE%\.cursor\mcp.jsonon Windows);.cursor/mcp.jsonfor one project, by hand. -
Entry (key
mcpServers):{"mcpServers": {"bantamkit": {"command": "/absolute/path/to/node", "args": ["/Users/you/.bantamkit/mcp/node_modules/bantamkit-mcp/dist/cli.js"]}}} -
Confirm: it prints
installed bantamkit into cursorandkey : mcpServers. Restart Cursor and ask the agent to callbantamkit_status. -
Undo / re-run: delete the entry or restore
mcp.json.backup-<date>. To replace a differing entry, such as an oldnpxone:npx -y bantamkit-mcp@latest --install cursor --force
Connect to VS Code (GitHub Copilot)
-
Command:
npx -y bantamkit-mcp@latest --install copilot -
File: macOS
~/Library/Application Support/Code/User/mcp.json· Windows%APPDATA%\Code\User\mcp.json· Linux~/.config/Code/User/mcp.json;.vscode/mcp.jsonfor one workspace, or MCP: Open User Configuration, by hand. -
Entry — the key is
servers, notmcpServers, plus"type": "stdio". This is the detail that catches people out:{"servers": {"bantamkit": {"type": "stdio", "command": "/absolute/path/to/node", "args": ["/Users/you/.bantamkit/mcp/node_modules/bantamkit-mcp/dist/cli.js"]}}} -
Confirm: it prints
installed bantamkit into copilotandkey : servers. Restart VS Code and ask Copilot to callbantamkit_status. -
Undo / re-run: delete the entry or restore
mcp.json.backup-<date>;--forcereplaces a differing entry.
Connect other MCP clients
Any stdio MCP client runs the same command/args; nothing is host-specific. Codex and a
generic JSON config: docs/mcp.md → Client setup. Hand-written forms
for every host: npm README ·
Python README.
🔧 Configuration
Flags go in the entry's args; environment variables in its env block (or
claude mcp add -e NAME=value). Both runtimes print the same --help.
Don't add --store by reflex: the layering is most of the value. One-shot commands that print
and exit: --install {claude,claude-desktop,copilot,cursor} (with --force),
--install-hooks / --remove-hooks (with --yes), --hook, --update,
--assets-root, --mcp-report, --statusline.
More: store binding ·
pinning ·
event log · prices.
🔄 Update
npx -y bantamkit-mcp@latest --update # patches the kept install at ~/.bantamkit/mcp
npx -y bantamkit-mcp@latest --assets-root # npx CACHES; without @latest you get an old resolve
npm i -g bantamkit-mcp@latest # global npm install
pip install -U "bantamkit[mcp]" # PyPI (pipx upgrade bantamkit · uv tool upgrade bantamkit)
git pull && npm ci --prefix runtime-ts && npm run build --prefix runtime-ts # a checkout: dist/ is build output
--update (check the package index and update this install if it differs, then exit) patches a
registry install or a kept install to exactly the version it compared, and reports success only
after the install says so; any other shape it refuses with exit 1 and names the manual route.
It is the only network access here, and only when you type it.
Then restart the server in the host (/mcp → reconnect in Claude Code; a full restart of
Claude Desktop) — a running server keeps the code it started with. bantamkit_status prints the
version and the build_id of the code answering you; a new version with an old build_id
means an old process. Per-install table: npm README → Updating.
🩺 Troubleshooting
🧰 What it serves
Both servers serve the same 15 tools, three prompts and two resource templates
(bantamkit://skills/{name}, bantamkit://rubrics/{name}). The prompts are what a person invokes from
the host's slash menu: bantamkit_status (the status report), skill_audit (#205: gathers the
skills this host loads, audits them, and inserts the report plus a proposed settings.json change
that is never applied for you; in Claude Code it is /mcp__bantamkit__skill_audit) and
skill_propose (#206: lists the skills bantamkit proposes from your repeated, successful work and
the ones it installed, and approves, rejects, undoes, promotes or demotes one; in Claude Code it is
/mcp__bantamkit__skill_propose, see docs/skills.md):
🐍 Use it as a Python library
pip install bantamkit
Editable install and runtime differences: docs/install.md,
docs/porting.md. Copy-paste start: examples/.
from bantamkit import Agent, CritiqueGate, Memory, OpenAICompatible, Tool, ToolDef
client = OpenAICompatible(base_url="http://localhost:11434/v1", model="qwen2.5:7b-instruct")
price_lookup = ToolDef(
tool=Tool(
name="price_lookup",
description="Get the unit price of an item",
parameters={
"type": "object",
"required": ["item"],
"properties": {"item": {"type": "string"}},
},
),
handler=lambda item: f"{item} price: 25",
)
agent = Agent(client=client, tools=[price_lookup]).use(
Memory(store="./.bantam-memory"),
CritiqueGate("task-completion"),
)
result = agent.run("What does a widget cost? Remember it for next time.")
print(result.output, result.usage.total)
📊 Recommended defaults
Measured on the bundled 22-task suite across four models, 528 runs each. Numbers and caveats: docs/usage.md → Recommended defaults.
- Always attach
Memory— the biggest single mover on every model measured. - Skip the blind
CritiqueGateon small instruct models — ≤6 passes at 2–3.5× bare's tokens. - Don't credit a rubric edit without a bar — the non-fragile anchor set is the floor.
- Use
structured()for schema'd output — zero schema retries in 2,112 runs. - Attach
FileAccessGraphwhen the agent reads files, on ~4B-class models. full(memory + schema + grounded critique) is a 4b-reference result — 66/66 there only.- Prefer
GroundedCritiqueGateoverCritiqueGatewhen the agent has tools — same 4b scope.
📚 Documentation
📁 Repo layout
Design notes live in docs/superpowers/specs/.