Skip to main content
Glama
IBazylchuk

Paparats: Local Semantic Code Search

Paparats MCP: self-hosted semantic code search for AI coding agents

npm version License: MIT PulseMCP MCP Badge Glama

Paparats MCP is an open-source, self-hosted MCP server that gives Claude Code, Cursor, Codex, GitHub Copilot and any other MCP client semantic code search across many repositories: by meaning, with who calls what, and what a change will touch. It runs on your machine or your server in Docker, with local embedding models by default, so your code stays with you.

Your agent asks "where do we retry failed payments?" and gets the few functions that do it, with file and line, instead of grepping and reading whole files. Before changing one, it asks what depends on it and gets the callers two steps out (up to three) and the tests that reach them.

With Paparats the agent answered 25% faster and read 23% fewer new tokens. Claude Code, the same question about this repository, without Paparats (left) and with it (right), at 5× speed. Averages over three runs each: 99 s against 74 s, 23% fewer new input tokens and 21% fewer output tokens. This repository is small, about 300 files. On large legacy codebases spread over many repositories, where I use Paparats every day, the difference is much bigger.

Quick start

You need Docker with Compose v2. Two files and one command:

mkdir paparats && cd paparats
curl -fsSLO https://raw.githubusercontent.com/IBazylchuk/paparats-mcp/main/examples/docker-compose/docker-compose.yml
curl -fsSLO https://raw.githubusercontent.com/IBazylchuk/paparats-mcp/main/examples/docker-compose/projects.yml
docker compose up -d
claude mcp add --scope user --transport http paparats http://localhost:9876/mcp

projects.yml indexes this repository, so there is something to ask about right away (docker compose logs -f paparats-indexer shows the progress). Put your own GitHub repositories there; the file is reloaded on save, and private ones need GITHUB_TOKEN in a .env next to it. Any other MCP client takes the same URL, http://localhost:9876/mcp (setup for each).

Then ask your agent:

Search the codebase for where we handle failed payments, show me what calls it, and what would be affected if I changed it.

Without local models: download docker-compose.voyage.yml instead, put VOYAGE_API_KEY=... into .env and run docker compose -f docker-compose.voyage.yml up -d. Code is then sent to Voyage AI to be embedded, and the 2.3 GB of models are not needed.

With the CLI

Easier for folders on your machine (it mounts them for you) and on macOS, where the models run natively with Metal; in Docker on a Mac they only get the CPU. Needs Node.js 24+.

npm install -g @paparats/cli
brew install llama.cpp mostlygeek/llama-swap/llama-swap   # macOS only: local models with Metal

paparats install            # starts the stack, connects Claude Code and Cursor
paparats add ~/code/my-app  # or `.`, or a GitHub repo: paparats add acme/widgets
paparats list               # wait until the project shows as indexed

Nothing local: Open in GitHub Codespaces runs the whole stack in your own Codespace, on this repository.

All install options, hardware and upgrading: docs/install.md.

Related MCP server: Serena

What your agent gets

  • search_code: finds code by what it does, across every repository in a group. The file path is embedded with each chunk, and a query naming a class or function ranks its definition higher.

  • find_usages and change_impact: a call graph by method, built from the syntax tree. change_impact lists what depends on the code you are about to change, marks the uncertain links and lists the tests apart.

  • module_map: the modules of a codebase, worked out from who calls whom, with their main files and how they depend on each other. Also a page you can walk: http://localhost:9876/ui/map.

  • Git history per chunk: who changed it, when, and the tickets named in the commit messages.

  • Architectural memory: components, decisions and lessons the agent records as it works and reads before changes that cross components. More.

  • Documentation search and a glossary: your markdown, searched by meaning and keywords (opt-in), and a shared list of team terms. More.

The code map at /ui/map: this repository folder by folder, with arrows for who calls whom.

Tools come on three endpoints: coding (/mcp) for the agent you write code with, support (/support/mcp), read-only, for support people and bots, and knowledge (/knowledge/mcp), documentation only, behind a token, for a service outside your network. Every tool: docs/tools.md.

FAQ

What is Paparats MCP?

An open-source (MIT) MCP server for semantic code search over many repositories. It runs on your machine or server with Qdrant and local llama.cpp embeddings, and adds a call graph, git history per chunk and agent-maintained architectural memory on top of the search.

How do I add semantic code search to Claude Code?

Start the stack from the quick start and add it to Claude Code with one command (paparats install does this step for you):

claude mcp add --scope user --transport http paparats http://localhost:9876/mcp

The Claude Code plugin does the same and adds a skill that tells Claude when to search by meaning and when to grep.

Which MCP clients work?

Any client with Streamable HTTP, at http://localhost:9876/mcp. docs/clients.md has the setup for Claude Code, Cursor, Codex, GitHub Copilot in VS Code, Windsurf, Antigravity, Gemini CLI, Grok Build, Cline and clients that only start a process (stdio).

Does my code leave my machine?

Not by default. Indexing, the embedding models (bge-code-v1 for code, Qwen3-Embedding-0.6B for prose, served by llama.cpp) and the vector store (Qdrant) all run locally in Docker. Cloud embeddings (Voyage, OpenAI), a remote Qdrant and trace export are opt-in. See PRIVACY.md.

When should I use it, and when not?

Use it when grep-and-read loops eat your agent's context on a large codebase or many repositories, or when several people and agents should share one index. Skip it for one small repository, or for precise refactoring: that is a job for a language-server tool such as Serena, which works well alongside Paparats.

Can it search several repositories at once?

Yes. Projects in one group share a Qdrant collection, so one query covers backend, frontend and infrastructure together. The call graph is built per project; calls from one repository into another are not linked yet.

How fresh is the index after I change code?

Within about 10 minutes. The indexer checks every repository every 10 minutes and indexes only the files that changed, call graph included; a full pass runs every few hours. POST /trigger on the indexer updates it at once, for example from CI. There is no file watcher, so an edit is not searchable within seconds.

Which branch is indexed?

A GitHub repository (url: in projects.yml) is indexed from its default branch. A local folder (path:) is reindexed when its files change, so after a branch switch the index follows the checkout at the next change check (every 10 minutes by default). Index main and let the agent read its own branch: with several worktrees open, indexing each copy is a full index per copy, and mixing branches in one index would answer from code that is not on the agent's branch. The index tells the agent where to look; the files on its branch give the current code. A team shares one server that reindexes main.

