Skip to main content
Glama

th-memory-mcp

npm version npm downloads License: MIT Node CI Version Sync Listed on mcpservers.org

th-memory-mcp MCP server

Status: v2.3.0 — a temporal, conflict-aware, hybrid-retrieval memory engine. 16 MCP tools, 25 passing test suites. Non-destructive schema migration from v1 (all v1 data preserved). New in v2.2: lifecycle states, temporal validity, conflict/dedup resolution with USER/SESSION/PROJECT/GLOBAL scope, hybrid FTS+vector retrieval (RRF), memory graph, get_context assembly, periodic consolidation, and link_memory / merge_memory / update_memory / import_memory / extract_memories. New in v2.2.3: scope-enforced retrieval, graph scope isolation, export/import round-trip, hardened import path (realpath), strict import validation, N+1 query elimination, cold/ablation benchmark, and MEMORY_RETRIEVAL_MODE switch. New in v2.2.7: synced secret filter between Claude hook and capture-core (6-pattern redact instead of line-drop), fixed err() to return isError:true per MCP spec, fixed backup rotation (backup only when migrations pending + prune to 5 files), and added hook error logging for SessionEnd distill. New in v2.2.8: fixed scope contamination 0.75→0 (critical) and conflict false 0→1 (GLOBAL leak), fixed graph hop1 0.52→1.0 via includeGraph, and rescaled benchmark profiles to 5K/20K/100K/500K/1M (pre-commit now quick 5K + normal 20K only). New in v2.2.9: extended export to entities/users/relations, forget now removes associated links, fail-closed migration with shared ISO helper, eliminated FTS N+1, included smoke in test script, and synced viewer to rescaled profiles 5K/20K/100K/500K/1M. New in v2.3.0: CLI th-memory + highlight underline.

Requirements

  • Node.js >= 20 — the server uses Node-only APIs (the better-sqlite3 native build and import.meta.url resolution) and the MCP SDK requires a modern runtime. CI tests on Node 20.x and 22.x.

  • npm — to install dependencies and run the build/test scripts (npm install, npm run build, npm test).

  • OpenCode — the host that loads this MCP server and the auto-capture plugin. Any build supporting MCP over stdio + plugins works; the plugin runs on OpenCode's bundled Bun runtime.

  • OS: Windows / macOS / Linux — the server is cross-platform (Node). The auto-capture plugin runs wherever OpenCode's Bun runtime runs. Windows note: MEMORY_DB_PATH is easiest to set with setx; on macOS/Linux use export in your shell profile.

No external services, accounts, or API keys are required — everything lives in a single local SQLite file.

Related MCP server: MCP Vector Memory

Quick Start

Fastest path: after cloning, run npm run quickstart — it builds, wires opencode.json, deploys the plugin, and sets MEMORY_DB_PATH for you in one command. The steps below show exactly what it does (use them if you prefer manual control).

Install via npm (alternative): install the server globally with npm install -g th-memory-mcp (or run it on demand with npx th-memory-mcp), then point the mcp command in opencode.json to th-memory-mcp instead of the built dist/index.js. The auto-capture plugin still comes from this repo (copy src/plugin/learning-capture.ts as described in step 4 below).

Note: no longer published to GitHub Packages — install from npmjs with npm i -g th-memory-mcp.

# 1. Clone and build
git clone https://github.com/worakorn-prince/th-memory-mcp.git
cd th-memory-mcp
npm install
npm run build

# 2. Share one DB between the server and the plugin
#    Windows (PowerShell):
setx MEMORY_DB_PATH "$PWD/data/memory.db"
#    macOS / Linux (add to your shell profile, e.g. ~/.zshrc):
# export MEMORY_DB_PATH="$PWD/data/memory.db"
  1. Merge this into your ~/.config/opencode/opencode.json (replace <REPO> with the absolute clone path):

{
  "instructions": ["<REPO>/AGENTS.memory.example.md"],
  "mcp": {
    "memory": {
      "type": "local",
      "command": ["node", "<REPO>/dist/index.js"],
      "enabled": true,
      "environment": { "MEMORY_DB_PATH": "<REPO>/data/memory.db" }
    }
  }
}
  1. (Optional) Auto-capture: copy src/plugin/learning-capture.ts~/.config/opencode/plugins/

  2. Restart OpenCode

  3. Try it: "Remember that I prefer pnpm" → new session → "What package manager do I prefer?"

Architecture

OpenCode ──┬─ Plugin learning-capture (Bun)  ── auto-captures prompts/tool/error into DB
            │                                   └─ injects profile back into context on compaction
             └─ MCP th-memory-mcp (Node.js stdio)  ── 16 tools read/write the same SQLite DB
                                                      ▲
                               Global instructions (memory-protocol.md) teach the AI to use the tools

See ARCHITECTURE_v2.md for the full architecture spec.

Why th-memory-mcp?

LLMs don't remember you between sessions — every new chat starts blank. th-memory-mcp gives your AI a private, local long-term memory:

  • Context-based learning, not fine-tuning — it captures your preferences, corrections, and habits, then recalls them into context next time. Same mechanism as the memory features of leading AI products, without sending any data off your machine.

  • 100% local & private — a single SQLite file, no cloud, no external API. Secrets are filtered before anything is stored.

  • Low overhead — each tool call is capped (latency < 10 ms, bounded output size) and the AI only queries memory when it's actually useful, so it never bloats your context.

  • Resilient — every tool degrades gracefully; if the DB is unavailable the AI keeps working instead of crashing.

  • Open & extensible — MIT licensed, 16 documented tools, a rule-based distill, and an auto-capture plugin you can adapt.

