TokenMizer
TokenMizer's server lets you persist and resume AI sessions as a knowledge graph, inspect session memory, and analyze project artifacts.
checkpoint_session — save the current session to graph memory under a session ID for later resumption.
resume_session — retrieve a compact resume context (critical/standard/full detail levels) to inject into a new session.
get_graph_stats — view counts of tracked tasks, decisions, files, and errors for a session.
analyze_file — summarize large files (CSV, Excel, PDF, JSON) into ~300–500 tokens with schema, stats, and samples.
get_savings_stats — report token savings analytics for today/week.
why_decision — trace the supersession chain for a decision (old → new) and explain why a choice is currently active.
Acts as a proxy for Google Gemini, applying compression, semantic caching, and memory graph features to reduce token consumption and maintain conversational context.
Supports proxying requests to Ollama's locally hosted models, with the same pipeline of compression, caching, and graph memory for efficient and persistent AI interactions.
Provides an OpenAI-compatible proxy endpoint that adds compression, semantic caching, and graph-based memory to any OpenAI model, reducing token usage and enabling session persistence.
The problem
Every AI session has a context limit. When you hit it, the model forgets every decision and every rationale built over hours of work, and you spend the first ten minutes of the next session re-explaining the project.
Summarising the history does not fix this. A summary tells you what was decided; it loses why, and it loses what was rejected — so the model happily re-proposes the thing you moved off three sessions ago.
Related MCP server: Hippocampus
Quick start
pip install "tokenmizer[anthropic,cache]"
export TOKENMIZER_ANTHROPIC_API_KEY=sk-ant-...
tokenmizer serveThen change one line in your client:
from openai import OpenAI
client = OpenAI(
api_key="your-key",
base_url="http://localhost:8000/v1", # only this changes
)
resp = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[{"role": "user", "content": "Continue where we left off"}],
extra_body={"session_id": "my-project"}, # optional, enables memory
)Everything else is unchanged: same request shape, same response shape,
plus a tokenmizer block reporting what was saved. Open
http://localhost:8000 and the session is already there.
Windows (PowerShell)
$env:TOKENMIZER_ANTHROPIC_API_KEY = "sk-ant-..." # this session
setx TOKENMIZER_ANTHROPIC_API_KEY "sk-ant-..." # persistentNo API key? Ollama runs locally and free:
ollama pull llama3
pip install tokenmizer
# then set `provider: ollama` in tokenmizer.yamlDocker
docker compose up -dFull installation notes, every provider's environment variable, and the configuration reference are in docs/configuration.md and docs/deployment.md.
See it
Nothing here is a mockup. Every screenshot and the demo below are the
shipped UI rendering a session from the labelled corpus in
benchmarks/eval/corpus.
The session graph is a page you drive, not a picture
Select a node and you get its type, status, community, importance, confidence, when it was first seen and every relation it carries — the provenance behind a fact, not just the fact. Filter a type or a community and the counts move with it. Three layouts, a light theme and a PNG export are one click each.
It is one self-contained HTML file with no external requests, so it
opens offline, works from a file:// URL, and can be sent to someone who
has never installed TokenMizer.
The dashboard tells you what it actually knows
Your sessions, the live resume block each one would inject right now, and
its graph — not an example of one. The health pill reads /health, which
reports degraded with the counters behind it when a write has failed,
rather than saying ok whatever happened.
The session graph, grouped the way you would group it
Each node type gets its own arc of the circle, named on the ring, and relations are drawn as chords bowed through the middle — so the shape of the session is readable before you read a single label, and which type a node is comes from where it sits, not from telling two hues apart. The palette is checked with a validator, not by eye: every adjacent pair clears the colour-blind separation floor, and the four types that carry no meaning of their own share one neutral grey.
The panel beside it counts what the session knows and what is missing — open issues, decisions changed, history gaps, unconnected nodes — then lists the detected communities, the hotspots everything hangs off, and which kinds of node point at which. Filter by type or community, search, click a node for the supersession chain behind it.
The same session as a story
Timeline mode puts each node type in its own lane, ordered by when the fact entered the session, with supersessions drawn as arcs. When a whole transcript was checkpointed in one call every node shares a timestamp, so the axis says so and falls back to the order the session stated things rather than inventing dates.
How it works
TokenMizer is a local proxy between your app and any LLM. Every request passes through a pipeline that builds a live knowledge graph, compresses inputs, caches responses, and checkpoints before the context runs out.
flowchart LR
App["Your app<br/><sub>OpenAI-compatible client</sub>"]
subgraph TM["TokenMizer :8000"]
direction TB
L0["<b>L0</b> File intelligence"]
L1["<b>L1</b> Prompt compression"]
L2["<b>L2</b> Terse-output injection"]
L4["<b>L4</b> Graph memory<br/><sub>extract to window to inject</sub>"]
L3["<b>L3</b> Semantic cache"]
L5["<b>L5</b> Provider prompt cache"]
L0 --> L1 --> L2 --> L4 --> L3 --> L5
end
LLM["Claude · GPT · Gemini<br/>Grok · DeepSeek · Ollama"]
DB[("SQLite<br/><sub>graph · checkpoints · ownership</sub>")]
App -->|"POST /v1/chat/completions"| TM
TM --> LLM
LLM -.->|response| TM
TM -.->|"response + savings"| App
L4 <-->|"per-row, locked"| DBThe graph is not a summary. It is typed nodes and edges — decisions, tasks, files, errors, goals — with a lifecycle, so a decision that gets replaced is marked superseded rather than deleted, and the transition records what triggered it. The resume block is a filtered projection of it: active decisions, open work, unresolved errors, in a few hundred tokens.
Edges carry the relations a session actually has. A task that fixed a bug
FIXES the error node and closes it. An open error BLOCKS the task
about it. A decision DEPENDS_ON the package it named. That is what the
communities above are detected from, and what /why walks.
To Architecture — the request sequence, the data model, and the decision lifecycle.
What a resume looks like
Goal: FastAPI authentication service with JWT and PostgreSQL
Working on: refresh token rotation in api/auth.py | rate limiting using slowapi
Done: Implemented POST /api/auth/login | Fixed the 422 in LoginRequest | User model in api/models.py
Decided: Use JWT and PostgreSQL | bcrypt for password hashing | Redis for refresh token storage
Changes: 'Use moment.js' -> 'Use date-fns' - tree-shakeable, saves 230KB
Files: api/auth.py, api/models.py, config.py, tests/test_auth.py
Continue from: Add rate limiting to auth endpointsA few hundred tokens in place of the whole conversation. The Changes:
line is the part a summary loses — and
GET /api/graph/{session_id}/why?q=date-fns replays the full chain with
the trigger, the reason and the evidence for each hop.
Habits, not just projects
A session graph remembers what you decided about this project. It does not remember that you want short answers — that is true of you, not of the repository, and it has to survive starting a session somewhere else.
preferences:
enabled: true # off by default; read the note before turning it onWith it on, a turn like "I prefer TypeScript, and keep answers brief" is
remembered per principal and injected as a few lines of system prompt.
/api/preferences (GET) shows exactly what was remembered and the exact
text it injects; the same path with DELETE and ?key=... forgets one,
without a key forgets all of them.
Off by default on purpose. The failure mode of a preference memory is not forgetting — it is remembering something that was never a preference and repeating it in every prompt you send for the rest of the year. The detector is a set of regexes and it will have false positives, which is why the endpoint above exists and why you turn this on deliberately.
Not only coding sessions
Set domain and the same five shapes are read in another vocabulary.
Nobody in an incident channel says "Decided:", and nobody in a research
log says "Fixed:" — which is why those sessions used to come back nearly
empty (macro F1 11%, decisions and errors at 0%).
domain: ops # coding (default) · research · ops · productIncident: We are seeing an incident on the pricing service, checkout is failing
Mitigating: Still monitoring the replica lag | Follow-up to add a pool-size alert
Done: Restarted the pool workers and rolled back to build 4471 | Traffic is recovered
Decided: Root cause is connection pool exhaustion after the 14:02 deploy
Symptoms: Error rate is 34 percent and p99 latency jumped to 8 seconds11% to 96% on the labelled sessions in benchmarks/eval/corpus_domains,
with the coding corpus unchanged — a pack's patterns run after the
coding ones and can only add. Three hand-written sessions, so read it as
"the mechanism works on sessions of this shape", not as a generalisation
claim; the benchmarks say the same.
Use it from your tools
Four ways in, depending on where you work. All of them talk to the same graph, so a session checkpointed from Claude Code resumes in the CLI.
Claude Code — plugin
/plugin marketplace add Shweta-Mishra-ai/tokenmizer
/plugin install tokenmizer@Shweta-Mishra-ai/tokenmizerThen, in any session:
/tokenmizer:checkpoint my-project save the session to graph memory
/tokenmizer:resume my-project load it back (~300 tokens)
/tokenmizer:analyze data/sales.csv digest a large file
/tokenmizer:stats token savings reportClaude Desktop, Cursor, VS Code, Zed — MCP server
{
"mcpServers": {
"tokenmizer": {
"command": "tokenmizer-mcp",
"env": { "TOKENMIZER_URL": "http://localhost:8000" }
}
}
}Client | Where that goes |
Claude Desktop (macOS) |
|
Claude Desktop (Windows) |
|
Claude Code |
|
Cursor | Settings, MCP, Add server, same JSON |
VS Code / Zed | their MCP settings, same |
Codex CLI |
|
Restart the client afterwards. You do not need to start anything else:
checkpoint_session, resume_session, get_graph_stats, why_decision
and analyze_file all read and write the graph directly when
tokenmizer serve is not running, and say which path answered. Only
savings need the proxy, since savings are measured on requests that pass
through it. If tokenmizer-mcp is not on your PATH, use
"command": "python", "args": ["-m", "tokenmizer.mcp.server"].
Six tools: checkpoint_session, resume_session, get_graph_stats,
get_savings_stats, analyze_file, and why_decision — ask your agent
"why did we pick X?" and it walks the supersession chain with the
reason and evidence for each hop.
Anything else — the proxy
Any OpenAI-compatible client works by pointing base_url at
http://localhost:8000/v1, as in the quick start above. That covers
Continue.dev, Aider, LangChain, LlamaIndex, the OpenAI SDKs in every
language, and curl.
Tool calling goes through too. Send tools / tool_choice in the
OpenAI shape and get message.tool_calls back, streamed or not, with
role: "tool" results round-tripping to the model:
resp = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[{"role": "user", "content": "weather in Pune?"}],
tools=[{"type": "function", "function": {
"name": "get_weather",
"parameters": {"type": "object", "properties": {"city": {"type": "string"}}}}}],
extra_body={"session_id": "my-project"},
)
call = resp.choices[0].message.tool_calls[0] # finish_reason == "tool_calls"Native for OpenAI, DeepSeek, Mistral, OpenRouter and Grok; translated for Anthropic, Ollama, Gemini and Cohere. All nine providers, streamed or not — each one's tool calls arrive on the stream as OpenAI-shaped deltas, whether the provider fragments them (Anthropic, Cohere) or sends them whole (Ollama, Gemini). Tool traffic is never compressed, and a tool-call turn is never cached.
To API & CLI reference — every endpoint, every command, every MCP tool.
Inside an agent — in-process, no server
For an agent loop that already owns its messages, use the memory directly. No proxy, no API key, no network; the same SQLite store the proxy uses, so an agent and the proxy can share a session.
from tokenmizer.agents import Memory
memory = Memory("order-service") # default: the working directory name
memory.add(messages) # {"role", "content"} dicts; idempotent
memory.search("what are we storing orders in", top_k=5)
memory.context(token_budget=400) # resume block for the system prompt
memory.why("postgres") # the decision trailsearch returns plain dicts (type, label, summary, status,
confidence); decisions() and errors() list each category. Works with
LangGraph, CrewAI, AutoGen or a hand-written loop the same way: call add
with the conversation so far, put context() in the system prompt.
Measured
python -m benchmarks.eval scores extraction against a labelled corpus
of 14 sessions, 6 of them real transcripts:
Category | Precision | Recall | F1 |
Files | 98% | 100% | 99% |
Decisions | 97% | 100% | 99% |
Completed tasks | 98% | 98% | 98% |
Pending tasks | 100% | 90% | 95% |
Errors | 93% | 96% | 94% |
macro F1 | 97% |
Precision is reported, not just recall. An extractor that emits the whole transcript as one node scores 100% recall, which is why recall-only extraction numbers should be distrusted — including our own earlier ones.
Scored separately by origin, because hand-written fixtures are easier than real transcripts and a single headline hides that: synthetic 98%, real 91%. Treat 91% as the number that describes real sessions. n=14 is a small sample and the same person wrote every label.
Retrieval is measured separately. python -m benchmarks.graph_retrieval.query_eval scores what query() returns for
questions phrased the way a person asks them, not in the node's own
words: recall@6 82% over 40 cases, keyword ranking only. The eval was
13 cases until this branch, where one case flipping moved the headline by
8 points; every case is checked to be answerable from its own transcript,
because an ungrounded question measures extraction and reads as a
retrieval failure forever. semantic_retrieval: auto turns on embedding
similarity when the model actually loads — the 92% figure previously
quoted for it predates the enlarged eval and has not been re-measured.
Independently verified against 7 other methods. A separate 100-session benchmark (tokenmizer-research, a different corpus and scorer than the numbers above) ties TokenMizer 0.5.4 for first place at 60% macro F1 — level with Mem0-style (60%) and Graphiti-style (59%), ahead of GraphRAG-style (44%), MemGPT-style (35%), and every naive baseline (under 20%).
To Benchmarks — memory quality against a plain-summary baseline, storage, and how to score your own sessions.
Why TokenMizer and not X?
Why not just use Git history? Git stores what changed, not why you decided to change it. You cannot ask Git "what did we decide about auth?" or "why did we switch from MySQL to PostgreSQL?" TokenMizer stores decisions with trigger, reason, and evidence — not diffs.
Why not RAG (retrieval-augmented generation)?
RAG retrieves relevant chunks — it does not model decision state. If you switched from bcrypt to Argon2 mid-session, RAG might retrieve both and confuse the model about which is current. TokenMizer tracks decision supersession explicitly: the old decision is marked SUPERSEDED, the new one ACTIVE, and the resume context only includes current state.
Why not a plain summary at the start of each session? Summaries lose structure. You cannot query "all superseded decisions" or "what triggered the auth change" from a blob of text. Our benchmark shows graph memory preserves 89% of labelled information against 79% for a summary baseline — and unlike a summary, the graph is queryable, editable, and grows incrementally instead of being re-summarized every turn. See Benchmarks.
Why not Mem0 or Zep? Mem0 and Zep store facts ("user prefers Python"). TokenMizer stores decisions with rationale — the full causal chain: what was decided, what replaced it, why, what evidence triggered the change. If you need "remember my name across sessions," use Mem0. If you need "remember that we switched from PostgreSQL to SQLite because of cost, and here is the evidence," use TokenMizer.
Why not Graphiti? Both build a temporal knowledge graph, and on the independent benchmark above they score within a point of each other. The differences are operational: TokenMizer runs on SQLite with no database to deploy, ships the graph as a self-contained HTML page you can open offline or send to someone, and is an OpenAI-compatible proxy — so adopting it is a base URL change rather than an integration. Graphiti is the better fit if you are already running Neo4j and want to query the graph in Cypher.
Why not just a longer context window? Longer context means higher cost, slower inference, and attention dilution on long histories. TokenMizer compresses a session into a resume block averaging 161 tokens (measured, n=3 — see Benchmarks) by extracting what actually matters, not by summarizing.
What is not implemented
Listed here rather than left to be discovered:
Setting | Status |
| Deprecated, removed next release. Never implemented. Use |
| Accepted, never implemented; behaves as |
| Accepted and ignored, with a server-side warning. Use |
The prioritised plan for these and everything else is in docs/roadmap.md, which pairs every planned item with the measurement that motivates it.
Documentation
Request pipeline, graph data model, decision lifecycle, file intelligence | |
Every setting, environment variables, precedence, providers | |
Endpoints, commands, MCP tools, tool calling, Claude Code integration | |
Docker, multiple workers, durability, session isolation, security | |
Extraction quality, memory quality, storage, running your own | |
Measured state of every layer, and the prioritised plan | |
Running alongside other token tools | |
Setup, layer rules, and how to improve extraction | |
How to run the suite, the coverage floor, and known limits | |
Release history and how to report a vulnerability |
Contributing
git clone https://github.com/Shweta-Mishra-ai/tokenmizer
cd tokenmizer
pip install -e ".[dev]"
pytest tests/ -q && ruff check tokenmizer/ # 1466 tests, must stay greenThe most valuable contribution is a session where extraction got it
wrong. The eval corpus is 14 sessions and the same person wrote every
label in it — that is the honest ceiling on what the numbers above can
tell you about your workload, and the only way past it is transcripts
nobody here wrote. Label a few of your own in the format documented in
benchmarks/eval/corpus.py and open a PR,
or open an issue
with the turn that was missed. Redact freely — the shape of the prose is
what matters, not its content.
CONTRIBUTING.md covers setup, the layer rules, and how to run the eval harness.
Contributors
TokenMizer is better because of the people who found something wrong with it and said so. Thank you.
The avatars above come from GitHub's contributor list, which counts commits. These lists do not, because some of the most useful things anyone did here never touched the code.
Sent a fix
@0xfroOty — negated-decision handling in the decision tracker (#22),
OutputTrimmerlevel alignment (#25), streaming cache-hit analytics (#31)@pollychen-lab — graph node IDs derived from stored (truncated) labels (#21), semantic-opposite decision detection (#26)
@floze-the-genius — dashboard stats authentication fix (#35)
@TechNovaWorldai — the
minimalterse prompt trimmed back under its own token budget (#63)
Found the bug in the first place — which this project considers the harder half, and says so above
@0xfroOty — opposite decisions merged into one node (#19), node IDs colliding after label truncation (#20),
fulltrimming behaving likelite(#23), streaming always recordingcache_hit=False(#30), dashboard stats failing under an API key (#34)@TechNovaWorldai — the terse prompt over its own budget (#62)
Looked at it from the outside
@neoneye (Simon Strandgaard) — an independent analysis of TokenMizer and a place for it among other agent-memory systems in the agent memory atlas (#39)
Support
If TokenMizer is useful to you, please give it a star. It takes a second and it genuinely helps.
Sponsorship is open too, if you would like to support the work. Entirely optional.
License
MIT © Shweta Mishra
Available Tools
6 toolsanalyze_fileA
Analyze a large file (CSV, Excel, PDF, JSON) and return a token-efficient summary. Instead of pasting thousands of rows into the chat, use this to get schema, statistics, and sample data in ~300-500 tokens.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | What you want to know about the file (improves relevance) | |
| file_path | Yes | Absolute path to the file to analyze | |
| token_budget | No | Max tokens for the summary (default: 500) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description carries full burden. It discloses the tool's token efficiency (~300-500 tokens) and what the summary includes (schema, statistics, sample data). No contradiction detected.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with purpose and benefit, no redundancy. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 3 parameters and no output schema, the description adequately explains the return format (schema, statistics, sample data) and token efficiency. Minor gap: no mention of error handling or prerequisites.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds value by explaining the 'query' parameter improves relevance and the 'token_budget' parameter is for max tokens. This goes beyond the schema's bare descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'analyze' with a resource 'large file' and lists supported file types (CSV, Excel, PDF, JSON). The sibling tools are unrelated, so differentiation is clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states a use case: 'Instead of pasting thousands of rows into the chat, use this...' It implies when to use but does not explicitly state when not to use or list alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
checkpoint_sessionA
Save the current AI session to TokenMizer's graph memory. Creates a checkpoint that can be resumed later with full context. Use this when: finishing a work session, before switching tasks, or when the conversation is getting long.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | Unique identifier for this session (e.g. 'my-project-auth') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses the destination ('graph memory') and the checkpoint nature, but does not mention side effects, permissions, or response behavior. Adds some context but lacks depth.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with zero redundancy. Each sentence serves a purpose: action, benefit, and usage scenarios. Well-structured and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter tool without output schema, the description covers what it does and when to use it. It could mention return/confirmation behavior, but overall it is complete enough for the tool's simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a clear example ('my-project-auth'), so the description need not add parameter details. It does not, and the baseline of 3 is appropriate since the schema already documents the parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verbs 'Save' and 'Creates a checkpoint', clearly identifies the resource ('current AI session to TokenMizer's graph memory'), and distinguishes itself from the sibling resume_session by focusing on saving vs resuming.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly lists three use cases ('finishing a work session, before switching tasks, or when the conversation is getting long'), providing clear context. However, it does not mention alternatives or when-not-to-use, though the sibling resume_session implies complementarity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_graph_statsA
See the knowledge graph stats for a session: how many tasks, decisions, files, and errors are tracked.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | Session ID to inspect |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description carries the full burden. It discloses that the tool reads stats (non-destructive) and lists the types of stats. However, it does not mention any behavioral traits like required permissions, response format, or potential side effects, which are minimal for a read operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that efficiently conveys the tool's action and output. Every word adds value, and there is no wasted content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one parameter, no output schema), the description is reasonably complete. It explains what stats are tracked, though it could elaborate on whether stats are cumulative or per-session. Overall, it provides sufficient context for an agent to understand usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds no extra meaning beyond the input schema. The schema already describes the session_id parameter with full coverage (100%), so the description's mention of 'session' is redundant. Baseline score 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the purpose: to see knowledge graph stats for a session. It specifies what stats are included (tasks, decisions, files, errors), making the tool's function precise and distinct from sibling tools like analyze_file or get_savings_stats.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implicitly indicates when to use (when needing graph stats for a session) but does not explicitly state when not to use or mention alternatives. However, the standalone purpose is clear enough for typical scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_savings_statsA
Get token savings analytics — how many tokens were saved today/this week.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, but the description implies a read-only operation via 'Get'. However, it does not explicitly disclose behavioral traits like side effects, rate limits, or authorization needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, no wasted words. All information is front-loaded and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters and no output schema, the description covers the basic functionality but lacks details on return format or units of savings. Could be more specific about the analytics provided.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are no parameters (0, so baseline 4). The description adds value by specifying the type of analytics (token savings) and time periods, which goes beyond the empty schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Get' and the resource 'token savings analytics', with specific time frames 'today/this week'. It distinguishes from siblings like get_graph_stats by focusing on token savings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives. There is no mention of prerequisites, exclusions, or context for use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resume_sessionA
Get the resume context for a previous session. Returns a compact summary of what was done, decided, and what's pending. Inject this into the system prompt when starting a new session on the same project.
| Name | Required | Description | Default |
|---|---|---|---|
| level | No | critical=~100 tokens, standard=~300 tokens, full=~600 tokens | standard |
| session_id | Yes | Session ID to resume |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral disclosure burden. It describes the output ('compact summary of what was done, decided, and what's pending') and usage recommendation, which is transparent for a read-only retrieval tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences cover purpose, content, and usage without waste. Essential information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 2 parameters and no output schema, the description fully explains its purpose, output nature, and intended usage. No gaps are apparent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds no parameter-specific details beyond what the schema already provides (e.g., level token sizes). The 'inject into system prompt' advice is helpful but not parameter-focused.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Get the resume context for a previous session' and specifies it returns a compact summary. It distinguishes itself from sibling tools like analyze_file or checkpoint_session by focusing on session resumption.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit context on when to use: 'Inject this into the system prompt when starting a new session on the same project.' It lacks explicit exclusions or alternatives, but the usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
why_decisionA
Reason over the session's decision history: why is something the current choice? Traces the supersession chain (old → new with trigger, reason, and evidence per hop) for decisions matching the query, and reports the currently active choice. Use when the user asks 'why did we pick X', 'what happened to Y', or 'what was the previous approach'.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Substring of the decision to explain (e.g. 'react', 'postgres') | |
| session_id | Yes | Session whose decision history to query |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses internal mechanics (tracing supersession chain with trigger/reason/evidence per hop) and output (active choice). However, it does not explicitly declare the tool as read-only or mention any side effects, auth needs, or rate limits. Basic transparency but lacks safety disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero wasted words. Front-loaded with primary purpose, followed by clear usage examples. Efficient communication of key information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity and no output schema, the description adequately covers what the tool does and what it returns (traced chain with details, active choice). It provides usage examples. Minor gap: lacks details on return format or pagination, but overall sufficient for agent decision-making.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for both parameters. Description rephrases the query parameter as 'substring of the decision to explain', which adds little beyond the schema's description. Session_id is not elaborated. Baseline score of 3 is appropriate as description does not significantly enhance parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly defines the tool as reasoning over decision history with specific verb 'reason' and resource 'decision history'. It explains the supersession chain tracing and active choice reporting, distinguishing it from sibling tools like analyze_file or checkpoint_session which serve different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use guidance with example user queries ('why did we pick X', 'what happened to Y', 'what was the previous approach'). Does not mention alternatives or when not to use, but the context is clear and sufficient for an agent to select this tool appropriately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v0.5.3- Changed
checkpoint_session1 field changed- removed
Input schema / properties / notesRemoved value: -{ - "description": "Optional notes about what was accomplished", - "type": "string" -}
1 tool update
v0.4.0- Added
why_decision
5 tool updates
v0.3.1- First observed
analyze_file - First observed
checkpoint_session - First observed
get_graph_stats - First observed
get_savings_stats - First observed
resume_session
TDQS
Scored across 6 tools
Each tool targets a distinct operation: session persistence, graph statistics, file analysis, savings analytics, and decision reasoning. Even the two stats tools are clearly separated by domain (knowledge graph vs token savings).
Most names follow a clear verb_noun pattern (checkpoint_session, resume_session, analyze_file, get_graph_stats, get_savings_stats), but why_decision deviates from the verb-first convention. The mixed get_ vs bare-verb prefixes are minor and don't impede comprehension.
Six tools is appropriate for a focused session-memory and token-optimization utility. Each tool has a distinct role with no redundant entries.
The core workflows of checkpointing, resuming, analyzing files, and reviewing decisions are covered. Missing session listing/deletion and explicit decision-management operations, but agents can work around these for typical use.
Maintenance
Related MCP Connectors
Persistent, portable memory for AI assistants — your private memory graph, from any MCP client.
Cloud-hosted MCP server for durable AI memory
Cross-tool persistent memory and context for AI assistants over MCP.
Persistent memory for AI agents to retain, retrieve, and recall conversation context through MCP.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceA graph-based MCP server that provides AI coding agents with persistent memory to store patterns, track complex relationships, and retrieve knowledge across sessions. It leverages graph structures to handle temporal queries and relational paths that traditional vector stores often miss.247MIT
- AlicenseNot gradedqualityAmaintenanceOpen-source MCP memory server providing persistent, cross-platform context for AI tools via a knowledge graph with encrypted storage.1 npm13AGPL 3.0
- AlicenseNot gradedqualityAmaintenanceA universal MCP server providing persistent, structured memory through a knowledge graph with graph storage, semantic vector search, and multi-hop traversal for AI agents and IDEs.1MIT
- AlicenseNot gradedqualityBmaintenanceMCP server providing persistent AI memory with four-tier retrieval (SQLite FTS5, graph, vector, LLM agent) to give AI assistants structured, long-term memory without RAG.1Apache 2.0