Does it replace grep?

No. grep is fast and exact when the agent knows the word: an error message, a field name, every use of a name before a rename. When it does not, it has to guess words and finds nothing where the code is named differently from what it looks for. Search by meaning finds that code; each result lists what the chunk defines and uses, with a chunk id for find_usages and change_impact. Then the agent reads the exact places with grep and plain file reads.

Which languages are supported?

Syntax-based chunking and the call graph cover 11 languages: TypeScript (with TSX), JavaScript, Python, Go, Rust, Java, Ruby, C, C++, C# and Terraform/HCL. Other files are cut into runs of lines of a fixed size and have no call graph.

What hardware does it need?

Docker with Compose v2; the paparats CLI also needs Node.js 24+ (a plain docker compose up of the examples does not). Local models take about 2.3 GB of disk, and the embed container 2–6 GB of RAM. CPU only works; on macOS the native build with Metal is much faster. With a cloud provider there are no local models at all.

Is there a hosted version or a public demo?

No, Paparats is self-hosted only. To try it without installing anything locally, open the repository in GitHub Codespaces.

How is Paparats different from Graphify, codegraph, GitNexus or Serena?

Graphify, codegraph, GitNexus and codebase-memory-mcp build a code graph from the syntax tree and let the agent walk it; they are lighter to install. Graphify and codegraph have no search by meaning, and GitNexus has it only with embeddings turned on; codebase-memory-mcp bundles an embedding model. Across repositories, codebase-memory-mcp links them in one local store, Graphify and GitNexus do it in Graphify Cloud and GitNexus Enterprise, and codegraph queries one project per call. Paparats searches by meaning with local models across many repositories in one query, adds git history and tickets per result, and runs as one server that a whole team and its agents share, with a read-only support endpoint and a docs-only one. Serena drives language servers for precise lookup and editing; Paparats has no editing tools, and the two work well together. All of them, claude-context and Sourcegraph side by side: comparison with alternatives.

Documentation

Page

What is in it

Install

paparats install and its options, plain docker compose, Codespaces, support mode, hardware, v1 migration

Clients

Setup for every MCP client, the note that tells an agent when to use it

Tools

Every tool on each endpoint, workflow prompts, typical flows

Configuration

projects.yml, .paparats.yml, groups, freshness, CLI, environment variables

How it works

Indexing, search and ranking, the call graph, the module map

Architectural memory

Components, decisions, lessons, the glossary

Documentation search

Docs indexing, audience labels, the knowledge endpoint

Embedding models

Local and cloud models, how they were chosen

Monitoring

Prometheus, OpenTelemetry, the /ui console, token-savings estimates

Comparison with alternatives

Graphify, codegraph, GitNexus, codebase-memory-mcp, claude-context, Serena, ast-grep, Sourcegraph side by side

Benchmarking, Chunking, Replacing models, Releasing

For contributors

Contributing

Issues and pull requests are welcome: more languages (PHP, Elixir, Scala, Kotlin, Swift), more embedding providers, faster indexing, new agent use cases. Every pull request carries a changeset; the release process is in docs/releasing.md. Changes to search quality come with a yarn bench compare against main.

The name

Paparats-kvetka, the fern flower, blooms in Slavic folklore on Kupala Night and lets whoever finds it see hidden things. Paparats helps your agent see the right code in a sea of repositories.

MIT license.

Available Tools

18 tools
arch_contextArchitecture ContextA
Read-only

Retrieve architectural memory relevant to a question or set of touched files. Returns three card kinds, each with an updated-at age stamp:

  • Components: what parts the system is made of.

  • Decisions: why they were built that way.

  • Lessons: rules that survived previous mistakes — each rule comes with why (incident context) and when (when to apply) continuation bullets. Superseded and deprecated cards are hidden by default. Cards older than 90 days are prefixed with ⚠ stale — verify them against the current code before acting. Call this BEFORE any non-trivial change. Returns an init hint when the arch layer is empty.

Each kind has its own independent top-N budget — a verbose decision bucket can't starve components. Pass limits: { component, decision, lesson } to override the per-kind cap (default 5 each, max 50; 0 suppresses the kind). When you pass project, cards whose payload matches that project also get a small additive rank boost (~one calibrated tier) so short global cards don't drown out longer project-scoped ones on raw cosine — globals stay visible but no longer dominate. When you suspect ranking issues, prefer arch_list for ground-truth enumeration.

NameRequiredDescriptionDefault
groupNoSpecific group, or omit to query all known groups
limitsNoPer-kind result limits — components, decisions, and lessons each get their own top-N so a verbose decision bucket cannot starve components out of the output. Default is 5 per kind. Set a kind to 0 to suppress it entirely.
projectNoScope results to a single project inside the group (same value the indexer uses as `payload.project` on code chunks). Components are filtered hard — a component without `project=X` is dropped. Decisions and lessons are filtered soft — cards with `project=X` OR no `project` field pass through, so globally-scoped guidance still surfaces. Omit to query the whole group.
questionYesQuestion, or comma-separated list of files being touched
min_scoreNoDrop hits whose cosine similarity is below this threshold. Default 0.45. Lower it (e.g. 0.30) when the arch memory is sparse and you want broader recall; raise it (e.g. 0.60) when you only want high-confidence matches.

TDQS

A4.9/5.0
Behavior5/5

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

The annotations already declare a safe read-only, closed-world operation. The description adds substantial behavior beyond annotations: hidden superseded/deprecated cards, `⚠ stale` prefixes for cards older than 90 days, an init hint on empty architecture memory, independent per-kind budgets, and project-based rank boosting.

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 front-loaded with the core purpose and return shape, then uses compact bullets and short paragraphs for behavior, staleness, limits, project ranking, and the sibling alternative. Despite its length, each sentence conveys operative guidance for invoking or interpreting the tool.

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 complex retrieval tool with five parameters, nested `limits`, no output schema, and read-only annotations, the description covers return kinds, staleness handling, empty-layer behavior, per-kind limits, project ranking, and when to prefer `arch_list`. Nothing essential for correct invocation appears 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%, so the schema already documents all parameters thoroughly. The description still adds meaning beyond the schema for `limits` and `project`, including the default/max behavior, the ability to suppress a kind with 0, and the project-scoped rank boost; it does not add much for `group` or `min_score`, but those are fully covered in 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: retrieve architectural memory relevant to a question or touched files. It enumerates the three returned card kinds and explicitly distinguishes this tool from `arch_list` when ground-truth enumeration is needed, so an agent can identify its role without opening the schema.

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

