statecore-mcp
StateCore MCP gives coding agents auditable, long-term project memory over the Model Context Protocol.
remember— store durable project/user facts, preferences, decisions, and constraints; notes default to 500 chars, setconsolidate=truefor up to 2000 chars distilled in the background.recall— retrieve relevant memory packed into a character budget, returning the distilled digest, believed facts, recent events, and what was left out.facts— list everything currently believed about the project, grouped with fact IDs and pending distillation count.why— explain why a fact is believed by showing its source evidence and full version chain, including superseded and retired versions.forget— suppress a fact byfactKey; the record is retired, not deleted, preserving the audit chain.handoff— record where a session stopped (summary, open questions, next steps); the next session receives it at the top ofrecall, andclear=trueretires the active handoff.
StateCore
Auditable memory for coding agents and AI systems. Every fact StateCore holds carries its evidence, its version chain, and a recorded reason for every discard — so "why do you believe this, and what did you believe before?" always has an answer.
StateCore is a self-hosted, low-drift long-term memory runtime for local or BYO models. It turns memory from accumulated text into governed state: events are ingested, run through a deterministic digest pipeline, and merged into protected stable state. The LLM proposes; the pipeline decides.
Try it in 30 seconds
No server, no signup, no model key — one SQLite file over MCP:
claude mcp add statecore -- npx -y statecore-mcp # Claude Code
remember a decision in one session, ask why in the next: you get the fact, the evidence behind it, and its version history — superseded and retired facts stay on the record, marked, never deleted. And sessions hand off across vendors: handoff records where one session stopped, and the next one — Claude Code, Codex, Cursor, any MCP client on the same project — receives it at the top of recall, with every earlier stop-point still on the audit chain. Configs for Cursor, dsh, and every other MCP host: apps/mcp/README.md.
Related MCP server: recollect
Capture is easy. Trust is hard.
Most agent-memory tools compete on capturing more — hook every event, compress the transcript, inject it back. Capture is the solved half of the problem. The unsolved half is what those tools' own issue trackers are full of: memories that silently stop being written, stale decisions injected as if still current, cross-project leakage, and no way to audit or repair what the store believes. That is not a rhetorical claim — docs/prior-art-failure-modes.md cites the verified issues, by number, across five systems.
StateCore is built for that second half:
Nothing is silently lost. Every discard is logged against a fixed set of reasons; every replaced fact keeps a
supersededBychain; retired facts are marked, never deleted.Nothing is silently believed. Writes go through a deterministic pipeline with consistency gates — an LLM proposal alone cannot promote itself into stable state.
Nothing degrades silently. A failed digest carries
degraded; the budget reports what it refused; retrieval reports which embedding stages failed and derives itsmodefrom what actually ran, not from what was configured.Everything is checkable.
whyreturns a fact's evidence and full version history; a digest's selection report shows exactly what it kept and dropped.
How this compares to other memory systems, mechanism by mechanism: docs/why-auditable.md.
Features
Event store — ingest stream events and keyed documents into per-scope memory
Digest pipeline — background worker consolidates events into stable state through selection, merge, consistency checks, and retry
Protected state — goals, constraints, decisions, and todos are gated by a consistency gate; the LLM proposes, the pipeline enforces
Auditable facts — every fact carries its evidence and its supersession chain, and a fact that leaves the active set is retired rather than deleted, so "why do you believe this, and what did you believe before" stays answerable
Recorded discards — the digest logs what it dropped and why, against a fixed set of reasons; losing information is survivable, losing it silently is not
Replaceable ontology — facets come from a pack resolved per tenant and scope, so the engine stores, protects and supersedes without knowing what a facet means
Retrieval — hybrid keyword + optional pgvector semantic search over events and digests, packed into a caller-declared character budget that reports what it refused; pinned events and write-protected facts get a bounded ranking boost (never a filter), and embedding failures are itemised in
retrieval.degradedinstead of silently downgrading qualityReminders — daily reminder job surfaces follow-up items from active scopes
Benchmarks — a published LongMemEval comparison against mem0 OSS at an equal context budget, plus a built-in synthetic regression suite that guards fact retention, goal stability, decision continuity, and retrieval MRR across commits
MCP server —
statecore-mcp, a zero-deploy Model Context Protocol front end for coding agents; keyless by default, one SQLite file, no infrastructure
Quickstart
1. Install dependencies
pnpm install2. Configure environment
cp .env.example .envMinimum required variables:
PORT=3002
LOCAL_USER_TOKEN=local-dev-user
DATABASE_URL=postgresql://postgres:postgres@localhost:5434/statecore
REDIS_URL=redis://localhost:6380To enable LLM features (digest, answers):
FEATURE_LLM=true
MODEL_PROVIDER=openai-compatible
MODEL_API_KEY=<your-key>
MODEL_BASE_URL=https://api.openai.com/v1
MODEL_NAME=gpt-5-miniOn OpenAI, pick a model that accepts
reasoning_effort. The runtime turn sends it on every request —assistant-runtime.tsdefaults it tolowrather than leaving it unset — soPOST /v1/memory/runtime/turnfails against agpt-4o*model, which rejects the parameter. Digest and answers do not send it unlessMODEL_STRUCTURED_OUTPUT_REASONING_EFFORTis set, so agpt-4o*model appears to work right up until the first runtime turn. Any endpoint that accepts the parameter, or ignores unknown ones, is fine.
3. Start infrastructure
docker compose -f docker-compose.local.yml up -dThis starts Postgres (with pgvector) and Redis.
4. Prepare the database
pnpm db:generate
pnpm db:migrate
pnpm seed5. Start the services
pnpm dev:api # NestJS API on PORT (default 3002)
pnpm dev:worker # background digest + reminder workersThe API is available at http://localhost:3002 (or whatever PORT is set to).
API
Authentication
All requests require an x-user-id header. For local development, set LOCAL_USER_TOKEN=local-dev-user in .env and send:
x-user-id: local-dev-userPublic surface (/v1)
The /v1 prefix exposes the stable, public-facing subset of the API. Full OpenAPI schema:
GET /openapi.jsonInteractive Scalar UI:
http://localhost:3002/docsReference documentation: docs/api.md
Key endpoints
Method | Path | Description |
|
| Ingest a stream event or document |
|
| Retrieve grounded evidence for a query, within an optional |
|
| Trigger a State Layer digest job |
|
| Grouped memory facts for a scope |
|
| A fact's evidence and its full version chain |
|
| What a digest kept, and what it discarded and why |
|
| The active facet ontology for a scope or account |
|
| List scopes |
|
| Current stable-state snapshot ¹ |
|
| Current working-memory snapshot ¹ |
|
| Aggregated layer health ¹ |
The three audit readers in the middle are the ones that make the engine's memory
checkable rather than merely stored; docs/api.md lists the full frozen surface.
API stability: the
/v1contract is frozen and additive-only — see STABILITY.md. It currently covers 22 operations across 20 paths. The contract carries its own version in the generated OpenAPI document (info.version, currently1.8.0), which is what tells you how current a spec you are holding; it is not the release tag and not any package version.
¹ Internal read-model endpoints — registered only at /memory/..., not under /v1, and not part of the frozen /v1 contract.
Use it from your coding agent (MCP)
statecore-mcp is a separately published npm package that fronts this engine
over the Model Context Protocol — no
running server required. It runs the engine embedded (one process, one SQLite
file), keylessly by default:

