mcp-code-indexer
This server lets you manage and semantically search local code projects through MCP tools.
Register a project directory and start background indexing with
add_projectDeregister a project and delete its index with
remove_projectList all registered projects and their index summaries with
list_projectsRun semantic searches (with automatic staleness check and incremental re-indexing) via
semantic_searchCheck indexing state/progress with
index_statusForce a full rebuild of a project's index with
reindex_project
Uses a LAN-local Ollama instance for generating code embeddings (default qwen3-embedding:8b, 4096-dim), enabling semantic indexing and search of local project directories.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-code-indexersearch my ~/code/api project for where auth tokens get validated"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
code-indexer
Semantic code index over Ollama + Qdrant, with two entry points over the
same core (code_indexer.core): an MCP stdio server (code-indexer-mcp)
for agent use, and a one-shot CLI (code-indexer) for shell/scripts. The MCP
server keeps an automatic semantic index of one or more local project
directories in Qdrant, using Ollama (qwen3-embedding:8b, 4096-dim) for
embeddings. Fully LAN-local; no cloud.
Agents never index anything themselves. They only call semantic_search
(which transparently runs a staleness check + incremental indexing first) plus
a few admin tools. Chunks, hashes, and collections are never exposed.
Installation (CLI)
From the repo directory, install both executables as editable uv tools (on
PATH in ~/.local/bin, edits to the checkout take effect immediately):
uv tool install -e .This installs code-indexer (and the optional code-indexer-mcp server
executable). Verify with code-indexer list-projects.
Related MCP server: ollqd
CLI
code-indexer add-project /path/to/repo [--name myproject]
code-indexer lookup-project /path/to/repo
code-indexer list-projects
code-indexer semantic-search "auth token refresh" --project /path/to/repo --limit 8 [--json]
code-indexer find-symbol FileTransferSession [--symbol-type class]
code-indexer find-definition main
code-indexer find-references QTimer --relationship calls
code-indexer get-code-context src/session.hpp --start-line 40 --end-line 80
code-indexer index-status /path/to/repo
code-indexer reindex-project /path/to/repo
code-indexer remove-project /path/to/repo
code-indexer watch /path/to/repo [--duration 300] [--background] # optional inotify watcher
code-indexer watch --all # watch all registered projectsEvery subcommand accepts --skip-stale-check to skip the staleness probe /
incremental index pass on that invocation (startup-cost opt-out; there is no
daemon on the default path). CLI subcommands and MCP tools map 1:1 to core
operations.
find-symbol, find-definition, find-references, and get-code-context
accept both --project X and --name X for the project argument (path,
slug, or registered custom name).
watch (optional, opt-in)
code-indexer watch [PATH...] | --all [--duration T] [--background] runs a
long-lived event-based watcher: project roots are watched recursively
with Linux inotify (the watchdog Observer library, opt-in watch
dependency-group — the MCP server and one-shot commands never import it).
A file event schedules an incremental pass after a quiet period of
WATCH_DEBOUNCE seconds (default 3 — the old poll tick is now the
debounce; the env alias WATCH_QUIET_PERIOD is accepted and wins). A
burst of events coalesces into at most one pass per quiet period, and an
event burst that changes no content costs a hash scan only — zero
embedding, zero Qdrant traffic.
Self-heal sweep: a full staleness pass for every watched project runs every
WATCH_SWEEP_INTERVALseconds (default 300 s) even with zero events, healing anything inotify missed.Degradation: without watchdog installed, or if inotify watch descriptors are exhausted (OSError scheduling the recursive watches), the watcher falls back to quiet-period polling (one hash scan per project per quiet tick) — correctness is never lost, only latency.
Self-write suppression: events under the index root,
.gitpaths, and editor temp files (.swp,~,.tmp, ...) are filtered; the watcher's own manifest/registry writes never trigger a pass.Moved/deleted dirs: directory delete/move events dirty the project (a wholesale file-set change), so deletions are purged on the next pass.
--duration Tbounds the watcher's life (exit 0 after T seconds;0or omitted = forever; applies to background mode too). SIGINT/SIGTERM exit 0; the kernel flock is released automatically.Multiple projects are served round-robin: repeatable path/slug/name args, or
--allfor every registered project (registry order). Never combine paths with--all.--backgrounddaemonizes (double-fork + setsid), writes the daemon PID to<INDEX_ROOT>/watch.pidguarded by anflockon that file (a second watcher is refused while a live one holds it — the flock, not the pid, is the liveness test), and redirects stdout/stderr to<INDEX_ROOT>/watch.log.--foreground(default) keeps the inherited stdio and normal output and does not take the pidfile. A stopped watcher leaves no live lock or PID residue (the pidfile is unlinked only after the flock is released).Opt-in and never a prerequisite: without a watcher, one-shot commands behave exactly as before (STALE_TTL probe per invocation).
Tools (MCP)
Tool | Description |
| Register a project directory; creates the Qdrant collection and starts a full initial index in the background. Idempotent: re-adding an already-registered path returns the current index status summary (state, files, chunks, last_indexed) and does NOT spawn a re-index — only nonexistent paths error. Optional |
| Check registration without side effects: returns one line with path, slug, custom name, Qdrant collection name ( |
| Deregister and delete the Qdrant collection, SQLite manifest, and registry entry. |
| Registered projects with file/chunk counts, last-indexed time, and state. |
| The hot path. Always runs a staleness check first; |
|
|
| Force a full rebuild. |
| Look up symbols by name in the manifest symbol index (no semantic search). Exact AST-first, capped substring fallback. |
| Where a symbol is declared (exact name match only, no substring). |
| Textual references TO a symbol (all confidence=heuristic). |
| Retrieve ONLY the relevant source lines — by line range ( |
MCP project parameters accept a path, slug, or registered custom name
(equivalent to the CLI's --project X / --name X). There is no MCP watch
tool: a watcher makes no sense inside an MCP server that is already
long-lived — watch is CLI-only.
How indexing / staleness works
First index (
add_project) runs on a background thread; the tool returns immediately. Useindex_statusto wait for completion.Staleness check (on every
semantic_search/index_status): if the project hasn't been scanned withinSTALE_TTLseconds (default 60), the server re-scans file hashes and incrementally re-indexes only what changed. Answers are never served from a stale index by more than one scan interval.Incremental diff: files are classified
unchanged/changed/added/deletedby content hash (sha256 — not mtime, which lies after branch switches). Only chunks whose own hash changed get re-embedded; point IDs are deterministic (uuid5(project|file|chunk_index)), so upserts are idempotent. Deleted files are purged from Qdrant by payload filter and dropped from the SQLite manifest.Chunking: tree-sitter AST units (function/class-level, with symbol names) via
tree-sitter-language-pack, falling back to a ~80-line regex window chunker with 10-line overlap when a language is unsupported or the parse fails. Chunks are capped at ~1000 chars.Filtering: honors
.gitignoreand.codeindexignore(nested, per- directory), skips.git/node_modules/venv/__pycache__/dist/build/target, files > 1 MB, and binary/non-UTF-8 files.Concurrency: multiple processes (multiple agents, CLI + server) are safe — per-project
flocklock files (fcntl.flock(LOCK_EX|LOCK_NB); BlockingIOError reports "indexing in progress"; the kernel releases the lock automatically when a process dies, so there is no stale-lock stealing and lock files are permanent), WAL-mode SQLite withbusy_timeout, idempotent point IDs. Two processes indexing the same project at once is wasteful, not corrupting: the flock serializes them to exactly one pass.
Upgrading from mcp-code-indexer
Upgrading from the old mcp-code-indexer repo/server: run code-indexer add
for each project; existing idx_* collections are reused, no reindex
required. The default state directory moved from ~/.mcp-code-indexer to
~/.code-indexer — the new registry starts empty (an undocumented reset, not
a migration), so re-registering with the same custom names (--name) that
the old projects used reattaches to the already-existing Qdrant collections.
Re-run reindex-project once per old project to populate its symbol index
(pre-schema-v2 manifests have no symbol rows).
State layout
$INDEX_ROOT/ (default ~/.code-indexer)
├── registry.db # path -> slug mapping (SQLite, WAL)
├── <slug>.lock # per-project lock
├── <slug>/manifest.db # per-project file manifest (SQLite, WAL)
├── watch.pid # flock-guarded watcher PID file (--background only)
└── watch.log # watcher daemon stdout/stderr (--background only)Qdrant holds one collection per project: idx_{slug} where slug is an 8-hex
hash of the absolute path — or idx_<name> when the project was registered
with a custom name.
Configuration
Resolution order: CLI flags > environment variables > defaults.
Env var | Default | Description |
|
| Ollama base URL |
|
| Qdrant base URL |
|
| Embedding model |
|
| State directory |
|
| Seconds between staleness re-scans |
|
|
|
| — | alias for |
|
|
|
|
| Texts per Ollama embed request |
|
| Points per Qdrant upsert |
|
| Skip files larger than this |
CLI flags: --ollama-url, --qdrant-url, --embed-model, --index-root.
MCP client config (Claude Desktop / Hermes / any stdio MCP client)
{
"mcpServers": {
"code-indexer": {
"command": "uv",
"args": [
"--directory", "/path/to/code-indexer",
"run", "code-indexer"
],
"env": {
"OLLAMA_URL": "http://192.168.X.X:11434",
"QDRANT_URL": "http://192.168.X.X:6333"
}
}
}
}Performance note
Embedding throughput depends on the Ollama host: measured ~1.2 docs/s with GPU passthrough (8B model, 4096-dim, batch 48) vs ~0.17 docs/s CPU-only. The first index of a large repo is the slow part (thousands of chunks); incremental updates only re-embed changed chunks, so a typical edit session re-indexes in seconds-to-minutes. Qdrant upsert throughput is ~550 pts/s. Embeddings are batched (one HTTP round trip per 48 inputs) with keep_alive to avoid model unload between batches.
Development
uv sync # install deps (.venv)
uv run code-indexer-mcp # run the stdio MCP server
uv run code-indexer list-projects # one-shot CLI (no daemon)
uv run pytest # unit + concurrency tests
# (old dev/audit scripts under scripts/ were removed with the rename; the
# live e2e coverage now lives in tests/, scripts/live_smoke.py in vector-memory)Python 3.11. Constraints: pins numpy<2 (1.26.4), qdrant-client<1.15,
mcp<2, tree-sitter==0.26.0, tree-sitter-language-pack==1.18.0
(older x86-64 CPUs without x86-64-v2; all pure/prebuilt wheels).
Available Tools
6 toolsadd_projectA
Register an absolute project directory for semantic indexing.
Creates the Qdrant collection and starts a full initial index in the
background (check progress with index_status). Errors if the path does
not exist or is already registered.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden and does meaningfully discharge it: it discloses side effects (creates a Qdrant collection, kicks off a background initial index) and two failure conditions. It stops short of describing idempotency, permissions, or what happens if indexing fails partway.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences with the core action front-loaded, followed by side effects and then error conditions. No filler or restatement of the tool name.
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?
An output schema exists, so return values need no explanation, and the description covers the mutation's side effects and error cases. For a no-annotation write tool it is nearly complete, missing only permissions/auth requirements.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter has 0% schema description coverage, so the description must compensate. It adds real meaning by specifying the path must be an absolute project directory and must already exist, though it gives no format examples or edge-case handling.
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?
Specific verb ('Register') plus resource ('absolute project directory') plus domain ('semantic indexing'). It clearly distinguishes itself from siblings like remove_project, list_projects, and reindex_project.
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?
Names a sibling for follow-up ('check progress with index_status') and states two preconditions that cause errors (path missing, already registered). It does not explicitly contrast with reindex_project, which the 'already registered' clause implies but never names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
index_statusA
Check indexing state for a project: idle | indexing | stale | error, plus last-pass progress. Also triggers the staleness check.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so the description carries full burden. It discloses the interesting side effect – the tool also triggers the staleness check – which is behavior beyond a pure read. However it doesn't say whether this mutates state, whether it's safe to call repeatedly, or cost/latency implications of triggering a check.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two terse sentences, front-loaded with the outcome space; every clause earns its place and the enum-like state list is immediately scannable.
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?
Output schema exists so return value needn't be explained, and the description covers states plus the side effect. But the undocumented 'path' param and unstated mutation/reversibility of the staleness trigger leave the agent with unanswered questions for a tool that does more than read.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% with one required param ('path') left undocumented. The description implies a project scope but never says the param identifies the project by path, and gives no format guidance. Baseline 3 given the single-param simplicity, but a gap remains.
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?
Specific verb (Check) and resource (indexing state for a project), and enumerates the four possible states. It is distinguishable from siblings like reindex_project (which mutates) and list_projects, though it doesn't explicitly name alternatives.
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?
Usage is implied: check status before/after indexing or when results seem stale. No explicit when-to-use, when-not-to-use, or alternative routing is given, so the agent must infer context from the sibling set.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_projectsA
List registered projects with per-project index summary and staleness.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It does disclose that results carry an index summary and staleness flag, which tells the agent something about the shape and freshness semantics of the output. It does not state that the operation is read-only/non-mutating, nor anything about pagination or scoping, so it is only partially transparent.
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?
One sentence, no filler, with the resource and the returned information front-loaded. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and with zero parameters the schema side is fully covered. For a simple list tool the description is nearly complete, missing only explicit routing versus its sibling listing/inspection tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to clarify; the schema is trivially complete. Baseline 4 applies since no parameter explanation is possible or needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('registered projects') and goes further by naming the payload contents (per-project index summary and staleness). That distinguishes it from index_status and reindex_project, though it never names those siblings explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No indication of when to prefer this over index_status or semantic_search, and no prerequisites or ordering advice. The tool's read-only nature is only implied by the verb 'List'; the agent must infer all usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reindex_projectA
Force a full rebuild of a project's index (chunker/model change, suspected corruption).
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the disclosure burden. It does indicate this is a 'force full' destructive-ish rebuild scoped to a project, which is meaningful, but it omits whether the operation is blocking, whether it can run while the project is in use, or reset semantics.
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?
One tight sentence with no waste; the operation is front-loaded and reasons are compactly delivered in a parenthetical.
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?
Output schema exists, so return values needn't be explained. However, with no annotations, a destructive full rebuild, and ambiguous 'path', the description should say more about safety and what 'path' means to be 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?
Only one parameter (path) with 0% schema description coverage. The description does not clarify what 'path' refers to (project root, project id, config path). With a single parameter the baseline is 4 per rules, but the ambiguous 'path' semantics and absent description warrant a modest downgrade to 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (force full rebuild) and resource (project's index), and parenthetically gives the precise conditions that motivate it. Clearly distinguishable from siblings like add_project or semantic_search.
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 parenthetical lists trigger conditions (chunker/model change, suspected corruption), which is explicit when-to-use guidance. It lacks any when-not-to-use or named alternative, 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.
remove_projectA
Deregister a project and DELETE its Qdrant collection + manifest + registry entry entirely.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does well by naming exactly what is destroyed (collection, manifest, registry entry) and signaling irreversibility via 'DELETE ... entirely'. It omits permission/auth requirements and behavior when the project does not exist or is already removed.
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?
One tightly written sentence with the destructive action and its full blast radius front-loaded. No 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?
An output schema exists so return values need not be described, and the destruction scope is covered. However, for an unannotated destructive tool the description should also address the undocumented path parameter and failure/idempotency behavior, which it does not.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description never mentions the single required 'path' parameter, so it adds no meaning about what path refers to or how it is resolved. The bare parameter name is the only clue available.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('deregister') and resource (project) with an explicit scope that enumerates exactly what is torn down: Qdrant collection, manifest, and registry entry. This cleanly distinguishes it from siblings like add_project, list_projects, and reindex_project.
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 destructive language implies a caution context for use, but there is no explicit statement of when to choose this over reindex_project or list_projects, nor any prerequisite or confirmation guidance. Usage is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
semantic_searchA
Semantic code search across indexed projects. THE hot path.
Automatically runs a staleness check first and incrementally re-indexes
changed files, so results are always fresh (within one scan interval).
Args: query (natural language); project (optional path — omit to search
all registered projects); limit; file_filter (optional substring/glob
on file path, e.g. '*.py').
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes | ||
| project | No | ||
| file_filter | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and it discloses a significant hidden behavior: an automatic staleness check plus incremental re-indexing of changed files (a write side effect) with a stated freshness bound of one scan interval. It omits cost/latency, permission requirements, and failure behavior, which keeps it below a 5.
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?
Front-loaded with purpose and priority, followed by behavior and a compact Args block; almost every sentence earns its place. The Args list is terse rather than well-structured, and 'THE hot path' is stylistic, but nothing is wasted.
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?
An output schema exists, so return values need not be described. Given four parameters at 0% schema coverage, the description adequately documents param meaning and the key side-effect behavior, leaving only minor gaps (limit semantics, performance/error characteristics).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it explains three of four parameters: query (natural language), project (optional path, omit to search all), and file_filter (substring/glob with a '*.py' example). Only 'limit' is named without explanation, though its meaning is self-evident from the name and default.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Semantic code search across indexed projects'), which is unambiguous and clearly distinguishable from the sibling management tools (add/remove/list/index_status/reindex_project). An agent can identify this as the retrieval tool 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Signals primacy with 'THE hot path' and explains that it auto-reindexes, which implicitly tells the agent not to call reindex_project first. It also notes that omitting 'project' searches all registered projects, giving conditional usage guidance, though it never explicitly names alternatives or when-not-to-use conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.1.0- First observed
add_project - First observed
index_status - First observed
list_projects - First observed
reindex_project - First observed
remove_project - First observed
semantic_search
TDQS
Scored across 6 tools
Each tool has a clearly distinct purpose: add_project registers, remove_project deregisters, list_projects lists, semantic_search searches, index_status checks status, and reindex_project forces rebuild. No overlapping or ambiguous functions.
All tool names follow a consistent verb_noun pattern (add_project, remove_project, list_projects, semantic_search, index_status, reindex_project) with snake_case throughout.
Six tools perfectly cover the lifecycle of project management and indexing for a code indexer: add, remove, list, search, status, and reindex. No tool is extraneous or missing.
The tool set provides complete CRUD for projects (add, remove, list) plus essential operations for indexing and searching (semantic_search, index_status, reindex_project). This covers all core workflows for a code indexer.
Maintenance
Related MCP Connectors
Project memory, semantic code search, and grounded agent context.
Shared memory for coding agents. Stop re-explaining your codebase every session.
Give your AI agent a persistent map of your project's structure, dependencies, and bugs.
Code intelligence for coding agents: semantic, AST, graph, and full-text search. 279+ languages.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables semantic search across your codebase using Google's Gemini embeddings and Qdrant Cloud vector storage. Supports 15+ programming languages with smart code chunking and real-time file change monitoring.78 npm20MIT
- AlicenseAqualityCmaintenanceEnables indexing and semantic search of codebases and documents via MCP, using Ollama embeddings and Qdrant vector store.5Apache 2.0
- AlicenseNot gradedqualityFmaintenanceIndexes codebases into Qdrant for semantic search, enabling AI assistants to find relevant code by meaning without re-exploring the repo.MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI coding agents to perform semantic code search locally, finding code by meaning rather than exact keywords.3MIT