Usage Guidelines5/5

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

It gives an explicit trigger - call this BEFORE any non-trivial change - and names `arch_list` as the alternative when ranking issues are suspected. It also explains when stale cards require verification, which is actionable usage guidance rather than merely implied context.

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

arch_deleteDelete Architecture CardsA
Idempotent

Hard-delete one or more arch cards by id. No undo, no audit trail — the cards are gone from Qdrant. Use for: cleaning up obsolete cards left over from a refactor, dropping cards for a removed feature, migrating away from old payload schemas. Idempotent: ids that no longer exist are reported in notFound but do not fail the call. Always re-fetch ids via arch_context immediately before calling — ids from earlier in the conversation may point to cards that have since been re-upserted (a re-upsert allocates a fresh UUID), so deleting by a stale id will silently miss the intended card and could wipe a now-current one if the id was reassigned. Prefer supersedes on arch_record_decision when you have a replacement decision; use arch_delete only when there is no replacement.

NameRequiredDescriptionDefault
idsYesCard ids to delete. Idempotent: ids that no longer exist are reported in `notFound` but do not fail the call.
groupYesGroup the cards live in.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations declare destructive and idempotent behavior, but the description adds critical context beyond them: no undo, no audit trail, cards are removed from Qdrant, stale ids can silently miss or wipe now-current cards after re-upserts, and missing ids are reported in `notFound` without failing. This is exactly the kind of behavioral detail an agent needs for a destructive 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 front-loaded with the core action and the most important warning (no undo, no audit trail). The remaining sentences each add distinct operational value: use cases, idempotency behavior, stale-id risk, and the preferred alternative.

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 destructive tool with no output schema, the description covers safety profile, return behavior via `notFound`, id lifecycle risks, required pre-call workflow, and the alternative tool. Nothing material 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 still adds meaningful id semantics beyond the schema: stale ids may point to re-upserted cards with fresh UUIDs and should be refreshed via `arch_context`, and deletion by a reassigned id could wipe a current card. The `group` parameter is left to the schema, which fully documents it.

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 precise verb and resource: hard-delete one or more arch cards by id. It clearly distinguishes the operation from related sibling tools by naming `arch_context` for re-fetching ids and `arch_record_decision` for replacement-based workflows.

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

Usage Guidelines5/5

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

It gives explicit use cases (obsolete cards, removed features, payload migrations) and an explicit when-not/alternative: prefer `supersedes` on `arch_record_decision` when a replacement exists. It also mandates re-fetching ids via `arch_context` immediately before calling, which is a concrete operational guideline.

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

arch_listList Architecture CardsA
Read-only

Enumerate arch cards in a group — no vector search, no ranking, no similarity threshold. Use this when you need every card (audit, dedupe, migration) rather than the top-N most similar to a query. arch_context is for relevance-ranked retrieval; arch_list is for ground truth.

Optional filters:

  • project: components must match this project (hard filter); decisions/lessons match this project OR have no project field (soft filter — group-wide guidance still surfaces).

  • kinds: subset of ['component', 'decision', 'lesson'].

  • include_history: include superseded/deprecated cards (default false).

  • limit (default 50, max 200), offset: pagination — pass next_offset from the previous response to resume.

Returns each card with id, kind, project (or 'global'), status, and a short label (name/title/rule). Use the ids with arch_delete or as input to follow-up arch_record_* calls (e.g. supersedes on arch_record_decision).

NameRequiredDescriptionDefault
groupYesGroup to list cards from.
kindsNoOptional. Restrict to a subset of card kinds.
limitNoOptional. Page size, default 50, max 200.
offsetNoOptional. Resume cursor from a previous call (`next_offset`). Pass the value verbatim — strings that look like JSON (start with `{` or `[`) are parsed back to the structured form Qdrant emits. Omit for the first page.
projectNoOptional. Restrict to one project. Components must match this project (hard filter); decisions and lessons match this project OR have no project field (soft filter, so group-wide guidance still surfaces).
include_historyNoOptional. Include superseded/deprecated cards. Default false.

TDQS

A4.5/5.0
Behavior4/5

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

The annotations already declare a read-only, closed-world operation, but the description adds important behavioral context: there is no vector search or ranking, `project` filtering is hard for components and soft for decisions/lessons, and history is excluded by default. It also describes pagination and returned fields. Minor gaps like error behavior are not material for this list 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 front-loaded with the core distinction and use cases, then lists optional filters and return/id usage compactly. Every sentence contributes actionable information without redundant restatement.

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?

There is no output schema, and the description compensates by explaining the returned card fields and how to use returned ids with `arch_delete` or `arch_record_*` calls. Combined with usage guidance, filter semantics, pagination, and annotation-covered safety profile, it provides enough context to invoke 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?

With 100% schema description coverage, the schema already explains each parameter, so the baseline is 3. The description reinforces the hard/soft `project` filter semantics and the pagination resume pattern, but it largely repeats structured parameter documentation rather than adding substantial new meaning.

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: enumerate arch cards in a group. It explicitly distinguishes this from vector search, ranking, similarity thresholds, and the sibling `arch_context`, so an agent can identify the tool's role without opening schemas.

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

Usage Guidelines5/5

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

It gives explicit when-to-use guidance: audit, dedupe, migration, or any need for every card rather than top-N similarity results. It names the alternative `arch_context` and explains that it is for relevance-ranked retrieval while `arch_list` is for ground truth.

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

arch_record_componentRecord ComponentA
Idempotent

Record (or update by name — idempotent) an architectural component. Use when you discover a logical unit not already in arch_context, or when an existing component's boundary changes. The summary field is structured markdown with four sections (Does / Owns / Does not / Touched when); anchors are stable exported symbol names that survive a refactor. Returns status created or updated.