npx -y statecore-mcp --data ~/.statecorePoint any MCP client at it, or run it against a full StateCore deployment via
--url for shared/multi-agent memory. Full docs, host configs, and the
keyless/keyed capability matrix: apps/mcp/README.md.
Client | Setup |
Claude Code |
|
dsh | pinned-executable overlay config included (config) |
Cursor |
|
Codex CLI, Gemini CLI, Windsurf, Zed, Cline, OpenCode, Claude Desktop, VS Code Copilot | standard MCP stdio config — |
Anything else that speaks MCP | same stdio command; HTTP via |
Team memory: one self-hosted deployment as the shared project brain for every agent your team runs — dsh sessions, Claude Code, CI — with one audit trail across all of them: docs/team-memory.md.
Architecture
apps/api NestJS HTTP server — ingestion, retrieval, runtime turns, diagnostics
apps/worker BullMQ background workers — digest, working-memory updates, reminders
apps/mcp statecore-mcp — MCP server, embedded or thin client against apps/api
packages/core Memory engine (MemoryService, DigestService, RetrieveService, AssistantSession)
packages/contracts Zod schemas for all API I/O
packages/db Prisma schema, migrations, and client
packages/prompts LLM prompt templates (digest, answer, runtime)StateCore sits between your client and your model endpoint. Events flow in, the digest pipeline consolidates them into protected state, and retrieval pulls grounded evidence back out for answers or runtime turns.
Three-layer memory model:
Fast Layer — synchronous; assembles prompt context for the current turn from recent events, working memory, and stable state
Working Memory — lightweight, quickly-updated structured memory; bridges raw recent turns and slow stable-state consolidation
State Layer — authoritative, replayable, low-drift long-term memory; updated asynchronously through the digest control pipeline
See docs/vision-and-roadmap.md for the layered model design and roadmap.
Testing and Benchmarks
Run package tests:
pnpm --filter @statecore/core test
pnpm --filter @statecore/api testRun the full latency + memory quality benchmark:
pnpm benchmarkRun the synthetic regression suite (no LLM required):
pnpm --filter @statecore/core evalThe synthetic suite is a regression guard, not a capability benchmark: every scenario scores 1.000 on the current engine, deliberately — its job is to fail when a change breaks retention, stability, or retrieval, not to rank systems. The comparison that ranks systems is LongMemEval, below.
Benchmark methodology: docs/benchmarking.md
LongMemEval
Compared against mem0 OSS on
LongMemEval at an equal context
budget — the same number of characters of memory in the answerer's prompt,
rather than the same number of retrieved items. 194 questions, gpt-5 answering,
the official gpt-4o judge (2026-08-08):
system | 4,000 tok | 16,000 tok | 64,000 tok |
StateCore | 51.0% ±7.0 | 80.9% ±5.5 | 87.6% ±4.6 |
mem0 OSS | 61.3% ±6.9 | 59.8% ±6.9 | 61.3% ±6.9 |
No memory (recency window) | 9.3% ±4.1 | 22.7% ±5.9 | 53.6% ±7.0 |
At 64k, StateCore also beats the 70.1% ±6.4 ceiling of pasting the entire corpus into the prompt with no memory layer at all. At 4k it loses to mem0 by 10 points — a real difference in kind, explained rather than closed, in the full write-up.
Numbers, caveats and what the benchmark does not measure:
docs/longmemeval.md. Harness, raw retrievals and
per-question judge verdicts:
memory-budget-bench.
Documentation
docs/start-here.md— orientation for new contributorsdocs/repo-map.md— repo structure, where code belongs, and the full doc indexdocs/philosophy.md— what the engine is for, and why auditability is the centredocs/why-auditable.md— audit mechanisms compared with other memory systems, factuallydocs/prior-art-failure-modes.md— the documented failure modes this design answers, with verified issue citationsdocs/glossary.md— facet, pack, supersession, retirement, drop logdocs/api.md— full API reference and the/v1contract rulesdocs/vision-and-roadmap.md— positioning and roadmap, with a status mapdocs/technical-overview.md— architecture internalsdocs/digest-state.md— digest state specificationdocs/protected-state-merge.md— the deterministic merge, field by fielddocs/drift-definition.md— drift definition and metricsdocs/assistant-runtime.md— assistant runtime specificationdocs/benchmarking.md— benchmark methodologydocs/longmemeval.md— LongMemEval results vs mem0 OSSdocs/evaluation-metrics.md— evaluation metrics specification
Contributing
Fork the repo and create a feature branch.
Run
pnpm lintandpnpm --filter @statecore/core testbefore opening a PR.Follow Conventional Commits.
License
MIT — see LICENSE.
Available Tools
6 toolsfactsA
List everything currently believed about this project, grouped, with fact ids, plus how many captured events are still waiting for distillation. Use to review or audit the memory.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that it returns grouped facts with ids and the count of pending distillation events, and implies a read-only operation. However, it does not explicitly state it has no side effects, nor does it describe any limitations or prerequisites. The described content adds value but leaves room for more explicit behavioral details.
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 sentence that front-loads the action ('List everything') followed by the key details (grouping, ids, pending count). It is concise, contains no filler, and every clause adds value.
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 output schema, the description adequately conveys what the user will receive: grouped facts with ids and a count of pending events. It is complete for a simple read-only enumeration tool. Minor gaps like pagination or format specifics are not critical here.
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 tool has zero parameters, so the schema provides complete coverage. Per the baseline rule for 0 parameters, a 4 is appropriate; the description need not explain parameters that do not exist, and it correctly focuses on output semantics.
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 it lists everything believed about the project, with grouping and fact ids, which is a specific verb+resource. It distinguishes itself from siblings like 'recall' by focusing on a comprehensive enumeration, though it does not explicitly name any sibling. Still, the purpose is unambiguous and actionable.
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?
It explicitly says 'Use to review or audit the memory,' providing clear context for when to invoke it. It does not mention when not to use it or alternatives, but the stated usage is sufficiently directive for an audit/review scenario.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
forgetA
Suppress a fact by factKey. The record is retired, not deleted — the audit chain is preserved.
| Name | Required | Description | Default |
|---|---|---|---|
| factKey | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It discloses the key non-obvious behavior: the record is retired rather than deleted, and the audit chain is preserved. This is valuable context beyond the mere action.
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 one concise sentence that front-loads the primary action and then adds the critical nuance about retirement versus deletion. Every word 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 single-parameter tool with no output schemahaving, the description covers the essential purpose and the most important behavioral caveat. It lacks explicit context about return values or error conditions, but the tool is simple enough that this is not a critical gap.
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 schema has no parameter descriptionscars, and the description only mentions factKey by name. It confirms that factKey identifies the fact to suppress, but adds no detail about the expected format or provenance of the key. The single-parameter simplicity keeps this at an acceptable level.
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 states a clear action ('Suppress') and a specific resource ('a fact') with the identifying key. It also clarifies the semantic distinction from deletion, which helps distinguish it from sibling tools like remember and recall.
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 implies when to use the tool: when you have a factKey and want to suppress a fact. However, it provides no explicit guidance on when not to use it or which alternative sibling tool might be more appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
handoffA
Record where this session stopped — a summary, open questions, and next steps — before ending or compacting. The next session (in this client or any other MCP client) receives it at the top of recall; each handoff supersedes the previous one on an auditable chain (why on the returned handoffId walks it). Pass clear=true to retire the active handoff instead.
| Name | Required | Description | Default |
|---|---|---|---|
| clear | No | ||
| summary | No | ||
| nextSteps | No | ||
| openQuestions | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the disclosure burden. It reveals that each handoff supersedes the previous one, that the handoffId can be walked via why for auditing, and that clear=true retires the active handoff. This gives the agent awareness of mutation and chain behavior, though it does not fully describe the return value or error cases.
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 dense sentences with no filler. The main action and payload are front-loaded, followed by chain behavior and clear mode. The phrase 'why on the returned handoffId walks it' is slightly jargon-heavy but still efficient and informative.
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 4 optional parameters, no output schema, and no annotations, the description covers when to use it, what payload to pass, how clearing works, and what happens to the next session. It lacks an explicit example and full return contract, but those are not essential for correct invocation.
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 0%, so the description must compensate. It does: 'summary, open questions, and next steps' maps to the three content parameters, and 'Pass clear=true' explains the boolean. Constraint details like maxLength and maxItems remain in the schema, which is acceptable.
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 and resource: 'Record where this session stopped' with a concrete payload (summary, open questions, next steps). This distinguishes it from sibling memory tools like remember/recall by focusing on session handoff and supersession rather than general memory storage/retrieval.
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?
It explicitly says when to use the tool: 'before ending or compacting' a session. It also explains the alternative clear mode: 'Pass clear=true to retire the active handoff instead.' It does not name sibling alternatives to avoid, but the usage context is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recallA
Retrieve project memory relevant to a query, packed into a character budget. Returns the distilled digest, believed facts, recent events, and a budget report of what was left out. Call at the start of a session or before relying on past context.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | ||
| maxChars | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description must carry behavioral disclosure. It explains the output is a distilled digest plus believed facts, recent events, and a budget report of omissions, and frames the result as packed into a character budget. It does not explicitly confirm read-only behavior, but 'Retrieve' and the absence of mutation language make the safety profile reasonably clear.
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 no filler; the action is front-loaded, the return content is listed compactly, and the usage trigger is in a short final clause. 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 simple two-parameter retrieval tool with no output schema, the description covers what it returns and when to call it. The main gaps are parameter-level detail (maxChars semantics, default behavior) and explicit read-only confirmation, but the core invocation context is present.
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 0%, so the description must add the meaning. It does so at a high level: 'query' is the relevance input and the output is 'packed into a character budget,' which maps to maxChars. However, it never names maxChars, states what happens when it is omitted, or describes how the budget size changes results, so it stops short of full compensation.
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?
States a specific verb ('Retrieve') and resource ('project memory relevant to a query') and adds the return shape. It does not explicitly differentiate from sibling tools like facts, but the general recall scope is clear enough for selection.
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 temporal guidance: call at the start of a session or before relying on past context. It does not state when not to use it or name alternatives, so it is clear context but not full routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rememberA
Store a durable fact about this project or user. Use for preferences, decisions, constraints, and anything worth knowing next session. Deterministic and audit-tracked. Notes (the default path) are capped at 500 characters; pass consolidate=true for longer conversational context, accepted up to 2000 characters and distilled in the background.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | ||
| consolidate | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It meaningfully adds that the operation is deterministic, audit-tracked, has a default 500-character cap, and that consolidate=true allows up to 2000 characters with background distillation. It does not cover conflict resolution or return behavior, but the disclosed traits go well beyond the raw schema.
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 fluff: the first states purpose, the second provides usage context, the third covers parameter behavior. The most important information is front-loaded, and every sentence contributes meaningful detail without redundancy.
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 two-parameter tool with no output schema and no annotations, the description covers the core behavior, the default vs. consolidated path, and usage context. It omits return value and error handling, which are minor for this simple store operation, so it is almost fully complete.
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 0%, so the description must compensate for both parameters. It elegantly explains that 'text' defaults to a 500-character note unless consolidate=true, which then accepts up to 2000 characters and gets distilled in the background. This adds crucial semantics about the consolidate flag that the schema alone could not convey, effectively documenting both parameters.
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?
States a specific verb and resource ('Store a durable fact') and clearly scopes the use to project/user preferences, decisions, and constraints for the next session. The purpose is instantly distinguishable from sibling tools like recall (retrieval) and forget (deletion), even without naming them.
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 guidance on what to store ('preferences, decisions, constraints, and anything worth knowing next session'), giving clear context for when to use the tool. However, it does not explicitly mention when not to use it or point to alternative siblings for retrieval or deletion, so it falls short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whyA
Explain why a fact is believed: its source evidence and the full version chain, including superseded and retired versions. Pass a factId from facts or recall.
| Name | Required | Description | Default |
|---|---|---|---|
| factId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden. It discloses the tool's output behavior (source evidence and full version chain, including superseded and retired versions), and 'Explain' strongly implies a read-only operation. However, it does not explicitly state that no state is modified or describe behavior for unknown/invalid factIds.
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 two sentences with no filler. The main purpose is front-loaded, and the usage hint about factId follows naturally. 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 low-complexity tool with one parameter and no output schema, the description covers what the tool returns and how to get the required input. Minor gaps remain: no explicit no-side-effects statement and no error behavior, but these are relatively small given the simple read/explain nature of the tool.
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 schema only provides type and minLength for factId, with no description. The tool description adds meaningful guidance by saying to pass a factId from facts or recall, giving the parameter a clear source. For a single simple string parameter, this is sufficient, though it lacks format examples or edge-case guidance.
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 ('Explain') and resource ('fact'), and spells out exactly what is returned: source evidence and the full version chain including superseded and retired versions. This clearly distinguishes it from siblings like facts or recall, which focus on retrieval rather than provenance.
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 clear context: use this tool when you need to understand why a fact is believed and what evidence/version history supports it. It also tells the agent where to obtain the required factId ('from facts or recall'), but it does not explicitly state when not to use it or name alternatives.
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.
6 tool updates
v0.6.0- First observed
facts - First observed
forget - First observed
handoff - First observed
recall - First observed
remember - First observed
why
TDQS
Scored across 6 tools
Each tool targets a distinct memory lifecycle stage: remember creates, recall/facts read (query vs full audit), forget retires, why explains provenance, and handoff manages session continuity. The only mild ambiguity is facts vs recall, but their descriptions clearly differentiate full audit from query-budgeted retrieval.
All tool names are lowercase single words and mostly imperative verbs (remember, recall, forget, handoff), so the style is consistent and readable. 'facts' and 'why' are noun/question-word deviations rather than verb forms, but they are not mixed conventions.
Six tools is well-scoped for a project-memory server: storage, retrieval, audit, forgetting, provenance, and session handoff each get one slot without redundancy. The count feels neither thin nor heavy.
The core memory lifecycle is covered: create (remember), read (recall/facts), delete (forget), provenance (why), and session handoff. The main gap is no explicit fact-update tool, though supersession/versioning is hinted at and forget+remember provides a workaround.
Maintenance
Related MCP Connectors
- memnodeOAuthdev.memnode
Persistent, inspectable memory for AI agents with lineage, correction, and a hosted MCP endpoint.
Long-term memory for AI coding agents: durable project facts, recalled by every MCP client.
Persistent memory for Claude Code, Cursor and Codex. Facts retire when they change.
Hosted MCP memory for coding agents: persistent across sessions, editable markdown, team sharing.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceLocal-first cross-agent memory for AI coding agents. Persistent, shared memory over MCP — what you tell one agent can be recalled by another — with all data stored in a single local SQLite file, no cloud and no API keys.-
- AlicenseNot gradedqualityDmaintenanceLocal, cross-agent memory for AI coding agents using a single SQLite file, enabling persistent sessions and durable facts shared across multiple MCP-compatible tools.13 npmMIT
- AlicenseAqualityBmaintenanceLocal-first, source-traceable memory for AI agents — no LLM at ingest, $0 per message, zero data egress. Gives Claude Code, Cursor, and any MCP client one shared persistent memory with semantic recall, belief revision, selective forgetting, and a provenance guard that blocks acting on stale or unconfirmed memories.2317 PyPI15MIT
- AlicenseNot gradedqualityFmaintenanceLocal-first, auditable memory for AI agents. Provides durable context for MCP hosts with SQLite storage, CLI, and MCP tools for memory management.2Apache 2.0