Works with other harnesses

th-memory-mcp is a standard MCP server, so the 9 tools run anywhere MCP-over-stdio is supported. Full auto-capture (background prompt/tool/error capture + profile injection) needs a hook runtime — OpenCode has it built in; Claude Code gets it via our hooks bridge; Codex and Cursor use the tools manually (no hook runtime yet).

Feature

OpenCode

Claude Code

Qwen Code

Codex

Cursor

16 MCP tools

Auto-capture (background)

✅ plugin

hooks

⚠️ adapter

❌ manual

❌ Rules

Profile injection

✅ compaction

✅ UserPromptSubmit

get_profile

get_profile

get_profile

Lexical fuzzy matching

✅ (v2.0)

✅ (v2.0)

✅ (v2.0)

✅ (v2.0)

✅ (v2.0)

  • Claude Code: see CLAUDE_CODE_HOOKS.md — drop-in hooks replicate the OpenCode plugin (capture + profile injection on UserPromptSubmit/PreCompact, rule-based distill on SessionEnd).

  • Qwen Code: see QWEN_SETUP.md — MCP works fully; hooks use the Gemini-CLI schema so auto-capture needs a small adapter.

  • Codex: see CODEX_SETUP.md

  • Cursor: see CURSOR_SETUP.md

All harnesses share one SQLite file via MEMORY_DB_PATH, so memory captured anywhere is readable everywhere.

Highlights

  • Structured memory — preferences with confidence scoring plus dedicated lesson records (situation → mistake → correction) for capturing corrections, not just flat facts.

  • Lifecycle & temporal — every memory has a lifecycle state (active/stale/superseded/archived), confidence/importance/salience scoring, per-type decay, and validity intervals so the AI can reason about point-in-time truth and supersession chains.

  • Conflict-aware — duplicate detection, contradiction detection, and update/supersession resolution preserve both sides of ambiguous evidence instead of silently overwriting.

  • Hybrid retrievalget_context blends FTS5 keyword search with a dependency-free lexical fuzzy matching (hashed n-gram similarity, 512-dim FNV-1a) (RRF fusion + scoring), then assembles a token-budgeted context with optional memory-graph expansion.

  • Consolidation — periodic clustering of similar memories into derived memories with full provenance (derived_from links).

  • First-class Thai / i18n — Thai-aware tokenization in distill; the AI accepts Thai and English interchangeably.

  • Private by default — a single local SQLite file, no cloud, no API keys, with secret lines (api_key=, password:, token) filtered before storage.

  • Cross-harness — runs on OpenCode, Claude Code, Codex, and Cursor sharing one DB; auto-capture + profile injection via OpenCode plugin or Claude hooks.

  • Lightweight & resilient — Node + better-sqlite3, no extra native extensions; every tool degrades gracefully so the AI keeps working if the DB is unavailable.

Scripts

Command

Description

npm run build

compile TypeScript → dist/

npm start

run the MCP server (stdio) from dist/index.js

npm run distill

rule-based distill: interactions → profile sections + prune old data (env RETENTION_DAYS default 30)

npm test

full suite: capture, distill, lifecycle, temporal, conflict, retrieval, graph, context, consolidation, benchmark, security, tools_v21, smoke, e2e_transport, retrieval_benchmark, recall_regression, scope, profile, entity_extraction, conflict_benchmark, security_regression, export_import_roundtrip

node test/capture.test.mjs

test capture-core (filter secrets, dedupe, truncate, insert SQL)

node test/distill.test.mjs

test distill-core (Thai tokenize, stats, profile sections, prune)

node test/lifecycle.test.mjs

test lifecycle engine (states, decay, supersession)

node test/temporal.test.mjs

test temporal model (validity, historical retrieval)

node test/conflict.test.mjs

test conflict & dedup resolution

node test/retrieval.test.mjs

test hybrid FTS+vector+RRF retrieval

node test/graph.test.mjs

test memory graph (entities, relations, traversal)

node test/context.test.mjs

test context assembly + token budgeting

node test/consolidation.test.mjs

test clustering + derived memories

node test/benchmark.test.mjs

latency benchmark over 300 memories

node test/security.test.mjs

injection / safety checks

node test/smoke.mjs

end-to-end smoke test over JSON-RPC (16 tools)

Tools (16)

Tool

Description

remember

upsert preference (category+key) — re-saving the same key increases confidence by 0.1 (cap 1.0)

recall

search preferences + lessons (FTS5) + recent matching interactions. Use before starting a new task

get_profile

user profile overview: profile sections + top preferences + 5 most recent lessons

save_lesson

record a lesson learned from a correction (situation / mistake / correction)

search_history

search past user prompts by keyword (200-char snippets per row)

forget

delete one memory row (preference/lesson/interaction) by id (+type prevents cross-table id clash)

memory_stats

memory statistics: counts by kind, DB size, oldest/newest interaction, profile sections

get_recent_interactions

list recent raw interactions (filter by kind) — feedstock for Smart Distill

export_memory

export memory to JSON under data/exports/ only (filename auto-sanitized)

get_context

assemble relevant memories for the current task via hybrid retrieval (+ optional graph expansion) with token budgeting

consolidate

cluster similar memories via embedding similarity; optionally create derived/consolidated memories linked via derived_from

link_memory

create a typed relationship between two memories in the graph (supports/contradicts/supersedes/derived_from/related_to/caused_by/depends_on)

merge_memory