NameRequiredDescriptionDefault
nameYesComponent name, unique per (group, project). Stable, refactor-resistant — e.g. "file indexer", not "Indexer (in indexer.ts)".
filesNoRepository paths the component spans (e.g. packages/server/src/indexer.ts).
groupYesTarget group
anchorsNoExported class / function / constant names that survive refactors. Used later to verify the card is not pointing at deleted code.
projectYesRequired. Project the component belongs to — the same value the indexer writes as `payload.project` on code chunks (typically the repo directory basename). Components in the same group with the same name but different projects coexist independently.
summaryYesMarkdown with four sections, each one or two short lines: - **Does:** what it does - **Owns:** state / DB tables / external IO it controls - **Does not:** one or two things it explicitly does NOT do (boundary) - **Touched when:** what kind of change forces editing this component
neighboursNoNames of related components (matches `name` of other arch_record_component entries).

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare idempotentHint=true, destructiveHint=false, openWorldHint=false, and the description is consistent with them. It adds value by disclosing the return statuses (created | updated) and the fact that identity is the component name. It omits a key behavioral detail for an upsert: whether omitted fields on update merge or are replaced.

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?

Four compact sentences in a logical order: action, when to use, field semantics, return value. The most decision-relevant information is front-loaded and nothing is padded.

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?

A seven-parameter, four-required mutation tool with no output schema is well served by a description that names the return statuses and explains the two least obvious fields. The remaining gap is the update/merge behavior, which matters for an idempotent upsert but is not addressed.

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 seven parameters are already documented, including the summary four-section structure and anchors stability. The description largely restates schema content (summary sections, anchors surviving refactors) rather than adding format or constraint details, so baseline 3 applies.

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?

States a specific verb+resource (record an architectural component), adds the upsert-by-name idempotent behavior, and names the exact prerequisite store (arch_context). It is clearly distinguishable from siblings like arch_record_decision and arch_record_lesson.

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?

Gives explicit triggers: a logical unit not already in arch_context, or an existing component whose boundary changed. It does not state when NOT to use it (e.g., versus arch_suggest_components or arch_record_decision), so it falls short of the full when/when-not/alternatives bar.

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

arch_record_decisionRecord DecisionA

Record an architectural decision. Use when you pick a library, pattern, or boundary that wasn't obvious. The server runs a similarity gate against existing decisions in the group; possible outcomes:

  • created: a new decision was written.

  • duplicate: a nearly identical decision already exists — nothing is written. Ask the user why arch_context did not surface it earlier.

  • similar: a related decision exists — nothing is written. To explicitly replace it, re-call with supersedes set to its id; otherwise sharpen the wording. Passing supersedes bypasses the gate and marks the named prior decision as superseded.

NameRequiredDescriptionDefault
groupYesTarget group
scopeNoglobal
titleYesShort imperative title — e.g. "Use qwen3-embedding-0.6b for arch-layer text embeddings".
contextYesOne sentence: the problem that forced the decision.
projectNoOptional. Project this decision is scoped to (same value the indexer uses in `payload.project`). Omit for decisions that apply across all projects in the group.
decisionYesOne sentence: what was chosen.
supersedesNoId of a previous decision this one replaces. Bypasses the duplicate gate — pass only when you are deliberately replacing a known prior decision.
consequencesYesMarkdown bullet list, 2-5 items. Each item is one sentence: a consequence, a trade-off, or a required follow-up.
alternatives_rejectedNoMarkdown bullet list, one per rejected alternative: - **<option name>:** why rejected (one sentence) - **<option name>:** why rejected (one sentence) Use an empty string only if no real alternatives were considered.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already identify this as a non-read-only, non-open-world, non-destructive write. The description adds important behavior beyond that: a similarity gate is run, `duplicate` and `similar` outcomes write nothing, and `supersedes` bypasses the gate and marks the prior decision as superseded.

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?

Front-loads the core purpose, then cleanly lists the three gate outcomes. The `supersedes` escape hatch is clearly separated, and every section adds actionable information.

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 a 9-parameter mutation tool with no output schema, the description supplies the missing outcome semantics and replacement workflow. It is complete enough for an agent to invoke the tool correctly and interpret the gate outcomes.

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 89%, so most parameters are already well documented. The description still adds meaningful semantics for `supersedes`, explaining that it bypasses the duplicate gate and marks a prior decision as superseded, which is not fully captured by the schema alone.

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?

States a specific verb and resource: "Record an architectural decision." It also frames the intended trigger condition—non-obvious choices about libraries, patterns, or boundaries—and distinguishes the resulting behavior from simply reading context via `arch_context`.

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

Usage Guidelines5/5

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

Gives explicit when-to-use guidance: "Use when you pick a library, pattern, or boundary that wasn't obvious." It also explains what to do when a duplicate or similar decision is found, including the `supersedes` alternative for deliberate replacement.

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

arch_record_lessonRecord LessonA
Idempotent

Record a lesson — a rule the agent should follow next time. Use when the user corrects a non-obvious mistake of yours, OR when you accept an unusual approach that would surprise a future reader. Skip typos, parser errors, and facts trivially visible in code.

Belongs here (arch) vs. agent-side memory (auto-memory / CLAUDE.md / AGENTS.md):

  • arch (this tool) — rules about the code: contracts, boundaries, patterns, API shape, type invariants, framework gotchas, schema/migration constraints, security rules tied to the codebase. Examples: "GraphQL admin mutations require a non-null ID and a corresponding picker query", "Always preserve createdAt on re-upsert", "Run integration tests against a real database, not mocks".

  • agent-side memory (not here) — rules about the user's workflow or how to collaborate with them: preferred commit style, branch naming, when to ask vs act, formatting preferences. Those live in auto-memory or a CLAUDE.md / AGENTS.md file — not in arch.

  • Heuristic: if a new engineer joining the codebase would need it → write it here. If only this specific user needs it → it's agent-side memory.

Three fields, each markdown:

  • rule: one imperative sentence (the rule).

  • why: 1-3 sentences with the incident — quote the user verbatim when possible.

  • when: one sentence describing the situation in which the rule applies. The server runs a similarity gate; possible outcomes:

  • created: a new lesson was written.

  • updated: a near-duplicate already existed — its updatedAt was bumped (confirmation signal). Refine the existing card if your wording was better.

  • similar: a related lesson exists — nothing is written. Decide whether to refine the existing or write a clearly distinct one.

NameRequiredDescriptionDefault
whyYes1-3 sentences. The incident or reason. Quote the user verbatim if they corrected you.
ruleYesOne imperative sentence — the rule itself. E.g. "Always preserve createdAt on re-upsert."
whenYesOne sentence describing the situation in which this rule applies. Future-you must be able to recognise it.
groupYesTarget group
scopeNoglobal
projectNoOptional. Project this lesson is scoped to (same value the indexer uses in `payload.project`). Omit for lessons that apply across all projects in the group.
evidenceNoOptional commit hash, PR link, or short quote backing the lesson.
severityNoinfo

