Skip to main content
Glama

golestan_code_mcp

A code context MCP server backed by Oracle AI Database 26ai. It indexes codebases into the database, cut at function and class boundaries. It searches them by name and by meaning, follows their calls, keeps a wiki page about each module, and remembers what earlier sessions learned. It serves all of it to AI coding tools such as Claude Code, Codex and Cursor over the Model Context Protocol (MCP), so an agent can find and understand code without reading whole files.

The idea was initiated by the article Coding Challenge #139 - Code Context from Coding Challenges. The project was developed with the help of GitHub Spec Kit: every feature went through a specification, a plan and a task list, kept in specs/.

It is free to use, change and share under the MIT License.

Features

  • Structure-aware indexing of 13 languages (Python, Go, JavaScript, TypeScript, C#, C, C++, Java, Kotlin, Rust, PHP, Ruby, Swift): one chunk per definition, with its exact lines and documentation. Re-ingesting only reads what changed.

  • Hybrid search: keyword and semantic matching fused in one database index, with each result's scores shown.

  • Code graph: callers, callees and the transitive impact of a change, as a SQL property graph.

  • Module wiki: one page per module, written from the index, with citations that follow the code and pages that are rewritten when it changes.

  • Agent memory: every tool call is recorded and distilled into facts a new session can recall.

  • Usage feedback: results that clients used rank a little higher, with a bounded, decaying boost.

  • Private by default: embeddings are computed inside the database, so no source code is sent out to be indexed and no API key is needed.

Related MCP server: code-graph-mcp

Quick start

You need Docker (tested with Rancher Desktop) with about 12 GB free, uv and git. The commands are run from the project root; Setup has the details and the PowerShell variants.

1. Configure and start the database. Copy .env.example to .env and replace both passwords. Then:

docker compose up -d
uv sync
uv run golestan-check-db       # waits for the first start, then checks the connection

2. Index a repository. Indexing explains what is read and how re-ingesting works.

uv run golestan-clone-samples                         # optional: flask and gin, into ../ccctx-repos
uv run ccctx repo add ../ccctx-repos/flask --name flask
uv run ccctx model load                               # once: the embedding model and the search index
uv run ccctx ingest flask

3. Search it. See Search and Code relationships.

uv run ccctx search "how are incoming requests routed to handlers"
uv run ccctx callers url_for
uv run ccctx wiki build --repo flask

4. Connect an AI coding tool. Install the command once, then register it. For Claude Code:

uv tool install --editable .
claude mcp add ccctx -- ccctx mcp

Any MCP client can start ccctx mcp the same way. The MCP server has the details.

Upgrading from 1.4.1 or earlier. The source moved from src/golestan_code_mcp/ to src/, so an existing install must be refreshed once: close the MCP clients that run ccctx (on Windows they keep ccctx.exe locked), then run uv sync and uv tool install --editable . --reinstall. Registrations stay as they are.

5. Run the tests. Database tests are skipped, with a reason, when the database is down.

uv run pytest

MCP tools

Tool

Answers

search_code

Find code, wiki pages and remembered facts by name or by meaning

get_symbol

The full source of a definition

find_callers

What calls a function or method

find_callees

What a function or method calls

impact_of

What could break if a definition changes

read_wiki

What a module does, from its wiki page

list_repositories

The indexed repositories

recall

What earlier sessions worked out

mark_used

Record that a result helped

Parameters, results and the change history are in The MCP server.

Documentation

  • Setup: prerequisites, the database, installing, checking that data persists

  • Indexing: registering and ingesting codebases, the languages and their limits

  • Search: search modes and ranking, usage feedback, evaluating retrieval

  • Code relationships: callers, calls and impact

  • Module wiki: the module pages, their citations and how they stay current

  • Agent memory: runs, facts, recall and the optional distilling model

  • The MCP server: the tools, registering clients, the change history

  • CLAUDE.md: commands, conventions and the file layout, for AI coding agents and contributors

License

MIT, see LICENSE.

Available Tools

9 tools
find_calleesA
Read-only

What does this call? Lists the indexed symbols called from the body of each definition matching name, with the line of each call and where the called symbol is defined (repository, path, line range). Use it to follow what a function does one level down; for who calls it, use find_callers. Calls into code that is not indexed, such as the standard library or dependencies, are not listed. At most 200 rows; truncated is true when more exist. Next step: get_symbol on a callee to read it.

NameRequiredDescriptionDefault
nameYesA bare name (url_for), which matches url_for and every Class.url_for, or a qualified name (Flask.url_for), which matches only that definition. Case-sensitive.
repoNoLook only in this registered repository, for example flask. list_repositories gives the valid names. Default: all repositories.

Output Schema

NameRequiredDescription
reasonYes
statusYes
resultsYes
truncatedNo

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true, so the safety profile is covered. Beyond that, the description adds substantive behavioral detail: non-indexed calls such as standard library or dependency calls are omitted, results are capped at 200 rows, and truncation is signaled via a truncated flag.

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 then covers scope, exclusions, limits, and next step in a compact sequence. Every sentence carries useful information, with no redundant restatement of the schema or annotations.

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 an output schema is present, the description need not specify return fields exhaustively, but it still summarizes the useful return shape (call line and callee location) and covers key constraints such as indexing scope and the 200-row truncation limit. This is complete enough 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.

Parameters3/5

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

Schema description coverage is 100%, so both parameters already have documented semantics, including bare vs qualified name matching and repo filtering. The description reinforces that results are for definitions matching name, but adds little parameter-level detail beyond the schema.

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

Purpose5/5

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

The description opens with a specific question that defines the operation, then states it lists indexed symbols called from each matching definition, including call line and callee definition location. It explicitly distinguishes itself from find_callers, so an agent can select the right directional traversal tool 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 usage guidance: use this to follow what a function does one level down, and use find_callers for who calls it. It also states the next step (get_symbol on a callee) and notes that calls into non-indexed code are excluded, leaving little ambiguity about when and how to use it.

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

find_callersA
Read-only

Who calls this? Lists every call to the definitions matching name: the calling symbol, its kind, the repository, path and line of the call, and which definition is called. Use it before changing a function's signature or behavior, to see its direct call sites. For everything a change could reach through chains of calls, use impact_of; for what this symbol itself calls, use find_callees. Calls come from the parse tree, so comments, docstrings and strings never count. A call at module level has kind file and name (module). At most 200 rows; truncated is true when more exist. Next step: get_symbol on a caller to read it.

NameRequiredDescriptionDefault
nameYesA bare name (url_for), which matches url_for and every Class.url_for, or a qualified name (Flask.url_for), which matches only that definition. Case-sensitive.
repoNoLook only in this registered repository, for example flask. list_repositories gives the valid names. Default: all repositories.

Output Schema

NameRequiredDescription
reasonYes
statusYes
resultsYes
truncatedNo

TDQS

A4.7/5.0
Behavior5/5

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

Annotations only declare readOnlyHint=true; the description adds substantial context beyond that: results come from the parse tree so comments/docstrings/strings never match, module-level calls are reported as kind 'file' with name '(module)', and results are capped at 200 rows with a 'truncated' flag. These are exactly the behavioral facts an agent needs before trusting or paging 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 question and the core behavior, then grouped into return fields, usage, sibling routing, a correctness caveat, limits, and next step. Every sentence carries distinct information with no redundancy.

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?

Output schema exists, yet the description still signals the row shape and truncation semantics; combined with explicit sibling routing and next-step guidance, an agent has everything needed to call it correctly and interpret the response.

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 both parameters (bare vs qualified name matching, repo scoping) are already fully documented in the schema. The description says only 'definitions matching name' and adds no matching syntax or repo semantics of its own, which is the expected baseline when the schema carries the load.

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?

Opens with a concrete question and a specific verb+resource ('Lists every call to the definitions matching name'), then enumerates exactly what each row contains. It explicitly names what it is not (impact_of, find_callees), so the agent can distinguish it from siblings without opening a 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?

States both when to use it ('before changing a function's signature or behavior, to see its direct call sites') and the two alternatives with the condition that selects each: impact_of for transitive reach, find_callees for outgoing calls. There is also a stated next step (get_symbol on a caller).

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

get_symbolA
Read-only

Read the full source of a named definition (function, method, class, type) when you know its name, for example from a search_code hit. Use this instead of search_code when the name is known, and instead of opening files: it returns the source exactly as it was indexed. A bare name returns every definition with that name, each labeled with its qualified name; pass a qualified name or a repo to narrow. Returns up to 5 matches, each with its qualified name, kind, repository, path, line range and source. A source longer than 400 lines is cut there and marked cut, and its full line range is still given. total is the number of matches and truncated is true when more than 5 matched. Unparsed files indexed as line windows have no names and are not found here; use search_code for them.

NameRequiredDescriptionDefault
nameYesA bare name (url_for), which matches url_for and every Class.url_for, or a qualified name (Flask.url_for), which matches only that definition. Case-sensitive.
repoNoLook only in this registered repository, for example flask. list_repositories gives the valid names. Default: all repositories.

Output Schema

NameRequiredDescription
totalNo
reasonYes
statusYes
resultsYes
truncatedNo

TDQS

A4.8/5.0
Behavior5/5

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

Beyond readOnlyHint=true, the description discloses concrete behavioral traits: return shape (qualified name, kind, repo, path, line range, source), the 5-match cap, the 400-line source cutoff marked 'cut', the 'total'/'truncated' pagination signals, and the caveat that unparsed files cannot be found. This is unusually complete for a read tool.

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?

Usage guidance is front-loaded ahead of return-format and edge-case details, and each sentence carries distinct information. It is denser and longer than ideal, but no sentence is padding.

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 read tool with an output schema and readOnly annotation, nothing an agent needs is missing: selection criteria, match cap, truncation behavior, and the unparsed-file limitation are all covered.

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 parameters are already documented, but the description adds the useful cross-parameter behavior: a bare name fans out to every same-named definition each labeled with its qualified name, while a qualified name or repo narrows the result. That is genuine semantic value beyond the field descriptions, though it partially repeats 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 first sentence gives a specific verb and resource ('Read the full source of a named definition') and enumerates the definition kinds in scope. It explicitly contrasts itself with search_code and with opening files, so an agent can distinguish it from siblings without inspecting 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 states exactly when to prefer this tool ('when the name is known, for example from a search_code hit') and names the two alternatives it replaces. It also gives the one exclusion case: unparsed line-window files, which should be handled with search_code instead.

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

impact_ofA
Read-only

What could break if I change this? Lists every symbol that reaches the definitions matching name through calls in at most depth hops, once each at its shortest distance (hops), nearest first, with the repository, path and line range. Use it to gauge the reach of a change; for just the direct call sites and their lines, use find_callers. At most 200 rows; truncated is true when more exist. Next step: get_symbol on the nearest symbols to see how they use it.

NameRequiredDescriptionDefault
nameYesA bare name (url_for), which matches url_for and every Class.url_for, or a qualified name (Flask.url_for), which matches only that definition. Case-sensitive.
repoNoLook only in this registered repository, for example flask. list_repositories gives the valid names. Default: all repositories.
depthNoHow many call hops to follow, 1 to 5. Default 3. 1 gives only the direct callers.

Output Schema

NameRequiredDescription
reasonYes
statusYes
resultsYes
truncatedNo

TDQS

A4.6/5.0
Behavior5/5

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

Beyond readOnlyHint=true, it discloses result ordering (shortest distance first), deduplication (once each at its shortest distance), a hard cap of 200 rows, and that truncated=true signals more exist. These are exactly the behaviors an agent needs to interpret output and avoid mistaking truncation for completeness.

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 motivating question and the core behavior, then routes to alternatives and next steps. The middle sentence is a dense clause stack ('once each at its shortest distance... path and line range') that takes effort to parse, but no sentence is wasted.

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?

An output schema exists, so return values need not be explained, yet the description still adds the ordering and truncation semantics that matter for interpreting results. Combined with the depth parameter rationale and sibling routing, an agent has everything needed to call and read 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 coverage is 100%, so name, repo and depth are already fully documented in the schema. The description restates the depth-hop semantics and nearest-first ordering, which adds a little framing but no format or edge-case detail 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?

Opens with a concrete question and then states a precise verb and resource: lists every symbol that reaches the definitions matching name via call chains, nearest first. It explicitly contrasts with find_callers, so an agent can distinguish it from the closest sibling without inspecting 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?

Gives the exact use case ('gauge the reach of a change') and names the alternative plus the condition that selects it ('for just the direct call sites and their lines, use find_callers'). It also prescribes a follow-up step (get_symbol on nearest symbols), 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.

list_repositoriesA
Read-only

Which codebases can I ask about? Lists the registered repositories with their paths and how many files and symbols each holds. Use it to learn the valid repo values for the other tools, or after a repo was refused. A repository with 0 files is registered but not indexed yet.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
reasonYes
databaseYes
repositoriesYes

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, so safety is covered; the description adds the useful edge case that a repo with 0 files is registered but not yet indexed, which explains otherwise-confusing results. It also implies the return payload (paths, counts), though it doesn't say anything about ordering or size limits.

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?

Three short sentences, front-loaded with the purpose and ending on the indexing caveat. The opening rhetorical question is a small stylistic flourish rather than wasted content, but the whole thing earns its length.

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?

An output schema exists, so the description doesn't owe return-value details, yet it still summarizes the payload and handles the empty-repo ambiguity. For a no-argument, read-only listing tool this covers everything an agent needs to call 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?

Zero parameters, so the baseline of 4 applies and there is nothing the description needs to compensate for. The schema coverage being 100% on an empty object means no additional parameter explanation is required or expected.

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

Purpose5/5

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

The description names the resource (registered repositories) and states exactly what is returned: paths plus file and symbol counts. It is clearly a discovery/enumeration tool, distinct from the query-oriented siblings like search_code, get_symbol, or impact_of.

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 two explicit triggers: use it to learn valid repo values for the other tools, or after a repo was refused. That is both a positive condition and an error-recovery condition, leaving little to infer about when to reach for this instead of a sibling.

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

mark_usedA
Idempotent

Tell the server a result helped: call this for each search hit you cite in your answer or rely on. Pass the hit's repo, path and name exactly as search_code returned them. Results that clients mark get a small, capped boost in later searches, and the boost fades over 30 days. Reading a hit with get_symbol or read_wiki already counts as a lighter use, so mark only what you actually used.

NameRequiredDescriptionDefault
nameYesThe hit's name, exactly as search_code returned it, for example url_for or Flask.url_for.
pathYesThe hit's path, exactly as search_code returned it (a page hit's directory).
repoYesThe hit's repository, exactly as search_code returned it, for example flask.

Output Schema

NameRequiredDescription
kindYes
nameYes
pathYes
repoYes
linkedYes
reasonYes
statusYes

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the annotations (readOnlyHint=false, idempotentHint=true, destructiveHint=false), the description discloses the actual effect: a small, capped boost in later searches that fades over 30 days. That is exactly the consequence an agent needs to judge whether calling is worthwhile, and it confirms nothing destructive happens.

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 purpose and the invocation condition, followed by the payoff and the exclusion. Every sentence contributes a distinct piece of guidance with no padding.

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 an output schema present and full schema coverage, the description only needs to cover intent, timing, provenance of inputs, and side effects — all of which it does. Nothing required to call the tool correctly is missing.

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 each of repo/path/name is already documented with examples. The description reinforces the key constraint ('pass them exactly as search_code returned them') but adds no format or edge-case detail the schema doesn't already carry, 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?

The description opens with a precise verb+resource framing ('Tell the server a result helped') and scopes it to search hits that are cited or relied upon. It also distinguishes itself from adjacent tools by noting that get_symbol and read_wiki already register a lighter use, so an agent can tell what this tool uniquely does.

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 for each search hit you cite in your answer or rely on') and an explicit exclusion ('mark only what you actually used', since reading via get_symbol/read_wiki already counts). Both the when and the when-not are stated rather than inferred.

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

read_wikiA
Read-only

What does this module do? Reads the tool's wiki page about a module (a directory of indexed code): its purpose, its key symbols with one line each, the modules it depends on and the modules that use it. Use it when a question is about a module as a whole rather than one function, or after search_code returns a hit of kind page. Pass page to read one page; it returns the text, whether it is fresh or stale (and what made it stale), when and by what it was compiled, and its citations, each with the repository, path and line range of the symbol or file it names. Omit page to list the pages, optionally for one repo, with each page's name, state and first purpose line. A stale page describes code that has changed since; check its citations. Next step: get_symbol on a key symbol to read its source.

NameRequiredDescriptionDefault
pageNoThe page name, for example flask/json, as returned by search_code or by listing. Case-sensitive. Default: list the pages instead.
repoNoLook only in this registered repository, for example flask. list_repositories gives the valid names. Needed when two repositories have a page of the same name. Default: all repositories.

Output Schema

NameRequiredDescription
pageNo
pagesNo
reasonYes
statusYes
truncatedNo

TDQS

A4.6/5.0
Behavior4/5

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

Annotations only declare readOnlyHint=true, so the description carries most of the burden and delivers real operational context: pages can be fresh or stale, what made them stale, and that a stale page describes code that has changed and its citations should be checked. It also discloses the citation payload shape (repository, path, line range). Some of the return detail overlaps the existing output schema rather than adding new behavioral information, which keeps it just below the top score.

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?

Purpose is front-loaded, then read-mode behavior, then list-mode behavior, then next step — a logical order with each sentence doing work. It is longer than necessary for a two-parameter tool, and the return-value paragraph partly duplicates the output schema, but nothing is filler.

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 read-only lookup tool with full schema coverage, annotations and an output schema, the description supplies everything an agent needs to choose it, pick a mode, and interpret staleness. The one remaining gap — pagination or size limits on listings — is minor and not implied by the schema.

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 baseline is 3; the description goes beyond the schema by framing the two modes (pass page to read one page, omit it to list) and by stating that listing can be scoped to one repo with name, state and first purpose line. It adds no syntax or format nuance beyond what the parameter descriptions already say, so it sits modestly above baseline.

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 ("Reads the tool's wiki page about a module") and immediately glosses the resource ("a directory of indexed code") so the domain concept is unambiguous. It also distinguishes the tool from its nearest sibling: use it for a module as a whole "rather than one function" (get_symbol), which lets an agent route correctly without opening either 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?

Gives an explicit trigger (question about a module as a whole, or after search_code returns a hit of kind page), an explicit alternative (get_symbol for a single symbol), and a prescribed next step (get_symbol on a key symbol). The omit-page-versus-pass-page branch is stated in prose, so both invocation modes are covered.

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

recallA
Read-only

Call this at the start of a session, and before searching, to load what earlier sessions already worked out about a codebase. Returns the stored facts, fresh first and most confident first, or most related to topic when one is given, and the most recent tool calls. Each fact has its subject (a symbol or wiki page), its text, a confidence from 0 to 1, whether it is fresh or stale (and why), what wrote its text (a configured model or the template distiller), the IDs of the runs it was distilled from, and the repository, path and line range of the code it describes. A stale fact describes code that has changed since; check it with get_symbol before relying on it. Facts are distilled from earlier calls by ccctx memory consolidate and after every ingestion. Next step: get_symbol on a fact's subject to read its source, or search_code for what recall does not cover.

NameRequiredDescriptionDefault
repoNoRecall only this registered repository, for example flask. list_repositories gives the valid names. Default: all repositories.
limitNoHow many facts to return, 1 to 50. Default 20.
topicNoPut the facts most related to this first, for example "sessions" or "url_for". Default: most confident first.

Output Schema

NameRequiredDescription
runsNo
factsNo
totalNo
reasonYes
statusYes
truncatedNo

TDQS

A4.6/5.0
Behavior5/5

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

Beyond the readOnlyHint annotation, it discloses the ordering of results (fresh first, most confident or topic-relevant first), the exact fields per fact, what 'stale' means and why it matters, the distillation source, and when distillation occurs. This is rich behavioral context an agent cannot get from the annotation.

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 purpose and timing, then return shape, then next steps. It is long and dense, but nearly every sentence carries functional detail (staleness semantics, provenance, next step) rather than padding.

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 an output schema present, the description still covers return semantics, staleness handling, and follow-up actions, plus the readOnlyHint annotation covers safety. Nothing an agent needs to call it correctly is missing.

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

Parameters3/5

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

Schema coverage is 100%, so the schema already documents all three parameters. The description only echoes the topic-ordering behavior and repo scoping that the schema states, adding little beyond it. 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?

States a specific verb and resource: loads facts earlier sessions derived about a codebase. It clearly distinguishes itself from siblings by framing recall as the pre-search memory step versus search_code and get_symbol.

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 ('at the start of a session, and before searching') and routes the agent elsewhere for gaps ('get_symbol ... or search_code for what recall does not cover'). Alternatives and conditions are named.

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

search_codeA
Read-only

Find code by what it does or by name: "how are requests routed?", "where are sessions saved?", "url_for". Use this first when you do not yet know which symbol to look at. If you already know the name, use get_symbol to read it, find_callers for its call sites, or impact_of for what a change would affect. Returns up to limit hits (default 10), best first. Each hit has the repository, path, symbol name, kind, language, line range, a snippet of the symbol's opening lines, and the scores behind its rank: the score, the relevance (the score before feedback), the feedback boost, the keyword rank and the semantic rank (null when that side did not find it). The feedback field is the boost from earlier sessions marking the result used: at most 0.2 (20 percent), fading over 30 days; relevance is the score before it. Keyword and semantic search are fused, and the definitions of an exact identifier come first. A hit of kind page is a wiki page about a whole module: its name is the page name, its path is the module's directory, its line range is null and its state says whether it is fresh or stale; read it with read_wiki. A hit of kind fact is something an earlier session worked out about the code at its path; recall lists all of them. Next step: call get_symbol with a hit's name to read its full source, or read_wiki with a page hit's name.

NameRequiredDescriptionDefault
repoNoSearch only this registered repository, for example flask. list_repositories gives the valid names. Default: all repositories.
limitNoHow many hits to return, 1 to 50. Default 10.
queryYesA question in plain English (how are requests routed) or an identifier (url_for). Taken literally; there is no query syntax.
feedbackNoRaise results that earlier sessions used, by at most 20 percent of their score. false ranks by relevance alone, exactly as with no feedback recorded. Default true.
languageNoSearch only files of this language: one of batch, c, cpp, csharp, css, go, html, ini, java, javascript, json, kotlin, markdown, php, proto, python, rst, ruby, rust, shell, sql, swift, text, toml, tsx, typescript, yaml. Default: all languages.

Output Schema

NameRequiredDescription
reasonYes
statusYes
resultsYes

TDQS

A4.8/5.0
Behavior5/5

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

Annotations declare readOnlyHint=true, and the description is consistent with a read-only search. Beyond that, it discloses ranking mechanics, feedback fading over 30 days, fused keyword/semantic search, special hit kinds (page and fact), and state semantics for wiki pages.

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 purpose and usage, then details results and next steps. It is somewhat long and repeats the feedback/relevance relationship and default limit that the schema already covers, so it is not maximally concise.

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 an output schema, the description supplies the semantic context an agent needs: ranking fields, feedback behavior, page/fact hit meanings, stale/fresh state, and next steps. Nothing essential for correct invocation or interpretation is missing.

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

Parameters4/5

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

Schema coverage is 100%, so the schema already documents all five parameters. The description adds useful meaning for feedback behavior (max 20 percent boost, fading over 30 days, relevance as pre-feedback score) and limit/return behavior, though it does not add much for repo or language beyond the schema.

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

Purpose5/5

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

States a specific verb and resource: 'Find code by what it does or by name,' with concrete query examples. It explicitly distinguishes itself from siblings by saying to use it first when the symbol is unknown, and routing known-name lookups to get_symbol, find_callers, or impact_of.

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 this first when you do not yet know which symbol to look at. It also names the alternatives for known symbols, call sites, and impact analysis, plus concrete next steps after a hit.

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. 9 tool updatesv1.4.2
    • First observedfind_callees
    • First observedfind_callers
    • First observedget_symbol
    • First observedimpact_of
    • First observedlist_repositories
    • First observedmark_used
    • First observedread_wiki
    • First observedrecall
    • First observedsearch_code

TDQS

A4.6/5.0

Scored across 9 tools

Disambiguation5/5

Each tool has a sharply distinct role: search by description, read by known name, read a module wiki page, direct callers vs callees, transitive impact, repository listing, session memory recall, and feedback marking. The descriptions explicitly cross-reference the neighbours (find_callers vs impact_of vs find_callees; search_code vs get_symbol) and state when to prefer each, eliminating overlap.

Naming Consistency4/5

Most tools follow a verb_noun pattern (search_code, get_symbol, find_callers, read_wiki, list_repositories, mark_used). A few deviate: impact_of is noun/prepositional and recall is a bare verb, which is slightly inconsistent but still readable and unambiguous.

Tool Count5/5

Nine tools sit comfortably in the well-scoped 3-15 range. Each maps to a distinct step in a code-investigation workflow (discover repo, search, read, navigate calls, gauge impact, consult/write memory), none feels redundant.

Completeness4/5

Covers the core lifecycle well: repository discovery, search, symbol/source reading, wiki pages, forward and backward call navigation, transitive impact, plus memory recall and feedback. Minor gaps exist—no way to enumerate symbols within a file or module, and no explicit tool to write/record a new fact (facts are distilled automatically), but agents can work around these.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Local-first code indexer that provides deep code understanding for Claude and other LLMs with symbol/text search across 48+ languages, semantic search capabilities, and real-time index updates through the Model Context Protocol.
    59
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Turns a codebase into a queryable graph with semantic search, call graphs, and control/data flow analysis, served to AI coding agents via the Model Context Protocol.
    182 npm
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides intelligent code indexing with 15 MCP tools for symbol extraction, hybrid search (FTS5+vector), call graphs, and incremental indexing of local folders and remote repos, enabling token-efficient code retrieval for AI agents.
    3
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI coding agents to query a locally indexed structural code graph — source entities, callers/callees, Git relationships and recorded mistakes — so they retrieve focused, token-bounded context instead of reading entire files. It runs over local SQLite and can be served through a CLI, agent hooks, an MCP executable and an authenticated local dashboard.
    66 npm
    MIT