merge a duplicate/near-duplicate into a canonical memory (source becomes superseded, provenance in metadata.merged_from)

update_memory

update mutable fields in place, or create a superseding memory when content changes (set supersede=false to edit in place)

import_memory

import memories from JSON (validates type, dedupes against existing, never overwrites blindly); dry-run by default, apply=true to insert

extract_memories

scan recent captured interactions for memory-intent phrases and propose memory candidates (deterministic, no LLM); dry-run by default, apply=true to create (source=captured)

CLI (th-memory)

Two binaries ship in package.json (bin):

Binary

Entry

Purpose

th-memory-mcp

dist/index.js

MCP server (stdio) — the 16 tools above

th-memory

dist/cli.js

local memory CLI (zero-dep, shares the same DB via MEMORY_DB_PATH)

Usage: th-memory [--db <path>] [--json] [--plain] <command> [options] — per-command help via th-memory <command> --help.

Global flags (every command):

Flag

Effect

--db <path>

use this SQLite file (sets MEMORY_DB_PATH)

--json

print JSON {ok,data} instead of plain text

--plain / --no-color

disable colors

-h, --help

show help (global or per-command)

-V, --version

print version

Commands:

Command

Usage

remember

remember --category <c> --key <k> --value <v|-> — save a preference (--value - reads from stdin)

recall

recall <topic> [--limit <n>] [--highlight] — search memory

forget

forget <id> [--type <t>] — delete by id (t: memory|preference|lesson|interaction)

export