TDQS

A4.3/5.0
Behavior5/5

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

Beyond the annotations (readOnlyHint=false, idempotentHint=true), it discloses the server-side similarity gate and its three outcomes (created/updated/similar), which is precisely the behavior an agent needs to interpret the result — and it is consistent with idempotentHint=true. It also implicitly sets expectations about what gets written and what the agent should do on a `similar` result.

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

Conciseness4/5

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

Front-loaded with the purpose, then cleanly structured with headings and a bulleted routing rule; almost every line carries decision-relevant content. The three field definitions partially duplicate the input schema's own parameter descriptions, which is the only wasted space.

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 8 params, 4 required, and no output schema, the description compensates well by documenting the three possible outcomes in place of a return schema. The remaining gap is operational: `group`, `scope`, and `severity` semantics are never explained, which matters for a tool whose scoping determines where the lesson lands.

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 75%, so the baseline is 3, and the description largely restates the schema for rule/why/when (adding only "each markdown"). It adds nothing about the undocumented parameters — `group` ("Target group" in the schema too), `scope`, and `severity` — so an agent must guess what a group is and what scope/severity change.

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 first sentence gives a concrete verb and resource ("Record a lesson — a rule the agent should follow next time") and even defines what a lesson is. It sharply distinguishes arch from external agent-side memory files, but never distinguishes itself from the sibling record tools arch_record_component and arch_record_decision, leaving that routing to the agent's inference.

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

Usage Guidelines5/5

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

It gives explicit triggers ("user corrects a non-obvious mistake", "you accept an unusual approach that would surprise a future reader") and explicit exclusions ("Skip typos, parser errors, and facts trivially visible in code"). The arch-vs-agent-memory section with a "new engineer joining the codebase" heuristic routes borderline cases decisively.

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

arch_suggest_componentsSuggest ComponentsA
Read-only

Suggest candidate components to record. Reads the symbol-graph in-degree (how often a chunk is called from the rest of the indexed code) and surfaces the most-called files that are not yet covered by an existing component card. Ranked by in-degree.

Use this when initialising the arch layer for a group (instead of guessing where the boundaries are) or after a large refactor to spot newly important modules. The tool only reads — it does not write component cards. Read each suggestion, decide whether it represents a meaningful architectural boundary (some high-degree files are utilities, not components), and call arch_record_component for the ones that do.

Optional project restricts suggestions to one project in the group. Optional limit (default 10, max 50) caps how many uncovered files to return.

NameRequiredDescriptionDefault
groupYesGroup to analyse.
limitNoOptional. Max suggestions to return. Default 10.
projectNoOptional. Restrict suggestions to one project in the group.

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false; the description reinforces this ('The tool only reads — it does not write component cards') and adds real context beyond annotations: the ranking signal is in-degree, already-covered files are excluded, and results are candidates requiring human/agent judgment rather than authoritative boundaries.

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

Conciseness4/5

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

Front-loaded with what the tool computes and how it ranks, then use-cases, then a caution, then parameters — a logical order with no filler sentences. Slightly longer than strictly necessary (the read-only point is stated twice across description and annotations), keeping it off a 5.

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?

No output schema exists, and the description implies the return shape (ranked list of uncovered high-in-degree files, capped by limit) and the decision workflow. That is sufficient for correct invocation, though the exact fields of a suggestion entry are left implicit.

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 group, project, and limit are already documented with types, bounds, and defaults. The description restates the limit default and max and clarifies that project scopes to 'one project in the group', but adds no new syntax or format meaning beyond the schema. Baseline 3 applies.

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?

States a specific verb and resource ('suggest candidate components to record') and precisely describes the mechanism: symbol-graph in-degree over indexed code, restricted to files not already covered by a component card. This is clearly distinguishable from siblings like arch_record_component and arch_list.

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

Usage Guidelines5/5

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

Gives explicit when-to-use triggers (initialising the arch layer for a group, after a large refactor) and contrasts with the alternative behaviour it replaces ('instead of guessing where the boundaries are'). It also spells out the follow-up action ('call arch_record_component for the ones you do') and warns that high-degree files may be utilities rather than components.

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

delete_projectDelete ProjectA
Idempotent

Delete all indexed data for a specific project: chunks from Qdrant, metadata from SQLite, and query cache. The project will be re-indexed on the next indexer cycle if configured. Use when a project's index is corrupted or stale.

NameRequiredDescriptionDefault
groupYesGroup name (collection) the project belongs to
projectYesProject name to delete

TDQS

A4.3/5.0
Behavior4/5

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

Beyond the annotations (readOnlyHint=false, idempotentHint=true, openWorldHint=false), the description adds valuable behavioral context: exactly what data is destroyed across three stores, and that the project will be re-indexed on the next cycle if configured, which clarifies reversibility. It does not discuss permissions or confirmation requirements, but it adds substantial concrete detail for a mutation 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 three tightly packed sentences with zero waste: scope first, recovery behavior second, usage guidance last. Every sentence earns its place and the most important destructive detail is front-loaded.

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 two-parameter mutation tool with no output schema and annotations that already cover safety characteristics, the description provides everything an agent needs: precise destruction scope, recovery behavior, and a usage trigger. Nothing material is missing for correct 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%, and the two parameters (group and project) are already fully documented in the schema. The description only refers generally to a 'specific project' and adds no syntax or format details beyond what the schema provides, so 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 verb ('Delete'), a precisely scoped resource ('all indexed data for a specific project'), and enumerates the underlying stores affected: Qdrant chunks, SQLite metadata, and query cache. This clearly distinguishes it from sibling delete tools such as term_delete and arch_delete, which target different resources.

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 explicitly says to use this tool when a project's index is corrupted or stale, giving a clear triggering condition. It does not name alternative tools or state when not to use it, so it falls short of the explicit alternatives expected for a 5.

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

find_usagesFind UsagesA
Read-only

Find symbol relationships: what calls this code, and what this code calls. Supports incoming (callers), outgoing (dependencies), or both directions. Use after search_code or get_chunk when the user asks 'where is this used?', 'what calls this?', or 'what does this depend on?'. Pass chunk_id from search results.

