Bantamkit MCP README

The full upstream README, mirrored for reference. Install config, tool schemas, adoption signals and our own overview live on the Bantamkit MCP listing page.

bantamkit — memory MCP server for Claude Code, Cursor, VS Code Copilot and Claude Desktop

npm version PyPI version Python versions Node version License: MIT npm downloads PyPI downloads

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

Terminal
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_save and memory_recall do the work; memory_compact and memory_dream keep 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. --install writes 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-hooks puts 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 bantamkit lifts 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

TopicWhat you'll find
Install the MCP serverThree ways to set it up — pick one
Install once, run offline (recommended)One command; later launches need no network
Run with npx at every launchThe online form, and why it hangs offline
Install with Python (PyPI)A venv you keep; a wheelhouse for no-network machines
Connect to a hostThe same five steps for every host
Connect to Claude Code--install claude, claude mcp list, claude mcp remove
Connect to Claude Desktopclaude_desktop_config.json per OS
Connect to Cursor~/.cursor/mcp.json
Connect to VS Code (GitHub Copilot)mcp.json with the servers key
Connect other MCP clientsCodex and any stdio host
ConfigurationEvery flag and environment variable, with its default
Update--update, then restart the server
TroubleshootingTimeouts, Connection closed, refusals, the wrong store
What it serves15 tools, three prompts, two resource templates
Use it as a Python librarypip install bantamkit and a minimal agent
Recommended defaultsWhich components to attach, measured on four models
DocumentationEvery page under docs/
Repo layoutWhat lives where

📥 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:

Terminal
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)

Terminal
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 npx entry needs --force (Claude Code: claude mcp remove first).
  • Installing into another host while offline: plain npx -y hangs before bantamkit starts. Use npx --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