export [--include-interactions] [--filename <n>] — export to data/exports/*.json

import

import (--file <p>|--json <s>) [--apply] [--user-id <id>] — import backup (dry-run by default)

stats

stats — memory statistics

profile

profile — distilled user profile

history

history [--query <q>] [--limit <n>] — search past prompts (no query = recent prompts)

recent

recent [--limit <n>] [--kind <k>] — recent interactions (k: prompt|tool_call|error)

highlight

highlight [text...] -q <topic> [--limit <n>] — highlight topic matches (empty text = stdin pipe)

Highlight behavior (highlight command and recall --highlight): matches are wrapped with an underline (ESC[4mESC[24m) when stdout is a TTY with colors enabled; when piped, with --json, or with --plain/--no-color, matches are wrapped with [mem][/mem] markers instead.

Examples:

th-memory remember --category coding_pref --key package_manager --value pnpm
th-memory recall pnpm --limit 5
th-memory recall pnpm --highlight
echo "I prefer pnpm for installs" | th-memory highlight -q pnpm

Note: --value - reads the value from stdin (e.g. echo -n "pnpm" | th-memory remember --category coding_pref --key package_manager --value -).

Install with OpenCode

  1. Merge the mcp section from opencode.example.json into your opencode.json (global or project-level)

    • Important: set MEMORY_DB_PATH to the SAME database file for both the server and the plugin (the example uses <ABSOLUTE_PATH>/th-memory-mcp/data/memory.db), otherwise the auto-capture plugin writes to a different DB than the one the AI reads

    • How to set it (pick one):

      • define it in the mcp environment (see example) — covers the MCP server only

      • or set it as a system/user-level environment variable (e.g. setx MEMORY_DB_PATH "D:/path/to/memory.db" on Windows) — covers both server and plugin, since the plugin runs in the same process as OpenCode

  2. Attach the global memory rules — add to opencode.json:

    "instructions": ["C:/Users/<user>/.config/opencode/memory-protocol.md"]

    (example rule content is in AGENTS.memory.example.md — can be attached at project level instead)

  3. (Optional) Deploy the auto-capture plugin: copy src/plugin/learning-capture.ts~/.config/opencode/plugins/learning-capture.ts

  4. Restart OpenCode (config loads at startup only)

  5. Test: "Remember that I prefer pnpm" → open a new session and ask back

Daily usage

The AI accepts both Thai and English interchangeably — you can switch languages at any time without warning.

Example command

Tool / effect

"Remember that..."

remember — save a preference

"Summarize memory" / "distill memory"

Smart Distill — AI reads get_recent_interactions, finds patterns, and saves insights itself

"How is my memory?" / "memory status"

memory_stats

"Export memory" / "backup memory"

export_memory

"Search history..."

search_history

"Forget..."

forget

Long-term care: run npm run distill occasionally to summarize stats and prune interactions older than 30 days.

data/ structure

data/
├── memory.db          # SQLite (WAL mode) — main DB (+ .db-wal, .db-shm)
└── exports/           # JSON files from export_memory (writeable only in this dir)
  • DB path can be overridden via the MEMORY_DB_PATH env var

  • everything in data/ is git-ignored

Benchmark — internal self-reported (not third-party)

⚠️ Internal self-reported benchmark — not third-party benchmark

  • internal small-N: 180 records/30 topics (B.retrieval: 30 topics × 5 relevant + 30 distractors = 180; full run also uses small-N storage/temporal/context subsets)

  • single-machine self-run: single developer machine, single OS/Node/better-sqlite3 build — not cross-machine, not independently verified

  • not third-party benchmark: self-reported, not independently verified; do not compare as if from an external evaluator

  • Dataset and harness are in repro/ (commitable) and benchmark/ (full framework, see TH_MEMORY_MCP_BENCHMARK_SPEC.md and benchmark/README.md).

Two modes

Mode

Command

Data

Suites

Use case

Normal

npm run benchmark

180 records / 30 topics

retrieval

quick check (<5s)

Heavy

npm run benchmark:heavy

600 records / 100 topics + 2k scale

all (storage/retrieval/temporal/context/performance/scalability/cold/ablation)

stress / regression

Reproduce:

npm run build
# Normal — quick
npm run benchmark
npm run benchmark -- --k 10
npm run benchmark -- --out repro/results

# Heavy — full framework, more data
npm run benchmark:heavy
# or custom:
node benchmark/run.mjs --suite all --topics 100 --distractors 100 --scale 2000 --out benchmark/results

Viewer — compare last 3 versions (table + charts)

npm run benchmark:viewer
# or: npx serve . -l 3000
# open http://localhost:3000/benchmark/viewer/  or  http://localhost:3000/result/viewer.html

The viewer loads benchmark/results/history.jsonl, groups by version, takes the latest run of the 3 most recent versions (e.g. 2.2.6 / 2.2.7 / 2.2.8) and shows a highlighted table (1 row per version) + bar charts for Recall@5 / MRR / NDCG@5 and Latency p95. Results are also saved per version in result/v*_benchmark_result.md and benchmark/results/versions/<ver>/.

Last internal run (v2.2.8, warm, normal profile, a2dcbce — not third-party): Recall@5=0.9060, Precision@5=0.9060, MRR=1, NDCG@5=0.9347 over 100 topics/600 records. See result/v2.2.8_benchmark_result.md and repro/README.md for details and caveats (internal, single-machine self-run).

Known Limitations

  • No encryption at rest (plaintext-at-rest)data/memory.db (WAL mode, better-sqlite3) is a plain, unencrypted SQLite file. 100% local & private means no cloud or network exfiltration — it does not mean encrypted at rest. Anyone with filesystem access (shared machine, backup, malware, stolen device) can read preferences/lessons/interactions in plaintext. For sensitive data, use OS-level full-disk encryption (BitLocker / FileVault / LUKS) or an opt-in SQLCipher build (requires native rebuild and key management). No SQLCipher/in-code encryption is applied by default and src/db/index.ts documents this explicitly.

  • Single-user local process — no auth layer (Batch B-3)userId / sessionId / projectId are caller-supplied strings with no authentication or authorization check inside the server. Scope isolation (retrieval, get_context, graph traversal/expansion, consolidate, link_memory, merge_memory) is enforced only against the values the caller sends, so a caller can read or write any scope by passing a different id. This is suitable for a single-user local process (one operator, local data/memory.db). Do not share one server/DB across mutually-untrusted users without an auth layer in front that authenticates each caller and forces the correct userId (and allowed projectId / sessionId). No new auth system is built into the server by design — that layer belongs in front of it.

License

MIT © 2026 worakorn-prince

This project is licensed under the MIT License — see the LICENSE file for the full text.

Available Tools

16 tools
consolidateConsolidate memoriesB

Cluster similar memories via embedding similarity and optionally create derived/consolidated memories linked via 'derived_from'. Use during periodic consolidation.

ParametersJSON Schema
NameRequiredDescriptionDefault
deriveNoCreate a derived memory for each cluster
userIdNoScope to a user (USER scope)
projectIdNoScope to a project
sessionIdNoScope to a session (SESSION scope)
thresholdNoCosine similarity threshold for clustering (default 0.7)
minClusterSizeNoMinimum members to report a cluster (default 2)

TDQS

B3.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses the clustering mechanism and optional derived creation, but does not state whether original memories are modified, whether the operation is reversible, what side effects occur (e.g., deleting clusters), or any permission requirements. The lack of such context leaves the agent guessing about the tool's impact.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no redundancy. The core purpose is front-loaded, and the usage hint is appended. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool performs clustering and optional derived memory creation, but the description lacks details on return values (no output schema), impact on existing memories, threshold behavior, and what 'consolidation' entails. An agent would need more context to call this correctly and understand its effects.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all six parameters are already documented in the schema. The description adds a small amount of context about 'derived_from' linking but does not clarify parameter interactions or defaults beyond what the schema provides. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action (cluster similar memories via embedding similarity) and a resource (memories), with an optional derived-memory creation linked via 'derived_from'. This clearly distinguishes it from sibling memory tools like merge_memory or link_memory by focusing on clustering and derived creation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a timing hint ('Use during periodic consolidation') but does not specify when to avoid this tool or how it compares to alternatives like merge_memory or link_memory. The guidance is minimal and lacks exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

export_memoryExport memory to JSONA

Export preferences, lessons, profile (and optionally raw interactions) to a JSON file under data/exports/. Only writes inside that directory. Returns the file path, size in bytes and a JSON preview.

ParametersJSON Schema
NameRequiredDescriptionDefault
filenameNoOutput file name inside data/exports/ (only A-Z a-z 0-9 . _ - allowed, must end with .json). Defaults to memory-export-YYYYMMDD-HHmmss.json
includeInteractionsNoInclude raw interaction rows in the export (file gets bigger)

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the burden of exposing behavior. It discloses an important safety constraint ('Only writes inside that directory') and states what the tool returns (file path, size, JSON preview). It does not mention overwrite behavior or permissions, but it covers the most material side effect for an export tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The first sentence front-loads the core action and target location; the second adds the safety guard and return-value summary. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given there is no output schema, the description compensates by naming return values (file path, size, JSON preview). Combined with full parameter documentation in the schema and the directory-restriction detail, the agent has enough context to call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema already documents both filename and includeInteractions. The description adds only the phrase 'optionally raw interactions,' which restates the includeInteractions parameter rather than adding new meaning. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description identifies a specific action ('Export'), a concrete resource (preferences, lessons, profile, optionally raw interactions), and a target destination (JSON file under data/exports/). This clearly distinguishes it from sibling tools like import_memory or recall, making its purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage — you would call this when you want a JSON export of memory data — but it does not explicitly state when to prefer this tool over alternatives like import_memory or get_recent_interactions. It gives clear context but no exclusions or alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extract_memoriesExtract memories from interactionsA

Scan recent captured interactions for memory-intent phrases and propose memory candidates (deterministic, no LLM). Dry-run by default; pass apply=true to create them (source=captured).

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNoInteraction kind to scan (default prompt)
applyNoCreate the proposed memories (default false = propose only)
limitNoMax recent interactions to scan (default 50)
userIdNoScope extracted memories to a user (USER scope)

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations at all, the description carries the full burden and does it well: it explicitly discloses deterministic behavior, no LLM involvement, dry-run default, and the mutation path when apply=true. This gives an agent a reliable model of side effects before calling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two focused sentences front-load the core purpose and then give the key behavioral switch. Every clause earns its place; no filler or redundant restating of the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The definition is sufficient for correct invocation: purpose, defaults, mutation flag, and provenance are all covered, and the schema documents parameters. It would be slightly stronger if it described the shape of the returned memory candidates, since there is no output schema, but this is a minor gap for a proposal tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents all four parameters. The description mainly restates the apply default and adds source=captured context, which is useful but does not add substantive meaning beyond the schema's own descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource: 'Scan recent captured interactions ... propose memory candidates'. It also differentiates from memory-write/recall siblings by emphasizing this is a deterministic scanning/proposal step, not direct storage or retrieval.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly signals the intended workflow: run in dry-run to propose candidates, pass apply=true to persist with source=captured. It does not name sibling alternatives or exclusion conditions, but the use case is clear from the context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

forgetForget a memory entryA

Delete one memory row (preference, lesson or interaction) by id and sync the search index. Pass type when you know it (ids from remember are preference ids, from save_lesson are lesson ids).

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNoWhich table the id belongs to. Recommended whenever known, because numeric ids can coincide across tables.
target_idYesRow id to delete (id returned by remember/save_lesson)

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must carry the full behavioral burden. It usefully discloses that the operation destroys a row and has a side effect ('sync the search index'), but says nothing about irreversibility, required permissions, or behavior when the id does not exist.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly written sentences with zero filler, and the core delete semantics and side effect are front-loaded before the optional-parameter advice.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter delete tool with no output schema, the description covers purpose, the key side effect, and parameter sourcing. It could add error/not-found behavior, but nothing essential for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and already explains why type matters across tables, but the description adds genuinely new mapping information: 'ids from remember are preference ids, from save_lesson are lesson ids'. That source-to-type mapping is not derivable from the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Delete one memory row ... by id') and names the entity types it can target, which clearly separates it from read-side siblings like recall and update_memory. It stops short of naming which sibling to use when the goal is modification instead of deletion, so it does not reach full sibling routing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives conditional guidance for the optional parameter ('Pass type when you know it') and explains where the ids come from. It never states when to prefer forget over update_memory or merge_memory, so the when-to-use-this-tool question is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_contextGet assembled contextA

Assemble relevant memories for the current task via hybrid retrieval (+ optional memory-graph expansion), with token budgeting. Use to load memory into context before a task.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoNumber of seed memories (default 10)
queryNoOptional focus query to seed hybrid retrieval
userIdNoScope context to a user (USER scope)
maxTokensNoToken budget for assembled context (default 2000)
projectIdNoScope context to a project
sessionIdNo
includeGraphNoExpand seeds with memory-graph neighbors
includeHistoryNoInclude superseded/archived memories

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It discloses the use of hybrid retrieval, optional graph expansion, and token budgeting, but does not clarify read-only behavior, return format, or what happens when the token budget is exceeded.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two dense sentences with no filler: the core mechanism is front-loaded, followed by a usage cue. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 8 parameters, no annotations, and no output schema, the description gives a good high-level purpose but omits important operational details: what the assembled context looks like, how scoping params (userId/projectId/sessionId) interact, and how it differs from recall/search_history. The schema covers param semantics but not these behaviors.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 88%, so the schema already documents most parameters. The description adds little beyond alluding to query via 'hybrid retrieval' and maxTokens via 'token budgeting'; it does not explain parameter interactions or the effect of includeGraph/includeHistory.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (assemble), resource (relevant memories), and method (hybrid retrieval with optional memory-graph expansion and token budgeting). It clearly identifies the tool's purpose beyond the title, though it does not explicitly distinguish it from sibling retrieval tools like recall or search_history.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides an explicit usage cue: 'Use to load memory into context before a task.' This gives clear when-to-use guidance. However, it does not mention alternatives or state when not to use this tool, leaving some sibling ambiguity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_profileGet user profileA

Get the distilled user profile: profile sections, top preferences by confidence (max 15), and the 5 most recent lessons.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral transparency burden. It usefully discloses output composition and limits (max 15 preferences, 5 most recent lessons) and frames the result as 'distilled', indicating it is not the full raw profile. It does not explicitly state side-effect freedom, but 'Get' and the summary-style output strongly imply 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that leads with the verb and resource, then packs the distinguishing output details efficiently. There is no filler or unnecessary repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given zero parameters and no output schema, the description adequately covers the tool's input and expected return shape. Terms like 'profile sections' and 'lessons' could be slightly more explicit, but the core information an agent needs to call and understand the result is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline of 4 applies. There is no parameter meaning for the description to add beyond what an empty schema already communicates.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Get the distilled user profile'. It goes beyond a generic getter by enumerating the exact components returned (profile sections, top preferences by confidence capped at 15, and the 5 most recent lessons), which helps distinguish it from sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to choose get_profile over related siblings like get_context, get_recent_interactions, or memory_stats. The intended use is only implied by the name and output description, with no exclusions or alternatives mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_recent_interactionsRecent interactionsA

List recently captured raw interactions (newest first) as [id] ts [kind] content lines. Optionally filter by kind. Use for auditing history or before distilling memory.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNoFilter by kind (prompt / tool_call / error)
limitNoMax rows (default 20, max 100)

TDQS

A4.2/5.0
Behavior4/5

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 key behavioral traits: newest-first ordering, raw interaction scope, and the line format [id] ts [kind] content. It does not mention edge cases like empty results or pagination, but these are minor for a read-only list tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no redundancy. The action, output format, filtering option, and use case are each covered efficiently, and the most important scoping information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a lightweight read-only tool with optional params and no output schema, the description adequately explains the return format, ordering, and purpose. The limit parameter is fully covered by the schema, leaving no critical gap, though the description could briefly note that results are capped.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides 100% coverage for both parameters, including enums, defaults, and limits. The description adds only the notion of optional kind filtering, which is already present in the schema, so no significant extra meaning is provided.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description states the specific verb 'List', the resource 'recently captured raw interactions', ordering ('newest first'), and the exact output line format. This distinguishes it clearly from memory-management siblings like remember, recall, and consolidate.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'Use for auditing history or before distilling memory' gives clear context for when the tool is appropriate. It does not name alternative tools or state explicit exclusions, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

import_memoryImport memoriesA

Import memories from a JSON array or a .json file inside data/exports/. Validates type, dedupes against existing memories, and never overwrites active memory blindly. Dry-run by default; pass apply=true to insert.

ParametersJSON Schema
NameRequiredDescriptionDefault
fileNoPath to a .json export file (must be inside data/exports/)
jsonNoInline JSON: an array of memory objects, or { memories: [...] }
applyNoActually insert memories (default false = dry run, just report)
userIdNoScope imported memories to a user (USER scope)

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the behavioral burden. It discloses several important behaviors: validation, deduplication, refusal to blindly overwrite active memory, and dry-run-by-default safety. It does not describe return format or failure modes, but the core safety-relevant traits are clearly conveyed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with no filler. The most important scoping information (source format) appears first, followed by safety guarantees and the activation flag. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no annotations and no output schema, the description covers source, validation, dedupe, overwrite policy, and dry-run default. It omits specifics about the returned report and error handling, but the essential context for safe invocation is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds little beyond the schema: it restates the file-location constraint and the dry-run/apply behavior already present in the parameter descriptions. It does not add new semantic detail for userId or JSON structure beyond what the schema gives.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Import memories from a JSON array or a .json file inside data/exports/.' It clearly distinguishes the tool from siblings like export_memory and merge_memory by framing it as the import path for external memory data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives operational guidance ('Dry-run by default; pass apply=true to insert') but does not explicitly say when to choose this tool over alternatives such as merge_memory or update_memory. Context implies import is for bulk ingestion, but no exclusions or alternative routing are stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

memory_statsMemory statisticsA

Summarize memory usage: interaction counts by kind, preference/lesson totals, DB file size, oldest/newest interaction timestamps, and profile sections.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the transparency burden. The verb 'Summarize' clearly implies a non-mutating read-style operation, but the description does not explicitly state that it makes no changes, nor does it describe any other behavioral details like cost or freshness.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that leads with the core action and then enumerates the exact delivered statistics. Every word adds useful information, with no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description serves as the sole source of return-value expectations, and it enumerates counts, totals, file size, timestamps, and profile sections. Some terms like 'profile sections' remain somewhat vague, but for a simple zero-parameter stats tool this is reasonably complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so there is no parameter semantics to clarify. The schema coverage is trivially 100%, and the description reasonably focuses on the output content instead.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Summarize') and identifies a clear resource (memory usage) with a detailed list of metrics included in the output. It is distinct from sibling tools in content, though it does not explicitly contrast with them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this tool is for retrieving high-level memory statistics and summaries rather than detailed records or management actions. However, it provides no explicit when-to-use or when-not-to-use guidance, nor does it name alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

merge_memoryMerge memoriesA

Merge a duplicate/near-duplicate memory into a canonical one. The source becomes superseded and provenance is recorded in metadata.merged_from.

ParametersJSON Schema
NameRequiredDescriptionDefault
sourceIdYesMemory to merge away (becomes superseded)
targetIdYesCanonical memory to keep (becomes active)

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

There are no annotations, so the description carries the full burden. It clearly discloses the key side effect: the source becomes superseded and provenance is recorded in metadata.merged_from. It does not mention reversibility or permissions, but the most important behavioral outcome for an agent to know is explicitly stated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single well-formed sentence with no fluff. It front-loads the main action and then states the two important behavioral results (source supercoded, provenance recorded). Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter merge tool with no annotations and no output schema, the description gives enough to call it correctly: what it does, which parameter plays which role, and the expected side effects. It could add nuances like whether the operation is reversible, but nothing essential is missing for a typical invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both sourceId and targetId clearly. The description adds context about the canonical relationship but does not add detailed parameter-level semantics beyond what the schema provides. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Merge'), a clear resource ('memory'), and a precise scope ('duplicate/near-duplicate memory into a canonical one'). It distinguishes itself from sibling tools like forget, update_memory, and consolidate by clarifying that this operation is about canonicalization of near-duplicates.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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 a memory is a duplicate or near-duplicate of another canonical memory. It does not explicitly name alternatives or give when-not conditions, so it falls just short of a 5, but the trigger condition is clear and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

recallRecall memoryA

Search preferences + lessons via full-text index, plus recent matching interactions. Use before starting a new task.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax preference/lesson matches (default 8)
topicYesTopic to recall from memory

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the behavioral disclosure burden. It does disclose that the tool searches a full-text index and returns recent matching interactions, but it does not state whether the operation is read-only, how results are ranked, or whether recent interactions are subject to the limit parameter. This is adequate for a search tool but leaves some behavioral details implicit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The core search scope is front-loaded, and the usage guidance is immediately actionable. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

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, the description covers the key elements: what is searched, the retrieval scope, and when to use it. It does not describe the exact return structure, but it gives enough context for an agent to invoke recall correctly before starting a task.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both 'topic' and 'limit'. The description adds minimal semantic value beyond the schema, only clarifying that the search targets preferences and lessons. Baseline 3 is appropriate given full schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Search') and resource ('preferences + lessons via full-text index, plus recent matching interactions'), which clearly identifies what the tool does. It is specific enough to distinguish recall from siblings like search_history or get_recent_interactions, 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.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit guidance on when to use the tool: 'Use before starting a new task.' It does not mention alternatives or exclusions, but the timing guidance is clear and actionable for an agent deciding whether to call it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

rememberRemember preferenceA

Save or update a user preference (category+key upsert). Re-saving the same key increases confidence by 0.1 (cap 1.0). Returns the row id for forget().

ParametersJSON Schema
NameRequiredDescriptionDefault
keyYesShort stable key, e.g. package_manager
valueYesThe preference value
categoryYesPreference category

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description fully carries the behavioral burden. It discloses the upsert semantics, the confidence increment on re-saving the same key, the 1.0 cap, and the return value (row id) needed by forget(). This is unusually transparent for a write operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight, front-loaded sentences with no filler. Every sentence adds distinct value: what the tool does, how repeat calls behave, and what the caller receives.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple 3-parameter tool with no output schema, the description covers the action, the uniqueness semantics, the confidence side effect, and the return contract. Nothing essential is missing for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds meaningful extra semantics by explaining that category+key together form the identity for the upsert and that re-saving the same key affects confidence, which is not captured in the schema property descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear action: 'Save or update a user preference' and specifies the uniqueness mechanism as 'category+key upsert'. This differentiates it from generic memory tools like update_memory and the recall/search siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The intended use case is implied: call this when you need to persist or update a user preference. However, it does not explicitly state when to prefer this over siblings like update_memory, save_lesson, or link_memory, nor does it describe exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

save_lessonSave lessonA

Record a lesson learned from a correction: what situation, what mistake, what is the correct way. Call immediately after the user corrects your work.

ParametersJSON Schema
NameRequiredDescriptionDefault
mistakeYesWhat was done wrong
situationYesThe original situation/context
correctionYesThe correct approach

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden, and it does supply useful behavioral context: the operation is a write ('Record') and carries a timing constraint (only after a correction). It does not disclose persistence semantics — whether the lesson is stored permanently, surfaced by recall or search_history, or deduplicated on repeated saves — which an agent would need to anticipate downstream effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, both purposeful: the first defines what the record captures, the second states when to invoke the tool. No wasted words, and the most operationally important guidance ('immediately after the user corrects your work') is prominent.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with three simple string params, full schema documentation, and no output schema, the description covers the essentials: what to record and when to call it. The only gap is explicit boundary-setting against the closely related write-siblings (remember, extract_memories, update_memory), which is implied by the correction-specific language but never stated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all three parameters, setting the baseline at 3. The prose ('what situation, what mistake, what is the correct way') merely restates the parameter meanings rather than adding format, examples, or edge-case nuance, so the description adds marginal value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Record a lesson learned from a correction') and enumerates the three captured elements ('what situation, what mistake, what is the correct way'), which map directly to the required schema parameters. This correction-specific framing clearly distinguishes it from generic memory siblings 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.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Call immediately after the user corrects your work' provides an explicit, unambiguous trigger for invocation. However, it does not name alternatives (e.g., extract_memories or remember) or state when not to use this tool, so it stops 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.

search_historySearch prompt historyA

Search past user prompts (kind='prompt') by keyword. Returns timestamped snippets truncated to 200 chars each.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax results (default 10)
queryYesText to search in past prompts

TDQS

A4/5.0
Behavior4/5

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 filtered scope (kind='promp'), that results are timestamped, and that snippets are truncated to 200 characters. This exceeds a bare 'Search history' statement, though it stops short of noting ordering, case sensitivity, or lack of side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The entire description is two efficient clauses that each add value: the first states the action and scope, and the second clarifies the return format. It is front-loaded and contains no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With only two parameters, full schema coverage, and no output schema, the description is complete enough for correct invocation. It explains what comes back (timestamped snippets truncated to 200 chars), and the schema covers input constraints. Missing details like ordering are minor for this simple search use case.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds the notion of keyword search but does not elaborate on the limit parameter or its interaction with results; the schema already documents query and limit adequately.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Search'), identifies the exact resource ('past user prompts'), and adds a distinguishing technical detail (kind='prompt'). It also describes the result shape (timestamped snippets truncated to 200 chars), making it easy to tell apart from broader memory-retrieval siblings like recall or get_recent_interactions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The scope is clear—use this to search past user prompts by keyword—but it is stated as a capability rather than explicit routing guidance. No when-not conditions or alternative tools are named, so an agent must infer when this should be chosen over sibling retrieval tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_memoryUpdate a memoryA

Update mutable fields (summary/importance/confidence/valid_from/valid_until/metadata) in place. If content changes, a superseding memory is created by default (set supersede=false to edit in place).

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesMemory id to update
contentNoNew content. When provided, a superseding memory is created (supersede=true) unless supersede=false.
summaryNoNew summary
metadataNoNew metadata object (replaces)
supersedeNoIf content changes, create a superseding memory instead of editing in place (default true)
validFromNoISO timestamp or null to clear
confidenceNo
importanceNo
validUntilNoISO timestamp or null to clear

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does disclose the single most important non-obvious trait: changing content creates a superseding memory by default rather than mutating the row. It still omits permissions requirements, reversibility, and what happens to the prior memory (invalidation vs retention), so it is strong but not complete.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences with zero filler; the in-place scope comes first and the default-fork side effect second, so the most consequential behavior is front-loaded. Nothing repeats the title or wastes tokens.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 9-parameter mutation tool with no annotations and no output schema, the description covers field mutability and the supersede default but says nothing about the response (does the returned id change when a superseding memory is created?) or about failure modes such as an unknown id. Adequate, but gaps remain for an agent to call it confidently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 78%, so most parameters are already documented in the schema, including the supersede flag and the content/supersede interaction. The description restates the field set (with snake_case names that differ from the schema's camelCase) and adds no format or constraint detail beyond the schema, so it sits at the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (update) and resource (memory), and enumerates the mutable fields plus the in-place vs supersede distinction. This separates it from write siblings like remember and merge_memory, but it never names an alternative explicitly, so an agent must infer routing from the field list alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by 'Update mutable fields ... in place' and by the supersede=false escape hatch, which tells the agent how to force an edit rather than a fork. However, there is no explicit when-to-use vs remember/merge_memory/consolidate guidance and no stated preconditions (e.g. that the id must exist and be live).

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. 1 tool updatev2.3.0
    • Changedconsolidate2 fields changed
      • addedInput schema / properties / sessionId
        Added value: +{
        +  "description": "Scope to a session (SESSION scope)",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedInput schema / properties / userId
        Added value: +{
        +  "description": "Scope to a user (USER scope)",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
  2. 2 tool updatesv2.2.9
    • Changedforget1 field changed
      • changedInput schema / properties / type / enum
        Previous value: -[
        -  "preference",
        -  "lesson",
        -  "interaction"
        -]New value: +[
        +  "memory",
        +  "preference",
        +  "lesson",
        +  "interaction"
        +]
    • Changedupdate_memory3 fields changed
      • addedInput schema / properties / validFrom
        Added value: +{
        +  "anyOf": [
        +    {
        +      "format": "date-time",
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "ISO timestamp or null to clear"
        +}
      • addedInput schema / properties / validUntil / anyOf
        Added value: +[
        +  {
        +    "$ref": "#/properties/validFrom/anyOf/0"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / validUntil / type
        Removed value: -[
        -  "string",
        -  "null"
        -]
  3. 16 tool updatesv2.2.1
    • First observedconsolidate
    • First observedexport_memory
    • First observedextract_memories
    • First observedforget
    • First observedget_context
    • First observedget_profile
    • First observedget_recent_interactions
    • First observedimport_memory
    • First observedlink_memory
    • First observedmemory_stats
    • First observedmerge_memory
    • First observedrecall
    • First observedremember
    • First observedsave_lesson
    • First observedsearch_history
    • First observedupdate_memory

TDQS

A3.7/5.0

Scored across 16 tools

Disambiguation4/5

Most tools clearly target distinct operations, but recall and get_context both serve task-time memory retrieval and could be confused by an agent. Search-related tools are otherwise differentiated by scope, and descriptions provide enough clarity.

Naming Consistency3/5

Names mix single-word verbs like remember and forget, get_ prefixed accessors, verb_noun operations like merge_memory, and the noun-only memory_stats. The inconsistent style is noticeable, though all names are snake_case and readable.

Tool Count3/5

With 16 tools, this sits at the borderline heavy end for a memory server. The breadth is somewhat justified by coverage of CRUD, graph links, consolidation, import/export, and stats, but a few tools could potentially be combined.

Completeness5/5

The tool set covers the full memory lifecycle: capture/extract, save, retrieve, update, merge, delete, graph linking, consolidation, profile generation, export/import, and statistics. There are no obvious critical dead ends for the stated memory-management purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • -
    license
    Not graded
    quality
    Not graded
    maintenance
    Provides persistent local memory functionality for AI assistants, enabling them to store, retrieve, and search contextual information across conversations with SQLite-based full-text search. All data stays private on your machine while dramatically improving context retention and personalized assistance.
    3
    -
  • A
    license
    Not graded
    quality
    Not graded
    maintenance
    Provides AI coding agents with persistent, long-term memory through local semantic search and SQLite storage. It enables agents to save and retrieve architectural decisions or project context across different conversation sessions without requiring cloud services.
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Provides persistent cross-session memory and full-text search for AI coding assistants, storing project context, decisions, and preferences while enabling searchable access to conversation history via local SQLite.
    8
    1
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Provides AI coding assistants with persistent memory storage using a local SQLite database. Enables tools to remember project details, notes, and relationships across sessions to maintain context and reduce repetitive explanations.
    17
    4
    MIT