NameRequiredDescriptionDefault
limitNoMax results per direction
chunk_idYesChunk ID to find usages of
directionNoincoming = who calls this chunk, outgoing = what this chunk calls, both = both directionsincoming
include_hubsNoWhen true (default) callers/callees whose own degree is above the group p95 are surfaced with a `[hub]` marker so the agent knows the link is noisy. Set false to drop hub neighbours entirely — useful when probing a specific path through the codebase.
relation_typesNoFilter by relation types (default: all)

TDQS

A4.4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds directional semantics and the notion that links can be 'noisy', but it never describes the shape of the response or how results are presented, which matters since there is no output schema. Some value added, but not rich behavioral context.

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?

Four tight sentences, front-loaded with the core capability, then invocation guidance. No filler or repetition of title/name.

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 full schema coverage and no output schema, the description covers purpose, directions, and workflow sufficiently to call it correctly. The main residual gap is what a returned usage record looks like, which the description leaves to inference.

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, and the description earns an extra point by explaining what the directions mean in prose and telling the agent to pass chunk_id from prior search results. It maps call semantics onto parameters rather than restating them.

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?

States a specific verb and resource ('Find symbol relationships: what calls this code, and what this code calls') and immediately distinguishes the two directions. An agent can tell this apart from search_code/get_chunk without opening the schema.

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

Usage Guidelines5/5

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

Explicitly says when to use it ('Use after search_code or get_chunk') and quotes the user utterances that should trigger it ('where is this used?', 'what calls this?'). It also names the prerequisite source for the required parameter, leaving nothing to inference.

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

get_chunkGet ChunkA
Read-only

Get a code chunk by ID with optional surrounding context. Returns code with symbol definitions and usage info. Use to expand on search results.

NameRequiredDescriptionDefault
chunk_idYesChunk ID from search_code results
radius_linesNoLines of surrounding context to include (0-200)

TDQS

A3.8/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds useful value by saying what comes back (code with symbol definitions and usage info), but says nothing about truncation, size limits, or behavior at large radius_lines values.

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 short sentences, front-loaded with the core action, followed by the return shape and usage hint. Nothing is wasted.

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?

No output schema exists, and the description compensates by summarizing the return content. For a two-parameter read tool with full schema coverage and annotations, this is nearly complete; only edge-case behavior for large radii is absent.

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 both parameters are already documented including the 0-200 range and the search_code provenance of chunk_id. The description only restates the existence of optional surrounding context, adding no syntax or tradeoff detail beyond 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 ('Get a code chunk by ID') plus the optional surrounding-context capability and what the response contains. It is clearly distinct from siblings like search_code and find_usages, though the differentiation is implied through the description rather than an explicit naming.

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?

'Use to expand on search results' gives clear context for when to reach for this tool, reinforced by the schema note that chunk_id comes from search_code results. No explicit when-not guidance or naming of an alternative, so it stops 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.

health_checkHealth CheckA
Read-only

Check indexing status: number of indexed chunks per group.

Use to verify projects are indexed before searching or debugging empty results.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds value beyond that by disclosing what the tool actually returns (per-group indexed chunk counts) and framing it as a pre-search verification step, though it doesn't explain what a 'group' is or how failures/zero counts present.

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 short lines, zero waste: the purpose and output content come first, the usage condition second. 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 zero-parameter, read-only, no-output-schema tool, the description covers purpose, return content, and invocation timing. It is slightly thin on return shape and the 'group' vs 'projects' terminology is used interchangeably, which could confuse an agent interpreting results, but the essentials are 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 takes zero parameters, which is the baseline-4 case. Nothing about the schema needs compensating for in the description.

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 — 'Check indexing status' — and specifies the payload ('number of indexed chunks per group'), so the agent knows exactly what diagnostic data comes back. It does not name a sibling or explicitly contrast itself with search_code/list_projects, leaving differentiation to inference.

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?

Gives concrete triggering conditions: verify indexing before searching, or debug empty results. It offers clear context but no explicit exclusions or named alternatives, so there is room left for an agent to guess at edge cases.

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

list_projectsList ProjectsA
Read-only

List all indexed projects with metadata: chunk count and languages per project, grouped by collection. Use when the user asks 'what projects are indexed?', 'which repos are available?', or 'show me all projects'. Optionally filter by group name.

NameRequiredDescriptionDefault
groupNoSpecific group name, or omit to list all groups

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds useful context about result shape (grouped by collection, per-project metadata) but says nothing about pagination, ordering, or handling of empty results.

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?

Front-loaded with the core action and return content, followed by concrete usage triggers and the optional filter. No wasted sentences.

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?

With no output schema, the description compensates by naming the returned metadata and grouping structure. For a zero-required-param read-only list tool, an agent has everything needed to invoke it 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% and the single `group` param is already documented as 'omit to list all groups'. The description restates the optional filtering behavior without adding syntax or edge-case semantics, so the baseline 3 applies.

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?

States a specific verb+resource (list indexed projects) and specifies what metadata is returned (chunk count, languages, grouped by collection). This clearly distinguishes it from siblings like delete_project, search_code, or arch_list.

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?

Gives explicit trigger phrases ('what projects are indexed?', 'which repos are available?') and the optional group filter. It doesn't name an alternative sibling for cases where the user wants search rather than enumeration, 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.

search_codeSearch CodeA
Read-only

REQUIRED — call this FIRST for ANY code question.

Semantic code search across all indexed projects. Returns relevant code chunks ranked by confidence score with symbol definitions and usages.

Triggers (call this when the user asks about): code location, implementation, "how X works", "how many X", "what versions of X", "count X", "list X", patterns, flows, error handling, auth, API usage, or ANY reference to project code.

WHY: Returns only relevant chunks (50-90% fewer tokens vs full files). Searches by meaning, not just keywords.

WORKFLOW: Search first → evaluate scores → get_chunk for details → find_usages for dependencies.

Project names are directory basenames, not org/repo format. Example: "billing" not "org/billing".

NameRequiredDescriptionDefault
groupNoSpecific group or omit for all
limitNoMax results
queryYesNatural language query or code snippet
projectNoProject name or "all"all

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, and the description adds real behavioral context beyond that: results are meaning-ranked chunks with confidence scores, coverage spans all indexed projects, and cost is claimed 50-90% lower than reading full files. The one blemish is the coercive 'REQUIRED — call this FIRST for ANY code question' framing, which risks over-invocation and adds no descriptive information.

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

Conciseness4/5

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