config.json
{"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)

Terminal
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:

Routecommandargs
npm, install once/absolute/path/to/node["/Users/you/.bantamkit/mcp/node_modules/bantamkit-mcp/dist/cli.js"]
Python venv/absolute/path/to/env/bin/bantamkit-mcp[]
npx every launchnpx["-y", "bantamkit-mcp"]

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

  1. Command: npx -y bantamkit-mcp@latest --install claude

  2. File: none edited directly — it runs claude mcp add bantamkit -s user -- <command> <args> (user scope, every project), because ~/.claude.json also holds host state that is not MCP config.

  3. Entry: printed as ran : claude mcp add bantamkit -s user -- <node> <cli.js>.

  4. Confirm: claude mcp list prints bantamkit: <node> <cli.js> - ✔ Connected (Claude Code 2.1.272; run it outside a project whose .mcp.json also names bantamkit, or it prints [Conflicting scopes]). In a session, ask the agent to call bantamkit_status.

  5. Undo / re-run: --force does not reach Claude Code, and a second add fails with MCP server bantamkit already exists in user config. Remove first:

    Terminal
    claude mcp remove bantamkit -s user
    npx -y bantamkit-mcp@latest --install claude
    

Connect to Claude Desktop

  1. Command: npx -y bantamkit-mcp@latest --install claude-desktop

  2. File: macOS ~/Library/Application Support/Claude/claude_desktop_config.json · Windows %APPDATA%\Claude\claude_desktop_config.json · Linux ~/.config/Claude/claude_desktop_config.json

  3. Entry (key mcpServers):

    config.json
    {"mcpServers": {"bantamkit": {"command": "/absolute/path/to/node", "args": ["/Users/you/.bantamkit/mcp/node_modules/bantamkit-mcp/dist/cli.js"]}}}
    
  4. Confirm: it prints installed bantamkit into claude-desktop with file, key and command. Fully quit and reopen Claude Desktop, then ask it to call bantamkit_status.

  5. Undo / re-run: there is no uninstall flag — delete the bantamkit entry or restore claude_desktop_config.json.backup-<date>. A matching re-run prints bantamkit is already installed in claude-desktop and matches; a differing entry needs --force.

Connect to Cursor

  1. Command: npx -y bantamkit-mcp@latest --install cursor

  2. File: ~/.cursor/mcp.json on every OS (%USERPROFILE%\.cursor\mcp.json on Windows); .cursor/mcp.json for one project, by hand.

  3. Entry (key mcpServers):

    config.json
    {"mcpServers": {"bantamkit": {"command": "/absolute/path/to/node", "args": ["/Users/you/.bantamkit/mcp/node_modules/bantamkit-mcp/dist/cli.js"]}}}
    
  4. Confirm: it prints installed bantamkit into cursor and key : mcpServers. Restart Cursor and ask the agent to call bantamkit_status.

  5. Undo / re-run: delete the entry or restore mcp.json.backup-<date>. To replace a differing entry, such as an old npx one:

    Terminal
    npx -y bantamkit-mcp@latest --install cursor --force
    

Connect to VS Code (GitHub Copilot)

  1. Command: npx -y bantamkit-mcp@latest --install copilot

  2. File: macOS ~/Library/Application Support/Code/User/mcp.json · Windows %APPDATA%\Code\User\mcp.json · Linux ~/.config/Code/User/mcp.json; .vscode/mcp.json for one workspace, or MCP: Open User Configuration, by hand.

  3. Entry — the key is servers, not mcpServers, plus "type": "stdio". This is the detail that catches people out:

    config.json
    {"servers": {"bantamkit": {"type": "stdio", "command": "/absolute/path/to/node", "args": ["/Users/you/.bantamkit/mcp/node_modules/bantamkit-mcp/dist/cli.js"]}}}
    
  4. Confirm: it prints installed bantamkit into copilot and key : servers. Restart VS Code and ask Copilot to call bantamkit_status.

  5. Undo / re-run: delete the entry or restore mcp.json.backup-<date>; --force replaces 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.

SettingWhat it doesDefaultExample
BANTAMKIT_MEMORY_DIRPins the store to one absolute path; a missing or relative path refuses at startupunset: nearest existing .bantamkit/memory at or above the start directory"env": {"BANTAMKIT_MEMORY_DIR": "/abs/project/.bantamkit/memory"}
--store STOREOne store, layering off; outranks BANTAMKIT_MEMORY_DIRoff (layered)"--store", "/abs/store"
--start STARTWhere store discovery starts; not with --storecwd"--start", "/abs/project"
Layered memoryRecall reads the project store, stores granted in .bantamkit/config.yaml, and ~/.bantamkit/memory; saves go to the project storeondocs/memory.md → Layers
--k KDefault recall budget3"--k", "5"
--index-budget BYTESMemory index byte budget24000"--index-budget", "32000"
BANTAMKIT_EVENT_LOGLogs tool outcomes as JSONLoff; on → <store>/events/mcp.jsonl; other values are a path"env": {"BANTAMKIT_EVENT_LOG": "on"}
BANTAMKIT_RETENTIONThe daily Retention job: deletes session read ledgers older than 7 days, folds log lines older than 30 days, archives closed .shiftwork jobs 7 days after they close (verified before delete). It does not stop the daily skill audit, which has its own switch (next row)on; off (or 0/false/no) turns it off"env": {"BANTAMKIT_RETENTION": "off"} — docs/storage.md
BANTAMKIT_SKILL_AUDITThe daily skill audit (#205): the same once-a-day child audits your skills and writes ~/.bantamkit/skill-audit.json; bantamkit_status prints its last run. Its own switch: with BANTAMKIT_RETENTION=off and this on, the child still wakes once a day, audits, and deletes nothing. Off also silences the SessionStart skill-audit line, even over an older record; the skill_audit prompt still runs on requeston; off (or 0/false/no) turns it off"env": {"BANTAMKIT_SKILL_AUDIT": "off"} — docs/storage.md
BANTAMKIT_SKILL_AUTOSkills from experience (#206): lets the daily run INSTALL a skill it mined (twice the bar, a gated draft, one a day, five live, 30 days of probation) and make the low-risk EDITS to installed skills (keyword widening, a Pitfalls line, a drafted description) and PROMOTE a skill used 3 times in 30 days to a native link, on its own. Off, the same work waits for you as proposals in the skill_propose prompt; the judge still rolls back a change of bantamkit's that made things worse. bantamkit_status's skills: line ends with auto on or auto off (BANTAMKIT_SKILL_AUTO=on to opt in)off in 0.37.0; on (or 1/true/yes, any case) opts in, and any other value leaves it off"env": {"BANTAMKIT_SKILL_AUTO": "on"}
BANTAMKIT_LLM_URL, BANTAMKIT_LLM_MODELSkills from experience (#206): an OpenAI-compatible endpoint (<url>/chat/completions) bantamkit itself may ask to draft a skill, after MCP sampling and before the host agent. Both must be set. No key is sent but Bearer none, which local endpoints (Ollama, LM Studio) accept. The daily run drafts through it only when BANTAMKIT_SKILL_AUTO is onunset: no endpoint"env": {"BANTAMKIT_LLM_URL": "http://localhost:11434/v1", "BANTAMKIT_LLM_MODEL": "qwen2.5-coder"} — docs/skills.md
BANTAMKIT_SKILL_BUDGETSkills from experience (#206): the catalogue budget in bytes (the summed description bytes of every skill the host loads) that promoting a skill to a native link may not exceed8192; any value that is not 1–15 digits falls back to it"env": {"BANTAMKIT_SKILL_BUDGET": "12000"}
BANTAMKIT_INDEX_DIRWhere the derived recall indexes live (hot and cold); deleting them loses nothing~/.bantamkit/index"env": {"BANTAMKIT_INDEX_DIR": "/abs/scratch/index"}
BANTAMKIT_ASSETSYour own asset pack (skills, rubrics, schemas)the pack inside the package"env": {"BANTAMKIT_ASSETS": "/abs/my-assets"}
BANTAMKIT_HOST_LOG_ROOTWhere --mcp-report finds the host's MCP logsmacOS ~/Library/Caches/claude-cli-nodejs; elsewhere unsetBANTAMKIT_HOST_LOG_ROOT=/abs/logs bantamkit-mcp --mcp-report
BANTAMKIT_PRICESPrice table for the token ledgerpricing/default.json in the asset pack"env": {"BANTAMKIT_PRICES": "/abs/prices.json"}
--whichWhere a checkout launcher resolved its halves — only tools/bantamkit-mcp and tools/bantamkit-mcp-node, not the npm/PyPI package—tools/bantamkit-mcp --which

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

Terminal
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

SymptomFix
The host times out; the server never answersThe entry uses npx with a registry spec and the network is down. Use Install once, run offline
ENOENT from the hostA GUI host does not read your shell rc, so npx/node is not on its PATH. --install records absolute paths
Connection closed at startupOlder builds crashed when a GUI host started them in /. Update; see docs/mcp.md
already has a bantamkit entry with different settings … re-run with --force to replace itRe-run with --force; the old file is kept as .backup-<date> (.backup-<date>.1 and on for a later write the same day)
MCP server bantamkit already exists in user configclaude mcp remove bantamkit -s user, then install again
The server stopped launching after a node changenpx -y bantamkit-mcp@latest --install <host> --force with the node you have now
Recall finds nothing, or the wrong storeSet BANTAMKIT_MEMORY_DIR; the reply names the store it searched (the three states)

🧰 What it serves

Both servers serve the same 16 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):

ToolWhat it does
memory_savestore one durable fact, deduped and budgeted
memory_recallretrieve facts matching a query
memory_compactarchive the stalest facts to fit the index budget
memory_dreamconsolidate facts the project and profile layers hold under the same name
memory_querieslist the facts that have no likely-prompt queries yet, and store the queries written for them; recall matches a prompt against them
validate_jsonvalidate a document against a JSON Schema
skill_auditaudit a skill catalogue for findings
shiftwork_clock_inopen a unit of work and get its brief
shiftwork_clock_outclose a unit with status and accounting
shiftwork_statusread-only progress summary of a checkpoint
shiftwork_planread-only: which units of a checkpoint its depends_on graph permits to run at once. Never moves the cursor
work_planturn any {id, depends_on, priority} graph into the batches that may run in parallel, plus the widest fan-out
token_ledgerwhat a session cost, read off the host's transcripts
bantamkit_statusis bantamkit working, and which build: version, build_id, store health against its budget
build_identityreport the fingerprint of the source on disk, not the executing code — useful when a machine carries two installs under one name

🐍 Use it as a Python library

Terminal
pip install bantamkit

Editable install and runtime differences: docs/install.md, docs/porting.md. Copy-paste start: examples/.

server.ts
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 CritiqueGate on 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 FileAccessGraph when the agent reads files, on ~4B-class models.
  • full (memory + schema + grounded critique) is a 4b-reference result — 66/66 there only.
  • Prefer GroundedCritiqueGate over CritiqueGate when the agent has tools — same 4b scope.

📚 Documentation

PageCovers
InstallRequirements, editable install, endpoints, BANTAMKIT_ASSETS, measured MCP install detail
ArchitectureThe 5-layer model and the no-mixing rule
UsageClient, agent, tools, components, structured(), errors, recommended defaults
MemoryStore layout, the four ops, dedupe and budget, layers, the operator CLI (python -m bantamkit.memory / bantamkit-memory)
File-access graphThe read ledger and the file_graph query tool
EvalRunning the suite, the config matrix, current results
MCPbantamkit-mcp for Claude Code, Codex and any MCP client
Event logThe JSONL outcome log, its vocabulary and the 1 MiB cap
MCP report--mcp-report: the host's MCP log joined with the event log
Status linebantamkit-mcp --statusline and the Claude Code statusLine adapter
Hooks--install-hooks: what each Claude Code hook entry does and what it costs
Statusbantamkit_status, line by line, and the degraded footer
Token ledgertoken_ledger: what a session cost, and the price table
Skill auditskill_audit: what the skill catalogue costs every session
Skills from experienceskill_propose: skills bantamkit mines from repeated, successful work, the [skill] layer, promotion and self-improvement
Shift-workCheckpoint contract and clock-in/clock-out driver (experimental)
PortingThe Node port, PyScalar, and where the two runtimes deliberately differ
ConformanceThe two-runtime diff harness and what a ruling: pins
Releasing to npmWhat ships and the pre-publish checklist

📁 Repo layout

PathWhat
runtime-py/The Python runtime (bantamkit package) and its test suite
runtime-ts/The pure-Node MCP server (bantamkit-mcp on npm)
assets/Language-agnostic asset pack: skills, rubrics, tool schemas, eval tasks
examples/Runnable starter scripts (quickstart, structured output, layered memory)
tools/Repo tools that ship outside the wheel (e.g. the shift-work driver)
docs/This runbook

Design notes live in docs/superpowers/specs/.