pond
The Pond server provides read-only, MCP-based access to a searchable archive of AI agent session history (Claude Code, Codex, opencode, etc.). It enables recall, retrieval, and SQL analysis of past sessions and messages.
Search: Use
pond_searchfor semantic (vector) or full-text (BM25) search across sessions, with filters for project, agent, session ID, and date range. Results are grouped by session, sorted by relevance or recency.Retrieve sessions: Use
pond_get_sessionto read a full session transcript chronologically, with paging and support for anchoring at start, end, or a specific message. Subagent sessions are accessible via footer links.Inspect messages: Use
pond_get_messageto expand a message with full content (tool calls, results, reasoning, files) and surrounding context (configurable before/after window).Run SQL queries: Use
pond_sqlto execute read-only SQL (PostgreSQL/DataFusion compatible) over thesessions,messages, andpartstables for aggregation, tool-call analytics, text search, or bulk export to Parquet/NDJSON.All tools are read-only and idempotent, safe for agents. The primary use case is to let AI agents query past sessions to recall how previous problems were solved.
It also offers
schema://pondandschema://pond-sqlresources for canonical data definitions.
pond
"I know we discussed that before. Why can't I find that damn conversation?"
Pond makes every AI agent session you've ever run - Claude Code, Codex, any tool, any machine - searchable in one place.
Your agent history is already on your disk: thousands of sessions full of decisions, fixes, and dead ends - scattered across tools that can't search them. Pond ingests them all automatically and losslessly into storage you own (a local dir or your own S3 bucket), makes the whole corpus searchable and SQL-queryable, and hands that recall back to your agents over MCP - so "how did we fix this before?" is a query, not an archaeology dig. Sessions stop being locked to the tool that created them: any session can be restored into any supported client and continued there.
brew install tenequm/tap/pond # macOS / Linux
scoop bucket add tenequm https://github.com/tenequm/scoop-bucket # Windows
scoop install tenequm/pondOr prompt your agent: "Please install and set up pond (see github.com/tenequm/pond)" - the full, failure-proofed version of that prompt is in Connect your agents.
Status: pre-v1. Schemas, wire shapes, and config keys are subject to breaking change until v1. Full documentation lives at pond.locker; the contract is docs/spec.md.
Quickstart
Install, run guided setup, and ingest your local sessions:
brew install tenequm/tap/pond # macOS / Linux; Windows: Scoop or a release zip - see Install below
pond init # guided setup: storage, adapters, MCP + agent skill, optional schedule
pond sync # ingest and index - every enabled adapterpond init registers pond as an MCP server for Claude Code and installs the bundled pond skill; for Codex it prints the command to run instead - restart the client afterwards so the tools load. By hand: claude mcp add -s user pond -- pond mcp, codex mcp add pond -- pond mcp; skill: mkdir -p ~/.claude/skills/pond && pond skill > ~/.claude/skills/pond/SKILL.md (that whole line is POSIX-only - mkdir -p, &&, and > all break or corrupt in Windows PowerShell 5.1; use the PowerShell block in Connect your agents). Then ask your agent - real prompts from daily use:
check in pond how we solved this before, then apply the same fix herewhere we left off yesterday - check pond, then continueare you sure that won't break X? check in pond how we struggled with exactly thisSessions are picked up automatically from Claude Code, the Claude desktop app (local agent mode), Codex CLI, opencode, pi-coding-agent, oh-my-pi, OpenClaw, NanoClaw, Hermes Agent, letta-code, and grok-build. A Claude.ai data export imports with pond sync claude-ai-export --path <path> (manual download, so not auto-discovered).
Related MCP server: suasor
Isn't this another memory tool?
No - it's the layer underneath one. Memory tools store what they decided you'd need - facts, summaries, filed chunks; the sessions themselves are gone. Pond keeps the sessions: every message, tool call, and result, value-complete, cross-client, in storage you own, never pruned - searchable over MCP and restorable into any client. Memory is a derived view you can always rebuild from an archive; an archive can never be rebuilt from memories.
Three kinds of tool get called "memory". Side by side:
pond | Session search (ctx, deja-vu, cass) | Memory layers (Mem0, Letta) | |
History from before install | yes | yes | no |
What is kept | the whole session | a search index ¹ | extracted facts |
Where it lives | local dir or S3 bucket | local index | the tool's database |
After the harness deletes the file | still there | gone at next refresh ¹ | only the extract |
Several machines | one shared bucket | pulled into one machine ² | shared server or cloud |
Agent access | CLI, MCP, HTTP, SQL | CLI, MCP ³ | HTTP, SDK, MCP |
¹ cass also mirrors the raw files, so they outlive the source. ² deja-vu copies records between machines over ssh; cass pulls other hosts' session files over ssh/rsync into its local index; ctx is single-machine. ³ cass has no MCP server.
Pick session search for fast local recall. Pick a memory layer when the agent should carry distilled facts, not the record. Pick pond when you want the sessions themselves, in storage you own, from every machine you run.
Full comparison, with receipts per tool: pond.locker/compare. Every cell is a claim about a specific version of someone else's project. If one has gone stale, open an issue and it gets fixed the same day.
Background
Every agentic CLI ships its own session format and its own search surface. Switching tools means losing history. Replaying a Claude Code session in another provider's tooling means re-translating the wire shape by hand. Hosted multi-tenant deployments rebuild the same storage layer from scratch.
Pond is the storage and retrieval layer that sits underneath. Every adapter is a bidirectional codec between a client format and one canonical schema, so any session can be restored by any adapter - it need not return to the client that produced it. Storage, search (BM25 full-text by default, with optional semantic search, one arm per query), and provider-agnostic replay all sit on a single Lance-on-object-storage foundation.
The v1 surface includes: full CLI, HTTP+JSON and MCP transports, search over three Lance datasets, opt-in intfloat/multilingual-e5-small embeddings at FP16 weights (Metal on macOS, CUDA opt-in, CPU fallback), and local-FS / S3 / GCS / Azure backends through Lance's object_store integration.
Install
Linux, macOS, and Windows are supported.
macOS and Linux:
brew install tenequm/tap/pond # Homebrew
nix profile add github:tenequm/pond#pond # NixWindows (Scoop, the primary channel - it also ships pondw.exe, the windowless launcher that scheduled sync runs through):
scoop bucket add tenequm https://github.com/tenequm/scoop-bucket
scoop install tenequm/pondBuckets are git clones, so the first line needs git on PATH - if it fails with "Git is required for buckets", run scoop install git and retry.
No Scoop yet? Bootstrap it first, from a normal (non-admin) PowerShell (its installer refuses an elevated shell):
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force
irm get.scoop.sh | iexThen open a new terminal - PATH changes reach only processes started after the install. See the Windows notes for Defender, long paths, scheduling, and WSL.
No package manager (any platform): every release attaches prebuilt binaries (pond-x86_64-pc-windows-msvc.zip on Windows, ~223 MB unpacked) - unpack one and add its directory to PATH (on Windows: Settings > System > About > Advanced system settings > Environment Variables, under your user variables), nothing else to install.
Via cargo (any platform, needs the Rust toolchain):
cargo binstall pond-db # downloads the prebuilt binary (needs cargo-binstall)
cargo install pond-db # builds from crates.io (installs the `pond` command)Both install pond.exe only, so scheduled sync on Windows - which runs through pondw.exe - wants the Scoop or zip install instead (or --features windows-launcher on a source build). cargo install also needs the protoc and NASM prerequisites below.
Build from source:
git clone https://github.com/tenequm/pond.git
cd pond
cargo install --path packages/pondOn Windows that clone needs git config --global core.longpaths true first (test-fixture paths exceed 260 characters), and the build needs an explicit --target x86_64-pc-windows-msvc - without it cargo applies the repo's +crt-static flag to build scripts and proc-macros too, which then fail to load.
For CUDA acceleration on Linux:
cargo install --path packages/pond --features cudaOn macOS the Metal backend is selected automatically; on other systems the CPU fallback runs without extra features. Building from source on Windows additionally needs protoc (winget install Google.Protobuf) and NASM (winget install NASM.NASM, then add C:\Program Files\NASM to PATH yourself - its installer doesn't) on PATH.
If any install path fails, the Troubleshooting guide covers the common stalls.
Usage
Sync and search
Set up storage, adapters, MCP registration, and an optional sync schedule in one pass (idempotent - re-run it any time to repair or update):
pond initThen import sessions from local adapters, update indexes, and search:
pond sync
pond search "how did we wire up the OCC retry loop"Run a server
pond serve # HTTP on 127.0.0.1:9797
pond serve --transport stdio # MCP over stdio
pond mcp # alias for stdio MCPFetch and copy
Fetch a single session or message, or move a whole corpus:
pond get-session <id>
pond get-message <id>
pond copy --from local --to snapshot.pond
pond copy --from snapshot.pond --to localRead-only SQL
Ask structured questions with read-only SQL (the same surface as the pond_sql MCP tool):
pond sql "SELECT project, count(*) FROM messages GROUP BY project ORDER BY 2 DESC"Maintenance
Run maintenance on demand (sync folds indexes on every run):
pond optimize --only embed # only when [embeddings].enabled = true
pond optimize --only indexScheduled sync
Keep pond current automatically (launchd on macOS, systemd user timers or cron on Linux, Task Scheduler on Windows - there, run it from a normal shell, not an elevated one, or the task ends up owned by Administrators):
pond schedule start # every 5m by default (--every 15m|1h|6h|1d)
pond schedule status
pond schedule logsStatus and introspection
pond status prints a per-table storage table, then indexes (text readiness, plus the semantic half only when embeddings are enabled), stored (sessions + messages), agents (source agents in the store), and this host's view of it: per-adapter sessions pending sync, the last sync's outcome (including a surfaced failure from a scheduled run), and the next scheduled run. pond status --hosts breaks a shared store down by ingest host; --include-subagents counts each subagent as its own agent. pond sync --dry-run previews what the next sync would read. pond search --explain returns Lance's analyze_plan output for each retrieval arm.
Remote storage
By default pond stores data locally under ~/.local/share/pond (%LOCALAPPDATA%\pond\data on Windows). To use an object store, add credentials and switch the destination:
pond creds add # interactive: name, access key, hidden secret
pond storage use s3+https://nbg1.your-objectstorage.com/my-pond # probe end-to-end, then flip [storage].path
pond storage check # verify: parse, creds, conditional-put (OCC), write/read/deletepond init --storage-path <url> configures a remote destination during setup and prompts for credentials inline when the destination is remote, so a bucket is one command. The s3+https://host/bucket form works for any S3-compatible store (Hetzner, R2, B2, MinIO); s3://, gs://, and az:// use the standard cloud SDK credential chain when no [creds.*] set matches. pond copy --from <local> --to <url> carries existing local data into the bucket - idempotent, never deletes the source, and on completion it rebuilds the destination indexes and verifies every row landed (exit 6 if any are missing or duplicated, so you never reconcile by hand). pond copy --verify-only --from <local> --to <url> runs that same check read-only, without copying. Full walkthrough: pond.locker.
Configuration
pond init walks through everything below interactively and enables the adapters it finds. pond sync only ingests already-enabled adapters - enabling one is an explicit step (pond adapters enable / pond adapters discover / pond init), never a side effect of sync. Config lives at ~/.config/pond/config.toml on macOS and Linux, %APPDATA%\pond\config.toml on Windows (pond config path prints it). Every [adapters.<name>] block needs enabled = true to be active; sections without it (or with enabled = false) are skipped. ~ in paths expands on every platform (%USERPROFILE% on Windows).
[adapters.claude-code]
enabled = true
path = "~/.claude/projects"
[adapters.codex-cli]
enabled = false # kept in config, skipped on `pond sync`
path = "~/.codex/sessions"Search is BM25 full-text by default. Semantic search is opt-in and off unless you ask for it: with it off no pond process downloads or loads an embedding model, new messages get no vectors, and --mode vector is refused. Turn it on in config or with POND_EMBEDDINGS_ENABLED=true, then run pond optimize --only embed once to fill the backlog:
[embeddings]
enabled = trueFull detail, including what it costs and how mixed fleets behave, is in the configuration reference.
Supported harnesses
One adapter per harness, in pond adapters discovery order; Reads is the path pond init discovers and writes to [adapters.<name>].path - shown POSIX-style, with the same home-relative layout on Windows (~/.claude/projects is %USERPROFILE%\.claude\projects). Last verified is the most recent capture or refresh date of the adapter's committed fixture (packages/pond/tests/fixtures/adapter/), the corpus its mapping is tested against. Adapters are maintained best-effort, and format drift is safe by design: unknown record shapes still ingest losslessly, malformed input surfaces as a typed error naming the file. Adding a harness is routine work - see Contributing.
Adapter | Reads | Last verified |
| Claude Code CLI, | 2026-08-14 |
| Claude Desktop / Cowork local agent sessions | 2026-05-13 |
| claude.ai data-export archive (manual | 2026-06-04 |
| OpenAI Codex CLI, | 2026-09-01 |
| opencode, | 2026-07-14 |
| openclaw, | 2026-05-13 |
| nanoclaw, | 2026-05-14 |
| Hermes Agent, | 2026-07-23 |
| pi, | 2026-08-06 |
| oh-my-pi, | 2026-08-14 |
| letta-code, | 2026-08-24 |
| grok-build (xAI | 2026-08-24 |
Verbosity
Root-level -v / -vv / -vvv raise the tracing level (info / debug / trace); -q / -qq lower it. The default surfaces warnings only. RUST_LOG overrides the CLI flag when set; POND_LOG is no longer honored.
Design
The full contract is in docs/spec.md. Key choices:
Lance direct, no wrapper. The
lance-format/lancecrates are the only storage and search engine. Nolancedb, no parallel abstraction. Storage, indexing, OCC, schema evolution, blob columns, versioning, and time-travel are all Lance. The read-onlypond sqlsurface is DataFusion planning over the same Lance datasets - a query escape hatch, not a second engine.Canonical Session / Message / Part interlingua. Owned in pond, in the shape of Effect v4's
Prompt-side Part union. This schema is pond's product; everything else is machinery around it.Three Lance datasets (
sessions,messages,parts).messagescarries the nullable embedding (vector+embedding_model) alongside denormalized filter columns (source_agent/project/role/timestamp) for single-stage filter pushdown.No-synthesis adapter seam. Adapters parse source records through extractor helpers that make "invent a value" a compile error -
model-no-synthesis,model-schema-honesty, andadapter-provenance-requiredare structural, not review rules.Index lifecycle decoupled from writes. Writes commit data (including embeddings, computed inline at ingest when embeddings are enabled) without folding the search indexes.
pond syncruns index maintenance by default, andpond optimize --only indexruns it on demand; Lance merges index results with a flat scan over unindexed fragments, so reads stay correct.Single-arm retrieval. Each query runs one retriever -
fts(BM25, the default) orvector(cosine, with a gentle recency tiebreaker, offered only when embeddings are enabled) - chosen per query; no server-side fusion.--sort-by recencyreturns newest-first. Results group to one summary per session, keyed onsession_root.Language-neutral full-text. Word-level
simpletokenizer with English stemming (ascii-folding on); tokens the stemmer does not recognize pass through unchanged and stay exact-matchable, so pond indexes sessions in any language alike.Two transports, one handler set. HTTP+JSON (axum) and MCP (rmcp) both dispatch into the same handlers. Wire ops:
pond_search,pond_get_session,pond_get_message,pond_ingest. MCP additionally exposes the read-onlypond_sqltool and theschema://pond,schema://pond-sql, andstats://pondresources.Opaque-string multi-tenancy. Each tenant is a
namespacestring the integrator supplies; pond does not authenticate, authorize, or model identity. The object store's IAM is the storage boundary.Encryption is operational. Bucket SSE plus filesystem encryption; pond holds no keys and adds no application-level crypto.
Roadmap
pond ships in small steps. This table lists the steps in order. Done steps stay in the table. The roadmap board holds the same items with their issues. React or comment on an issue to influence the order.
# | Step | Status |
1 | Lossless ingest from Claude Code and Codex into Lance, local or S3 | ✅ v0.5 |
2 | Single-arm search: BM25 or vector, one arm per query | ✅ v0.10 |
3 | Remote sync in under a minute; warm search in under a second | |
4 | Tool-call columns and read-only SQL over the corpus | ✅ v0.13 |
5 | Crash-safe local stores that self-heal on open | ✅ v0.14.0 |
6 | Eleven harnesses, | ✅ v0.14.11 |
7 | BM25 becomes the default arm. Embeddings become opt-in. #164 | ✅ v0.15.0 |
8 | New adapters become routine: | ✅ v0.15.1 |
9 | Lance 10, then 11: count pushdown, date-filter zonemaps, stemmer self-heal. #145 | |
10 |
| ⏭ Next |
11 | Remote reads as fast as local reads. #165 | ⏳ Later |
12 | Namespaces: keep work and personal sessions apart. #166 | 🔧 In progress (design) |
13 | Redaction on copy, export, and resume. Never at ingest. #167 | ⏳ Later |
14 | herdr plugin: every session in one list, live or not, on any machine. Resume, fork, hand off. #219 | ⏳ Later |
The canonical model as a published contract: ATIF export and import, a | 🔧 In progress | |
Community adapters: ten harnesses wanted, playbook-driven - Antigravity CLI, Qwen Code, Crush, Cline, OpenHands, Copilot CLI, Cursor CLI, Droid, Kiro CLI, Roo/Zoo Code. | 🙋 Wanted | |
A capture daemon. pond reads what your harness already writes. | ❌ Not planned | |
A hosted service that owns your bucket. Your storage stays yours. | ❌ Not planned | |
Summaries or pruning of stored sessions. pond keeps the sessions. | ❌ Not planned |
Step 7 was based on data. Over 63 days, agents ran 1,126 searches against this archive. BM25 found the answer 61% of the time. Vector found it 37% of the time. Read the measurement.
This is a direction, not a contract. The order changes when the data changes.
References
The upstream schemas that shaped pond's canonical model are documented in docs/references/ (source URLs + why each matters; the vendored code itself is not redistributed). Real session captures live under packages/pond/tests/fixtures/adapter/.
Source | Why it matters |
Effect v4 Prompt/Response Part unions. Pond's canonical types copy this shape. | |
Effect Schema canonical Part union; SDK types; storage schema. | |
OpenCode fork. Adds | |
pi-coding-agent leaf-cursor branching and cross-provider conformance test matrix. | |
GenAI semantic conventions. Inspiration for shape overlap; pond does not derive from OTel. | |
| Session samples for thirteen source harnesses (claude_ai_export, claude_code, claude_desktop_app, claude_managed_agents, codex_cli, grok-build, hermes, letta-code, nanoclaw, oh-my-pi, openclaw, opencode, pi-coding-agent; real captures except the synthetic hermes |
Contributing
Issues and pull requests are welcome. The most useful contributions right now:
An adapter for a harness pond does not read yet. The playbook is the
add-adapterskill; the PR expectations are in CONTRIBUTING.md.Spec feedback on
docs/spec.md.Pointers to additional reference schemas or session samples worth documenting under
docs/references/.Bug reports against the v1 surface (CLI verbs, wire ops, schema mismatches, OCC behavior, object-store backends).
For something bigger, the roadmap is the list. Comment on the issue before you start, so we agree on the scope. For other larger changes, open an issue first to discuss the direction. For security issues, see SECURITY.md.
Questions or feedback? Start a GitHub Discussion, or DM me on Telegram or X - I answer personally.
Links
Docs: pond.locker
Crate: pond-db on crates.io
MCP Registry name:
mcp-name: io.github.tenequm/pond
License
Apache-2.0 (c) 2026 tenequm
Available Tools
4 toolspond_get_messageARead-onlyIdempotent
Expand one message with its full part bodies (tool_call / tool_result / reasoning / file), plus conversational neighbors for context. Pass a message_id from pond_search or a transcript line; context_before / context_after size the neighbor window (default 3, like grep -B/-A). For the whole session use pond_get_session. Response format details: resource schema://pond.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The message to expand - a message_id from pond_search or a transcript line. | |
| context_after | No | Conversational sibling messages to include after the target (mirrors grep -A). Default 3. | |
| context_before | No | Conversational sibling messages to include before the target (mirrors grep -B). Default 3. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the tool read-only and idempotent. The description adds meaningful behavioral context by explaining the output includes full part bodies and that context_before/context_after control neighbor inclusion (default 3, like grep -B/-A). No contradiction is present.
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 three sentences, front-loaded with the primary action, and every sentence earns its place. It packs core semantics, usage guidance, and a sibling pointer without waste.
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 only 3 parameters, no output schema, and strong annotations, the description covers what the tool does, how to identify the target message, the behavior of optional parameters, and a pointer to the alternative for broader context. It also points to a resource schema for response format details, making it 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 coverage is 100%, but the description enriches parameter meaning by explaining id can come from pond_search or transcript, and by giving the grep analogy for context_before/context_after defaults. This adds value beyond the bare schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Expand') with a clear resource ('one message') and details what expansion includes (full part bodies: tool_call/tool_result/reasoning/file) plus conversational neighbors. It also distinguishes from sibling tools by explicitly pointing to pond_get_session for whole-session 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?
The description clearly instructs how to obtain the message_id (from pond_search or a transcript line) and names an alternative tool for whole-session needs ('For the whole session use pond_get_session'). It doesn't explicitly state when not to use it, but the context is unambiguous enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pond_get_sessionARead-onlyIdempotent
Read a whole past session as a chronological transcript - the tool for analyzing, reviewing, or summarizing a session (user/assistant text plus one-line tool/file refs; tool bodies stay one pond_get_message away). Pass the id from pond_search or a subagent footer; a message_id also works - it resolves to its parent session with the page anchored at that message. Paging: limit (default 20), from="end" reads the most recent turns first (the session's final state; late conclusions supersede early ones), after_message_id / before_message_id continue from a page marker. The first page lists subagent sessions in a footer - pass a listed id back to open one. Not for bulk export - use pond copy --to <file>. Response format details: resource schema://pond.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The session to read - a session_id from pond_search or a subagent footer. A message_id also works: it resolves to its parent session with the page anchored at that message. | |
| from | No | Which end to read the first page from: "start" (oldest, default) or "end" (most recent - the session's final state, e.g. to recover context after compaction). Pages stay chronological. | |
| limit | No | Max messages per page. Default 20, max 1000. | |
| after_message_id | No | Page forward: a message id from a prior page's bottom marker; returns messages after it. | |
| before_message_id | No | Page backward: a message id from a prior page's top marker; returns messages before it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, but the description adds substantial behavioral context: chronological ordering, paging semantics, from="end" reading final state, subagent footer listing, and that message_id resolves to parent session. It also warns about late conclusions superseding early ones.
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 dense but every sentence serves a purpose: purpose, id resolution, paging, subagent navigation, and bulk-export exclusion. It is front-loaded with the core purpose and avoids filler.
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 no output schema and nontrivial paging, the description covers the key aspects: content of the transcript, paging methods, id sources, and subagent handling. It points to resource schema://pond for return format, but does not detail response fields. Slight gap, but still robust enough for an agent to select and invoke correctly.
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?
Though schema coverage is 100%, the description significantly enriches parameter meaning: it explains that message_id resolves to parent session, from="end" reads most recent turns first, and describes how after_message_id/before_message_id act as page markers. This goes far beyond the schema's basic field definitions.
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 opens with a specific verb and resource: "Read a whole past session as a chronological transcript." It clearly distinguishes from siblings (pond_get_message, pond_search, pond_sql) by noting tool bodies are one message away and that bulk export should use `pond copy`.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly frames when to use the tool: "the tool for analyzing, reviewing, or summarizing a session," and gives a clear alternative for bulk export. Also explains how to obtain the id from pond_search or a subagent footer, and advises against bulk export, directing to `pond copy`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pond_searchARead-onlyIdempotent
Find relevant messages in past sessions - the entry point for recall: "have we worked on X", "what did we decide about Y", "find the session where...". mode="vector" (default) matches meaning; mode="fts" matches exact whole words (BM25). Scope with project / session_id / source_agent / from_date / to_date; keep the query semantic (concepts, not project names). Returns scored hits grouped by session, best session first; pass a hit's session_id to pond_get_session or its message_id to pond_get_message to read it. Searches conversational text only (tool calls/results and reasoning are excluded by design - a gap there is expected, not a failure) and excludes subagent sessions; reach both via pond_sql. Response format details: resource schema://pond.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | Retrieval arm: "vector" (default - matches on meaning) or "fts" (matches exact whole words via BM25). Use vector for concepts/ paraphrases, fts when you know the literal words. Falls back to fts when the store has no embeddings. | |
| limit | No | Max sessions to return. Default 10, server-capped at 200. This is also the "want more results" knob - raise it; there is no pagination. | |
| query | Yes | What to search for: concepts and keywords. Keep it semantic - do not put project names in the query, use the `project` filter instead. | |
| project | No | Filter to projects whose path contains this substring. | |
| sort_by | No | Result order: "relevance" (default - best match first) or "recency" (newest first; the response is labeled so you don't read rank-1 as the best match). | |
| to_date | No | Only messages on or before this date (YYYY-MM-DD). | |
| from_date | No | Only messages on or after this date (YYYY-MM-DD). | |
| session_id | No | Filter to one session (exact match) - search within a single, possibly long, session. | |
| source_agent | No | Filter to one source harness. A root value ("openclaw", "claude-code") returns that harness's main sessions (subagents stay excluded, like the default). Name a subpath ("claude-code/general-purpose", "openclaw/subagent") to search those subagent sessions directly - a subpath value is the deliberate opt-in that disables the default subagent exclusion. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only and idempotent, and the description adds substantial behavioral detail: vector mode fallback to fts, scored hits grouped by session with best-first ordering, conversational-text-only scope, subagent exclusion with deliberate opt-in via source_agent subpath, and no pagination (limit as knob). No contradiction with annotations.
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?
Four dense sentences, each earning its place: purpose/examples, modes, scoping/filters, output/navigation, exclusions. Well front-loaded and free of fluff.
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?
Despite lacking an output schema, the description explains return structure (scored hits grouped by session), how to access full messages, and the expected gap for excluded content. It also points to a resource schema for further response details. Given the tool's complexity, this is 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 coverage is 100% with rich per-parameter descriptions. The main description reinforces a few concepts (semantic query, mode meaning, scoping filters) but adds limited new parameter-level detail beyond the schema. Baseline 3 is appropriate since the schema carries the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description opens with a specific verb+resource: 'Find relevant messages in past sessions' and positions it as 'the entry point for recall' with example queries. It further distinguishes from siblings by directing users to pond_get_session/pond_get_message for reading hits and to pond_sql for excluded content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly defines when to use: entry point for recall queries. Clearly states what is excluded (tool calls/results, reasoning, subagent sessions) and points to pond_sql for those cases, giving concrete when-not-to-use guidance. Also explains mode choices (vector vs fts) and scoping filters.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pond_sqlARead-onlyIdempotent
Advanced escape hatch: run ONE read-only SQL statement (SELECT/WITH, DataFusion / PostgreSQL-compatible) over the sessions / messages / parts tables. NOT for finding or reading conversations - pond_search and pond_get_session / pond_get_message cover almost all recall. Reach for SQL only for: aggregation (counts, group-by, joins, time buckets), exact strings or identifiers in conversational text (contains_tokens / fts), tool-call analytics and tool bodies, subagent sessions, bulk export (format=parquet|ndjson). Read resource schema://pond-sql FIRST - exact columns, indexed predicates, JSON access rules, worked examples; do not guess column names or JSON paths. Inline text output is row-capped and long cells clip with a +N chars marker (full values via format=parquet|ndjson); queries are wall-clock-capped (raise via timeout_seconds).
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | One read-only SQL statement (SELECT/WITH only; writes rejected). Exact columns - messages(session_id, message_id, timestamp, role, source_agent, project, content [system-role only], search_text [the conversational text], embedding_model, options) | sessions(session_id, parent_session_id, parent_message_id, source_agent, created_at, project, options) | parts(session_id, message_id, id, ordinal, type, provenance, tool_name, call_id, is_failure, variant_data, options). parts.type enums use underscores: 'tool_call', 'tool_result', 'text', 'reasoning', 'file'. Tool bodies live in JSONB variant_data - tool_call is {call_id, name, params} (a Bash command is json_extract(variant_data, '$.params.command')), tool_result is {call_id, name, is_failure, result}; never CAST JSON columns. No substring index covers tool bodies: an unscoped LIKE over variant_data full-scans and times out on a remote store - scope-then-scan instead (collect session_ids WHERE contains_tokens(search_text, '...'), then match variant_data fields only within them; worked example in schema://pond-sql). Tool analytics: prefer the narrow native columns (tool_name, call_id, is_failure). Text search: WHERE contains_tokens(search_text, 'words'), or FROM fts('messages', '{...}') for BM25 ranking. Joins, indexed columns, JSON functions, pagination, worked examples: resource schema://pond-sql. | |
| format | No | Output format: "text" (default; rendered ASCII table with metrics footer, row-capped), "parquet", or "ndjson". For parquet/ndjson the full result set is written to a file and a `pond-sql-export://` resource link is returned (no truncation) - ndjson is the path for machine-readable JSON output. | |
| timeout_seconds | No | Per-query timeout in seconds (default 30, max 600). Raise it for a genuinely long-running query (e.g. a large remote-store scan); prefer narrower predicates and the indexed/native columns first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint, openWorldHint, idempotentHint), the description discloses critical runtime behaviors: output is 'row-capped' with 'long cells clip with a +N chars marker', queries are 'wall-clock-capped', and writes are rejected (in schema description). It also warns about performance pitfalls ('unscoped LIKE over variant_data full-scans and times out') and tells users to scope-then-scan. This goes well beyond annotation hints and prepares the agent for real-world edge 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?
The description is a single, dense paragraph that front-loads purpose and exclusions, then lists use cases, then gives operational guidance and output/performance caveats. Every sentence earns its place; there is no filler or tautology. The structure makes it easy to scan and absorb.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (SQL over multiple tables, JSONB fields, export modes, potential for timeouts), the description is remarkably complete. It covers return value behavior (row cap, truncation, export links), performance pitfalls, schema resources to read first, and use-case boundaries. No output schema exists, but nothing is missing for selecting and invoking the tool correctly.
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?
With 100% schema description coverage and highly detailed parameter descriptions, the baseline is 3. The tool description adds usage context for parameters: linking format=parquet|ndjson to avoiding truncation, and timeout_seconds to raising the wall-clock cap for long-running queries. This enriches the bare schema without being essential, so a 4 is appropriate rather than a 5.
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 opens with a clear verb+resource: 'run ONE read-only SQL statement' over specific tables ('sessions / messages / parts'). It explicitly distinguishes itself from siblings by stating 'NOT for finding or reading conversations' and naming pond_search and pond_get_session / pond_get_message as alternatives. This leaves no ambiguity about the tool's niche.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance: 'Reach for SQL only for: aggregation (counts, group-by, joins, time buckets), exact strings or identifiers in conversational text (contains_tokens / fts), tool-call analytics and tool bodies, subagent sessions, bulk export'. It also gives a clear exclusion ('NOT for finding or reading conversations') and names alternative tools, fulfilling the when/when-not/alternatives criteria perfectly.
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. Dates show when Glama detected each change.
4 tool updates
v0.14.4- First observed
pond_get_message - First observed
pond_get_session - First observed
pond_search - First observed
pond_sql
TDQS
Each tool targets a distinct purpose: pond_search for discovery, pond_get_message for single-message expansion, pond_get_session for full-session transcripts, and pond_sql for advanced SQL queries. The descriptions make the boundaries clear, and there is no overlap in functionality.
All tools share the pond_ prefix and use snake_case, but the pattern is not perfectly uniform: two use get_ (pond_get_message, pond_get_session), one uses a bare verb (pond_search), and one uses a noun (pond_sql). This is mostly consistent but with a slight deviation.
Four tools is well within the ideal 3-15 range for a focused server. Each tool earns its place: search, single-message read, session read, and SQL access cover the core recall/analytics functionality without redundancy.
The set provides a complete workflow for recalling past conversations: search to find, then either get a message or get a session to read, with SQL as an escape hatch for advanced queries, exact matching, and analytics. The documented gaps (tool bodies, subagent sessions) are explicitly addressed via SQL, so there are no dead ends.
Maintenance
Related MCP Connectors
Hosted MCP memory: save sessions/decisions once, search from Claude, Cursor, ChatGPT. EU-hosted FTS.
Portable memory for AI agents: capture once, recall across Claude, Cursor, and any MCP client.
Persistent memory for AI agents — log and recall conversation context over MCP.
- memnodeOAuthdev.memnode
Persistent, inspectable memory for AI agents with lineage, correction, and a hosted MCP endpoint.
Related MCP Servers
- AlicenseAqualityBmaintenanceCognitive prosthetic for AI agents. Indexes conversation history from ChatGPT, Claude Code, Cursor, and Gemini CLI into searchable embeddings. 25 MCP tools including tunnel_state (resume where you left off), switching_cost (quantify context-switch penalty), thinking_trajectory (track idea evolution), and alignment_check (decisions vs principles). LanceDB + Parquet, 12ms recall, local-first.2569MIT
- AlicenseNot gradedqualityAmaintenanceA local-first AI secretary that gathers your work context into private memory and enables AI agents to search and summarize it over MCP.38MIT
- AlicenseNot gradedqualityBmaintenanceLocal-first memory daemon for AI coding agents that captures session transcripts, distills typed memories (decisions, facts, lessons, commands, todos), and serves them via hybrid search through MCP tools.45MIT
- AlicenseNot gradedqualityAmaintenanceLocal-first MCP server that lets AI agents query their own LLM call history as a branchable DAG and offload conversation context into immutable, AES-256-GCM-encrypted capsules — restorable in full or per segment, crypto-shreddable, with RAID-style replication. 12 tools, no API keys, no cloud.1793MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/tenequm/pond'
If you have feedback or need assistance with the MCP directory API, please join our Discord server