Well front-loaded: the imperative, then scope, then triggers, then rationale, then workflow, then the naming caveat — an agent reading only the first line still routes correctly. Slightly verbose: the trigger list is long and its final clause ('or ANY reference to project code') subsumes everything enumerated before it, and the WHY/token-savings section reads as advocacy rather than specification.

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 four-parameter read-only search with no output schema, the description covers return format, ranking semantics, scope, and the downstream chain, so an agent can call it correctly. Remaining gaps are minor: no guidance on what a confidence score threshold looks like in practice or how 'group' interacts with 'project' filtering.

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, but the description earns an upgrade by clarifying project naming: directory basenames, not org/repo form, with a concrete example ('billing' not 'org/billing') — a convention the schema's 'Project name or "all"' does not convey. The group parameter and limit bounds are left entirely to 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?

States a specific verb and resource — semantic code search across all indexed projects — and immediately defines the return shape (ranked code chunks with symbol definitions and usages). The workflow sentence positions it as the entry point ahead of get_chunk and find_usages, so an agent can tell where it sits relative to siblings without opening any schema.

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

Usage Guidelines5/5

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

Explicitly says when to call it ('call this FIRST for ANY code question') and enumerates trigger intents: location, implementation, how-X-works, counts, versions, patterns, flows, error handling, auth, API usage. It also hands off explicitly: search → evaluate scores → get_chunk for details → find_usages for dependencies, which names the alternatives and the condition selecting each.

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

search_docsSearch DocumentationA
Read-only

Hybrid (dense semantic + BM25 keyword) search over indexed markdown documentation, fused with RRF. Returns EXCERPTS, not whole documents: each hit is the best-matching passage plus its neighbouring sections, carrying the document title, heading breadcrumb, project, file, and source link when available. When a hit covers only part of its document an Excerpt: line says which sections you got and how many exist — read the named file directly when you need the rest, because the passage may not be the document's full answer. The top hit is usually right but not always; scan the alternatives before concluding. Use for questions answered by prose docs (runbooks, RFCs, onboarding, business docs), not code. For code use search_code. Optional audience restricts results to visibility labels (e.g. ["internal"], ["client","public"]); omit to search every audience the endpoint is allowed to see. Some deployments enforce an audience ceiling — there, audience can only narrow within it, never widen past it. Results are filtered by a semantic-similarity floor, so a question the corpus does not cover returns nothing rather than the nearest unrelated page; treat an empty result as "not documented". Two floors apply: min_score (default 0.45) for long-form prose, and min_score_code (default 0.6) for markdown that ships inside code repositories (README, CLAUDE.md, design notes) — those are written as overviews and score deceptively well against questions they do not answer, so they are held to a stricter bar. A Last updated ... ago line marks a document untouched for over a year: docs checked in beside code go stale quietly, so prefer a recent source when they disagree, and verify against the code before relying on it. Absence of that line means recent OR unknown age, not verified-current. The reported score is a fusion rank, not a similarity — use it to order hits, not to judge how good a match is.

NameRequiredDescriptionDefault
groupNoSpecific group, or omit to search all known groups.
limitNoMax results. Default 8.
queryYesNatural-language documentation query.
projectNoRestrict to a single project (directory basename), or omit for all.
audienceNoRestrict to these visibility labels (e.g. ["internal"], ["client","public"]). Omit to search every audience this endpoint is allowed to see. Un-labelled docs count as "internal". If the server enforces an audience ceiling, this can only narrow within it, never widen past it.
min_scoreNoRelevance floor as a semantic cosine (default 0.45). Hits below it are dropped, so a question the docs do not cover returns nothing instead of the closest unrelated page. Raise toward 0.6 to demand near-exact matches; pass 0 to disable. Applies to long-form prose docs; markdown that ships inside code repositories uses min_score_code instead.
min_score_codeNoRelevance floor for markdown that lives in code repositories (README, CLAUDE.md, design notes), default 0.6. Higher than min_score because such files are written as overviews and score deceptively well against questions they do not answer. Pass 0 to disable for this kind only.

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the readOnlyHint and openWorldHint annotations, the description explains that results are excerpts rather than whole documents, how excerpt boundaries work, that scoring is a fusion rank not a similarity, and that semantic floors can produce empty results. It also discloses audience-ceiling behavior, stale-document indicators, and when to verify against code.

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

Conciseness4/5

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

The description is front-loaded with the key purpose, return shape, and sibling alternative, and nearly every sentence carries useful caveats. It is dense and long for a single paragraph, but the length is largely justified by the complexity of the search behavior.

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 complex search tool with no output schema, the description covers return format, excerpt limitations, audience filtering, relevance floors, score interpretation, stale-document handling, and empty-result meaning. An agent has enough information to invoke and interpret the tool 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 schema already defines all seven parameters. The description still adds useful operational context for audience restrictions and the two relevance floors, especially why markdown in code repositories uses a stricter threshold, though much of this overlaps the schema text.

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: hybrid dense semantic plus BM25 keyword search over indexed markdown documentation. It explicitly distinguishes the tool from search_code, making sibling selection clear without needing to inspect schemas.

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

Usage Guidelines5/5

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

It says exactly when to use this tool for prose documentation and when to use search_code for code. It also gives operational guidance: scan alternatives before concluding, treat empty results as undocumented, and read the named file when an excerpt is partial.

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

term_deleteDelete Glossary TermA
Idempotent

Hard-delete a glossary term by id. No undo. Use to remove obsolete or wrong terms.

NameRequiredDescriptionDefault
idYesTerm id to delete.
groupYesGroup the term lives in.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations declare readOnlyHint=false and idempotentHint=true, and the description adds the key trait not covered there: 'No undo' — irreversibility. It does not say what happens to references or usages of the term (find_usages exists as a sibling), which is the one behavioral gap for a destructive 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 very short sentences, zero filler, with the destructive nature and irreversibility front-loaded before the usage hint. Nothing repeated from annotations or 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?

For a two-parameter, non-open-world mutation with full annotation coverage and no output schema, the definition covers what is needed to call it safely. The only missing piece is the downstream effect on anything referencing the deleted term.

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?

Both parameters are already fully documented in the schema (100% coverage) with per-field descriptions for id and group. The description adds only 'by id', not clarifying the group scoping or whether group/id must match an existing pair. Baseline 3 is appropriate when the schema does the work.

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?

States a specific verb and resource ('Hard-delete a glossary term by id') with an explicit qualifier ('Hard') that separates it from soft-removal or edit operations. An agent can distinguish it from siblings like term_record, term_list and term_search without opening any schema.

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?

'Use to remove obsolete or wrong terms' gives a clear condition for selecting this tool. It stops short of naming alternatives (e.g. term_record for renaming or deprecating instead of deleting) or stating prerequisites, so it is clear context without exclusions.

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

term_listList Glossary TermsB
Read-only

List recorded glossary terms in a group (optionally scoped to a project). Use to audit coverage or review what terminology has been captured.

NameRequiredDescriptionDefault
groupNoSpecific group, or omit for all groups.
limitNoMax terms. Default 200.
projectNoRestrict to a project, or omit for all.

TDQS

B3.2/5.0
Behavior2/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is settled. The description adds nothing beyond that: no ordering, no pagination/truncation behavior beyond the schema's limit cap, no indication of what a term record contains, and no statement that empty groups return an empty list.

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

Conciseness4/5

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

Two compact sentences with the operation stated first and the purpose second; nothing is redundant. It could be tightened slightly by merging the scope and use-case into one clause, but there is no padding.

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 simple read-only listing tool with full schema coverage and annotations, the essentials are present. However, with no output schema, the description should have said what a listed term looks like (name, definition, project) so the agent knows what it gets back.

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% and each of the three parameters is documented in the schema, including defaults and max limits. The description corroborates group and project scoping but adds no format hints or guidance beyond the schema, so the baseline 3 applies.

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 ("List recorded glossary terms") plus scoping by group and optional project, which is enough to distinguish it from a search or write tool. It does not explicitly contrast with the sibling term_search, so it falls short of a 5.

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?

"Use to audit coverage or review what terminology has been captured" gives an intended scenario but no exclusions or alternatives. An agent facing both term_list and term_search is left to infer that list is for enumeration and search is for lookup.

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

term_recordRecord Glossary TermA
Idempotent

Record a glossary term (canonical name, definition, aliases, optional project scope). Goes through a duplicate/similar gate like arch_record_decision: if a near-identical term already exists it is returned instead of writing a duplicate — reconcile by updating that term. Authored by the agent as it learns domain vocabulary, or in bulk via the extract-terminology skill.

NameRequiredDescriptionDefault
termYesThe canonical term, e.g. "feed-poster".
groupYesGroup the term belongs to.
aliasesNoAlternate spellings / abbreviations.
projectNoProject scope, or omit for group-wide.
definitionYesPlain-language definition.

TDQS

A4.1/5.0
Behavior4/5

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

Adds meaningful behavior beyond the annotations: a duplicate/similar gate returns the existing near-identical term instead of writing, and advises reconciliation via update. This complements idempotentHint=true with concrete mechanism, though it doesn't state what a successful write returns.

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

Conciseness4/5

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

Front-loads the core action and field list, then explains the duplicate gate and provenance in a compact follow-up. Dense but each clause carries information; no padding.

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 write tool with full annotation and schema coverage, the description covers the duplicate-gate behavior and authoring workflow, which are the non-obvious aspects. Only the success return value is unaddressed, which is minor given no output schema exists.

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 five parameters are documented in the schema. The description only restates field purposes (canonical name, definition, aliases, project scope) without adding syntax or format detail beyond the schema, so baseline 3 applies.

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?

States a specific verb (record) and resource (glossary term) and enumerates the content fields, so it is clearly distinguishable from term_search, term_list, and term_delete among the siblings.

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?

Gives clear usage context: authored by the agent as it learns domain vocabulary, or in bulk via the extract-terminology skill. It also explains what to do when a near-identical term exists (reconcile by updating that term), though it does not explicitly name the sibling update/search tool to use.

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. 18 tool updatesv0.1.0
    • First observedarch_context
    • First observedarch_delete
    • First observedarch_list
    • First observedarch_record_component
    • First observedarch_record_decision
    • First observedarch_record_lesson
    • First observedarch_suggest_components
    • First observeddelete_project
    • First observedfind_usages
    • First observedget_chunk
    • First observedhealth_check
    • First observedlist_projects
    • First observedsearch_code
    • First observedsearch_docs
    • First observedterm_delete
    • First observedterm_list
    • First observedterm_record
    • First observedterm_search

TDQS

A3.9/5.0

Scored across 18 tools

Disambiguation4/5

The three tool families (code search, glossary, arch memory) are clearly separated, and the pairings that could collide — search_code vs search_docs, get_chunk vs find_usages, arch_context vs arch_list, term_search vs term_list — are explicitly distinguished in their descriptions (ranked retrieval vs ground-truth enumeration, chunks vs prose, symbol graph vs glossary). The only mild residual overlap is term_search vs search_docs for domain questions, but the guidance ('glossary first for acronyms') resolves it. An agent should reliably pick the right tool.

Naming Consistency3/5

All names are snake_case, but the ordering convention flips between verb_noun (search_code, get_chunk, find_usages, list_projects, delete_project, health_check) and noun_verb (term_search, term_record, arch_context, arch_list, arch_delete, arch_record_component). The prefix-grouping is readable and even praiseworthy for discoverability, yet inconsistent with the search/code family. Readable overall, but not a single predictable pattern.

Tool Count4/5

18 tools spans three genuinely distinct sub-domains (semantic code search, glossary, architectural memory), so the count is roughly proportional rather than padded. Still, it sits at the top of the comfortable range, and the seven arch_* tools plus four term_* tools make the surface heavier than a pure search server would need. Slightly over a lean ideal but each tool maps to a real operation.

Completeness4/5

Glossary (record/search/list/delete) and arch memory (record/list/context/delete/suggest) have near-full lifecycles, and code search covers discovery, expansion, and dependency tracing. The notable gap is indexing control — there is no reindex/refresh tool, only delete_project with a note that re-indexing happens on the next cycle — and term updates are only implicit through the duplicate gate. Workarounds exist, so nothing is a dead end.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    A fully featured coding agent that uses symbolic operations (enabled by language servers) and works well even in large code bases. Essentially a free to use alternative to Cursor and Windsurf Agents, Cline, Roo Code and others.
    29
    35,035 PyPI
    30,830
    GPL 3.0
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides semantic code search capabilities that run 100% locally using EmbeddingGemma embeddings. Enables finding code by meaning across 15 file extensions and 9+ programming languages without API costs or sending code to the cloud.
    238
    -