Skip to main content
Glama

solograph

MCP server for a portfolio of projects: symbol search across every repository you own, plus full-text search over your Claude Code session history, a markdown knowledge base, and indexed external sources (YouTube, ProductHunt, TrustMRR, Telegram).

Write-up: Solograph, rebuilt: one Rust binary over SQLite instead of a graph database and vectors — what was cut and why, what was borrowed from which repositories, and how to set up your own.

One Rust binary does all of it — the MCP server, every read on the command line, an HTTP API for the sources, the nightly scan. Python is left only for the scrapers that fill the sources index (yt-dlp, Scrapy, Playwright live there).

Everything is SQLite with FTS5: BM25 ranking, Snowball stemming for Russian and English, no graph database, no daemon, no embedding models, no API keys. Each index checks the disk before it answers, so there is no reindex step to forget.

What was cut, and why

solograph used to be a FalkorDB code graph with vector search on top. Both were measured on a real machine before they went:

  • Vectors (removed in 0.7). The session index had zero overlap with the transcripts on disk, KB search took 14 s cold and scored results by rank position, source search hung past two minutes. FTS answers in tens of milliseconds and finds 32 of 39 sessions in a known-answer test the vector index found none of.

  • The structural graph (removed in 0.8). 781k call edges plus imports, inheritance and session→file edges got zero structural questions from agents in four months: five calls in total, every one "list the projects" or stats. Grep answers those questions as well. On a 1,100-file Rust + Swift repository, claude -p with a dedicated code-graph MCP against plain Grep/Read gave the same accuracy in all 8 runs; the call-chain question cost $1.73 against $2.07 (16.5 tool calls against 25), the impact question $0.69 against $0.65.

  • Seven of twelve tools (removed in 0.17). Below, under 5 MCP tools.

  • The second implementation (removed in 0.9). For a day the same 12 tools existed in Rust and in Python. Two implementations of one search drift — the class of bug that kept session_search failing for seven weeks — so every read now comes from the binary the MCP server runs, and Python keeps only what writes the sources index.

What stays is what grep cannot do across repositories: one index of every project's definitions, packages and history. The Python environment went from 862 MB to 34 MB; the binary is 31 MB.

Related MCP server: mcp-context

Install

A prebuilt binary from the latest release, macOS (Apple silicon) or Linux (x86_64):

mkdir -p ~/.solo/bin
curl -fL -o ~/.solo/bin/solograph \
  https://github.com/fortunto2/solograph/releases/latest/download/solograph-macos-arm64   # or solograph-linux-x86_64
chmod +x ~/.solo/bin/solograph && ~/.solo/bin/solograph --version

Or from source with a Rust toolchain: cargo install --git https://github.com/fortunto2/solograph solograph --root ~/.solo, or make rust-install in a clone.

Then hand it to your agent and index your projects:

claude mcp add -s user solograph -e KB_PATH=$HOME/notes -- ~/.solo/bin/solograph
CODEGRAPH_SCAN_PATH=~/projects ~/.solo/bin/solograph scan     # every git checkout under ~/projects
~/.solo/bin/solograph symbols "auth middleware"               # what the agent will get

Sessions need nothing: the index reads ~/.claude/projects on the first search. For new code by morning, cron or launchd solograph registry && solograph scan: registry adds checkouts that appeared, scan only reads the registry, so a project removed from it on purpose stays out.

Your knowledge base

A folder of markdown with YAML frontmatter, the linked pages in wiki/ (or wherever .solograph.yaml says, below). KB_PATH above points kb_search at it.

cd ~/notes
~/.solo/bin/solograph kb --pages "privacy architecture"   # search the wiki
~/.solo/bin/solograph kb-graph --check                    # orphans, broken links; exit 1 when any

Two languages: add wiki/_aliases.yaml, one group per line, the term your pages use last — - [песочница, sandbox]. The hook, in ~/.claude/settings.json, registered for both events:

"hooks": {
  "SessionStart": [
    { "hooks": [ { "type": "command", "timeout": 3,
      "command": "$HOME/.solo/bin/solograph hook --kb-path $HOME/notes" } ] }
  ],
  "UserPromptSubmit": [
    { "hooks": [ { "type": "command", "timeout": 3,
      "command": "$HOME/.solo/bin/solograph hook --kb-path $HOME/notes" } ] }
  ]
}

On a prompt it gives the wiki hint, silent unless the prompt names something the wiki is specifically about. Once per session per project, at SessionStart or on the first prompt that starts work ("plan", "fix", "сделай", "почини"), it gives a map of the registered project holding cwd: stack, size, languages, layers, the first dependencies, and which tool answers what. A second profile adds --db-path for its own portfolio store. Any failure is silence with exit 0; 50-85 ms warm.

The scrapers are a separate, optional Python CLI: uv tool install --editable . gives solograph-cli index-youtube and the rest.

5 MCP tools

Tool

What it answers

session_search

What was asked and answered in past Claude Code sessions, including ones Claude Code already deleted. The session asking is left out. With a result's session_id, it reads that session: the passages that match the query

kb_search

Markdown knowledge base: title and summary fields weigh above the body; path scopes it (wiki/), expand_graph adds up to 3 [[wikilinked]] pages

symbol_search

Where something is defined, across every project: "montage profile" finds resolve_montage_profile and MontageProfile

source_search

Indexed YouTube transcripts (timestamped links), ProductHunt, TrustMRR, Telegram; related gives videos sharing a video's topics, no query at all lists the sources and topics

project_info

The projects: all of them with stacks and counts, one project's make-up (stack, languages, layers, dependencies), or every project using a package

Twelve until 0.17. With tool search on, Claude Code's default, the agent sees only tool names and the server's instructions until it loads a tool, so it picked from twelve bare names, four of them codegraph_* for a graph that no longer existed, and solograph sent no instructions. Two months of transcripts from both profiles hold 72 calls: session_search 34, kb_search 11, symbol_search 7, source_search 4, the other eight tools 11 between them (codegraph_shared and source_related none, web_fetch one), and 5 calls to tools removed earlier. The tools with similar products are 2-5 (episodic-memory 2, qmd 5, claude-context 4). Now the server says when to reach for each tool (848 characters of instructions), session_search and kb_search load with the session (anthropic/alwaysLoad), the descriptions are 5.6k characters instead of 7.9k, and answers are compact JSON, 13-46% smaller than the indented JSON before. web_fetch went with its HTTP client, 113 of the 253 crates in the build, and the binary shrank by 3 MB: Claude Code's own WebFetch and the searxng server's web_extract do that job.

The session asking was left out because it came first: in 18 agent searches that found something, the session doing the search was in the results 10 times and first 7 times, since its prompt holds the very words searched for.

Web search is not here: it lives in the separate searxng MCP server, so a broken import in one cannot take the other down.

How the indexes behave

  • Symbols by their words. Names are split on camelCase and snake_case (as codebase-memory-mcp's tokenizer does), so a phrase finds every spelling. All words rank above some words; an exact name comes first. Definitions only — functions, classes, protocols — from tree-sitter grammars for Python, Swift, TypeScript, JavaScript, Kotlin, Rust, Go, Java, Ruby, C, C++, PHP, HCL, Bash and SQL.

  • Lexical, stemmed. "графами" finds "граф", "indexing" finds "index". No cross-language matching by itself: a Russian conversation is found by Russian words.

  • Never stale. A scan re-reads a file only when its mtime or size changed; a session search re-reads only transcripts that grew, from their last byte offset — live transcripts reach hundreds of MB, and a resync costs ~10 ms.

  • Sessions are archived. Claude Code deletes transcripts after 30 days (cleanupPeriodDays). The index keeps their text and marks them transcript: deleted; live ones come with a claude --resume command. Batch runs started from temp directories (claude -p in /tmp, agent scratchpads) are left out.

  • Private folders stay private. A session whose working directory is inside a folder holding .solograph-private (or Spotlight's .metadata_never_index) is never indexed, and is purged if it was.

  • Scores are BM25 — higher is better, comparable within one answer only.

  • Secrets never enter an index. Every text the session and KB indexes store passes through secrets.rs first: API keys and tokens (AWS, GitHub, OpenAI, Anthropic, Google, Slack, Stripe, Hugging Face, Telegram bots, JWTs), private key blocks, passwords in connection strings, and *_TOKEN= / *_SECRET= values, which keep their name and lose the value. The rules are solo-factory's secret_guard hook (adapted from ScreenShield), placeholders such as your-key or ${VAR} left alone. Indexes written earlier are cleaned once on open: the session index here held 23 secrets in 18 sessions, now 0. The sources index, written by the Python scrapers, is not covered yet.

  • Every call is logged, for the next change. One JSON line per MCP tool call (arguments, result count, first three ids, size, milliseconds, the client's name and Claude Code's session id) and per prompt-hook run (session, pages pointed at, never the prompt), in usage/ next to the portfolio store, so a second profile's queries stay in its own store. solograph usage reads it back, below. Nothing is written from a process started in a folder marked .solograph-private, and the CLI is not logged, so evals and scripts do not drown it.

Is it useful? Five numbers

solograph usage opens with them. They count only calls made inside a Claude Code session: the first log held 58 calls, 47 of them from scripts, which would have read as use.

Number

Counts

Before 0.17

reach

sessions where the agent searched at least once, of sessions seen

12 of 681 (1.8%)

hints

pointers and nudges from the hook followed by a call before the next prompt

not logged

found

searches that returned something

31 of 45 (69%)

opened

of those, searches after which the agent opened a returned file or page, or read a returned session with session_id, before the next prompt (from the transcript, while it is on disk)

11 of 31 (35%)

retried

searches asked again by the same tool within 2 minutes: the first answer did not do

8 of 45 (18%)

The last column is two months of transcripts (one profile) counted with the same definitions. 13 of the 45 searches were errors: session_search failed on every call from 27 September to 25 October in the Python server it replaced, and nothing counted errors then. Reach is the number to move: a search that is never made helps no one, and hooks that put the pointer into the prompt are what other tools found agents act on (a skill the agent must remember was never invoked in 56% of Vercel's evals; injected context was used 66% of the time against 6% in Codeminer42's).

A first check of the change, before any log: the same five prompts that lean on earlier work ("what did we decide about vectors", "where is MontageProfile defined"), claude -p from a temp directory with nothing but the user's CLAUDE.md, the server swapped between 0.16 and 0.17. The agent called solograph on 1 of 5 prompts with 0.16 and on 5 of 5 with 0.17; the answers were right in both (the wiki held them, and with 0.16 the agent grepped it), at $0.30 and $0.32 a prompt. Five prompts, one run each: a direction, not a rate. Where grep is enough, solograph adds a step; what grep cannot reach is the sessions, deleted ones included.

Search quality itself is measured offline, on known answers: a query and the page or session it should find, recall@1 and @5 before and after a change (the numbers in Session ranking below).

The knowledge base

One index ($KB_PATH/.solo/kb/kb.db) serves search, the link graph and the prompt hint. It replaced three things that read the same markdown separately: a Python FTS index, a JSON link graph only as fresh as the last script run (it sat at 36 nodes for eight months while the wiki passed 160 pages), and the hint's own index.

The engine knows no KB's layout. A KB states it in .solograph.yaml at its root:

kb:
  pages: wiki/                  # the wiki: [[links]], index.md, _aliases.yaml (default wiki/)
  stacks: 1-methodology/stacks  # YAML templates for "which stack for X?" hints (default none)
  exclude: [archive, clients/acme]   # a bare name anywhere, a path from the root
  memory_gate: harness/memory-gate.json  # weights for the memory nudge (default none)

A search with no path takes two lanes in turn, the whole KB and the wiki, so a Russian question still reaches an English wiki page past Russian notes elsewhere (6 → 16 of 22 in the top 5; 40 questions about notes outside the wiki: same at #1, 34 → 33 in the top 5). kb-graph, kb-hint and kb --pages scope to pages; a typo in the section is an error, not a silent default. The same file's scope: key is the portfolio scan's.

  • Fields. Title; then index_line, description, tags and the file name; then the body. BM25 weights 2/2/1, measured on a 75-query known-answer set: top-1 29→31/40 on body words, 18→22/25 on summary words, against the old title-plus-body index.

  • Links. [[slug]] and [[slug|label]] outside code are recorded at sync, so the graph is never stale. solograph kb-graph lists hubs, connectors, orphans, broken links and pages missing from index.md; expand_graph adds the pages most linked to the hits (Σ 1/rank, catalog and _* pages excluded, at most 3).

  • Aliases. A YAML table in the KB, wiki/_aliases.yaml: each group lists other spellings of a term, the term the KB writes last — - [песочница, sandbox]. A query word matching an earlier member (by stem) also searches the last; the last expands to nothing. One way on purpose: expanding both ways sent English queries to Russian documents (top-1 fell 31→24/40). On 22 Russian questions for English pages: 0 found before, 21 in the top 5 within wiki/.

  • Hint. solograph kb-hint PROMPT --session ID names a page when the prompt holds a word rare in the wiki that names it and the page covers the prompt's topic; silent otherwise, each page once per session. solograph hook runs it on every prompt (kb-hint --hook still works alone): it reads the hook's JSON and answers it, syncs only wiki/, and is silent with exit 0 on any failure. The rules are in src/kb/hint.rs.

  • Memory nudge. With memory_gate: set, the hook also scores each prompt of three words or more for leaning on the user's earlier work ("как мы делали", "у нас свой крейт…") and, past the file's threshold, tells the agent to look it up with session_search and kb_search. It says that, not what: the agent writes a better query than the raw prompt, and injecting results for the prompt itself was half noise. Before the nudge the agent searched after 17% of such prompts. The scorer is a logistic regression over words and character 3-4-grams (src/kb/memgate.rs); the weights come from your own labelled prompts, so they hold fragments of them and stay in your KB, not here. On a 290-prompt hard set it scored AUC 0.908 against 0.889 for the three small neural models it replaced (258 MB resident, ~100 ms a prompt); this adds under a millisecond. Each run logs gate and nudged to the usage log; solograph usage counts the nudges.

CLI

solograph symbols "auth middleware" [-p my-app]    # definitions across every project
solograph sessions "webhook retry" [-p my-app]     # past sessions, archived ones too
solograph sessions "webhook retry" --session ID    # read one found session for the query
solograph kb "privacy architecture" [--path wiki/] # the knowledge base (KB_PATH, else cwd)
solograph kb-graph [--path wiki/] [--page slug]    # hubs, orphans, broken links, backlinks
solograph kb-graph --path wiki/ --check            # only the problems; fails when there are any
solograph kb-hint "prompt" --session ID            # the UserPromptSubmit pointer, or nothing
solograph sources search "pricing tiers" -s youtube
solograph sources list | tags | related VIDEO
solograph explain my-app | deps my-app | stats | shared [react]
solograph dupes escape                             # names defined in several places
solograph usage [--days 14]                        # the five numbers, then calls, what found nothing, slowest
solograph scan [-p my-app]                         # registry merge + index what changed
solograph sync-sessions | index-kb                 # warm an index (searches sync on their own)
solograph http                                     # sources over HTTP, port 8002

Every read takes --json and then prints what the matching MCP tool returns, so a script and an agent see the same thing (project_info and source_search join explain/stats/shared and sources list/tags/related into one answer each).

Python, for the sources index only: solograph-cli index-youtube -c GregIsenberg -n 10, index-producthunt, index-trustmrr, source-delete, and compact for the KB inbox.

scripts/refresh-changed.sh is the nightly job: registry merge, a scan of every project, session-index sync. It is meant for launchd or cron, and needs only the binary: SOLOGRAPH_SCOPE="a b" or a .solograph.yaml narrows it, and a name the registry lacks fails the run.

Configuration

Variable

Default

Description

CODEGRAPH_DB_PATH

~/.solo/codegraph.db

Only its directory is used now: the portfolio store is portfolio.db next to it

SOLOGRAPH_PORTFOLIO_DB

(none)

Names the portfolio store outright

CODEGRAPH_REGISTRY

~/.solo/registry.yaml

Project registry

CODEGRAPH_SCAN_PATH

~/startups/active

Comma-separated directories registry looks for checkouts in

KB_PATH

current dir

Knowledge base root; index at $KB_PATH/.solo/kb/kb.db (before Oct 2026: search.db, left for binaries still running)

SOLOGRAPH_LOG_DIR

usage/ next to the portfolio store

Usage log, one JSON line per MCP call and per hook run (YYYY-MM.jsonl)

SOLOGRAPH_LOG

on

off stops the usage log

SOLOGRAPH_KB_WEIGHTS

2,2,1

BM25 weights for title, summary fields, body, to re-measure

CLAUDE_SESSIONS_DIR

~/.claude

Claude config dir whose projects/ holds transcripts

CODEGRAPH_SESSIONS_DB

~/.solo/sessions

Session index directory (search.db)

SOURCES_ROOT

~/.solo/sources

Sources index (search.db) and YouTube VTT cache

Every store is per-registration, so one install serves several profiles (say a personal one and a client one) from separate MCP entries with different env.

Portfolio store

portfolio.db: projects (from the registry), packages (npm, pip, SPM, Gradle, Cargo manifests), files (path, language, lines, mtime, size), symbols (name, kind, line) and an FTS5 index over the symbols' words.

Sources

One FTS index at $SOURCES_ROOT/search.db, documents keyed <source>/<id>, plus videos and video_tags tables.

  • YouTube — index-youtube discovers videos via SearXNG, fetches metadata and VTT with yt-dlp, chunks by chapter. Each chunk is a document, so a hit links to its second (&t=140s); a search returns each video once, at its best chunk. Topic tags come from keyword matching against the TOPICS table in sources.py (title hits count double).

  • ProductHunt / TrustMRR — scrapers into the same index; upvotes nudge ranking by at most 15%.

  • Telegram — scripts/index_telegram.py in the consuming repo.

solograph http serves the sources index over HTTP (GET /search?q=...&source=...&n=5, /sources, /health, port SOLOGRAPH_SEARCH_PORT, default 8002) for the SearXNG engine sources_local; Dockerfile.search builds it into an image (make docker-search). Same endpoints and JSON as the Python solograph-search it replaced.

Rust core

rust/ builds the solograph binary. The scrapers in src/ write the sources index through sources.py; the binary reads it — the tables are the contract, and tests/test_sources.py checks it the only way that means anything: Python writes, the real binary reads.

make rust-test       # unit tests + an MCP contract test over stdio
make test            # builds the binary, then the Python write → Rust read tests
make rust-install    # → ~/.solo/bin/solograph

Session ranking

All the query's words before some of them: a session that has every word comes first, then the rest by BM25. Measured on 37 sessions with a known answer (queries are three words from the session's first prompt), on a frozen copy of the index:

Variant

recall@1

recall@5

OR, title ×3 (0.8)

26

30

all words first, then OR (0.9)

29

32

OR, title ×1

27

30

OR, title ×10

24

30

all words first, title ×10

28

32

OR + recency boost

26

30

Typos. Every word is searched as a stemmed prefix, so one wrong letter ("солграф", "технопакр") matched nothing and the word dropped out. A word in fewer than 3 documents whose neighbour one edit away (two from 8 letters) is in at least three times as many is also searched as that neighbour (src/fts/spell.rs, the index's own vocabulary through fts5vocab; a KB adds its alias spellings, so "солграф" reaches "solograph"). Sessions take three passes in turn: every word as written, every word in either spelling, any word, so a session holding a typo verbatim still comes first. One typo planted in the longest word of each known-answer query, 0.15 → 0.16:

Set

clean @1 / @5

with a typo, before

with a typo, after

KB, 40 body-word questions

30 / 38 (same)

19 / 31

27 / 38

KB, 40 questions outside the wiki

25 / 33 (same)

17 / 23

23 / 31

KB, 22 Russian questions for English pages

0 / 16 (same)

0 / 14

0 / 15

Sessions, 40 known answers

27 / 31 (same)

17 / 24

21 / 27

Without typos the known answer keeps its rank on all 199 queries, and 196 of 199 top-5 lists are identical; in the other 3, places 2-5 change. On the words of 300 real prompts (1358 distinct words of 5+ letters) the rule respelt 69: 51 right ("првоерку" → "проверку"), 14 real but rare words wrongly ("тачке" → "точке", "брокер" → "блокер") and 4 typos to the wrong word ("заплонирован" → "заблокирован"). A wrong respelling adds a term but removes none, so it costs places lower in the list. Not caught: words under 5 letters, a typo in the first letter, transliteration ("фази сеарч" for "fuzzy search"). A query costs 0-14 ms more.

Titles skip the lines Claude Code writes itself: 82 archived sessions were titled "[Request interrupted by user for tool use]", and prompts lose their "[Image #N]" markers.

Equivalence with the Python 0.8 it replaced

Measured on 27 Oct 2026 against copies of the real stores, each engine on its own copy:

Python 0.8

Rust

Same top-5, same order — 54 session, 8 KB, 8 symbol, 6 source queries

76 / 76

Session recall@5, 40 known-answer sessions

30

30

stats, explain, shared, project_info, source_tags, source_related

identical JSON

Query stems, 28,576 RU+EN words from the KB and sessions

snowballstemmer 3.1.1

0 differ

Portfolio from scratch, 77 projects: files / packages / symbols

8,935 / 1,350 / 63,585

8,935 / 1,350 / 63,582

Full scan from scratch

32.7 s

9.8 s, registry merge included

MCP start → initialize answered

280–300 ms

4 ms

First / repeat session_search

24 / 14 ms

15 / 10 ms

On disk

97 MB venv

33 MB binary

The English stemmer is a port of Snowball 3.1.1 (english.rs): rust-stemmers implements Snowball 2, and 24 of ~13,000 English words stemmed differently ("organization": organ vs organiz), which is a different prefix query. The three symbols Rust does not find are in files that do not parse cleanly (C++ inside a .h read with the C grammar, one Swift async method), where tree-sitter's error recovery differs between the core Python bundles (0.26.0) and the one on crates.io (0.26.13). The first launch after a rebuild takes ~0.9 s while macOS checks the new binary.

Part of Solo Factory

Solograph is the MCP backend for Solo Factory. It also works standalone.

License

MIT

Available Tools

15 tools
codegraph_explainA

Architecture overview of a project from the code graph.

Returns structured data: stack, languages, directory layers, key patterns (mixins, base classes, CRUD schemas), top dependencies, and hub files.

Args: project: Project name (e.g. "my-app", "backend-api")

NameRequiredDescriptionDefault
projectYes

TDQS

A3.7/5.0
Behavior3/5

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

With no annotations, the description carries the behavioral disclosure burden. It clearly states that the tool returns structured data and lists the categories, which is useful. It does not explicitly say the operation is read-only, how the code graph is accessed, or describe failure behavior, though nothing suggests side effects.

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

Conciseness5/5

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

The description is compact and well-structured: a one-line purpose statement, a concise list of return categories, and a clearly labeled Args section. Every sentence adds value and there is no redundant information.

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?

Since there is no output schema, the description compensates by enumerating the major return categories and giving an example for the single parameter. It is complete enough for correct invocation, but the absence of explicit read-only confirmation and sibling differentiation leaves a small gap.

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 0%, so the description must compensate. It does by defining the only parameter: 'project: Project name (e.g. "my-app", "backend-api")', which provides both meaning and examples. For a single required string parameter, this is sufficient, though it could mention whether an ID, path, or exact name format is expected.

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

Purpose4/5

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

The description states a clear purpose: it provides an architecture overview of a project from the code graph, and it enumerates concrete return categories such as stack, languages, directory layers, key patterns, top dependencies, and hub files. It does not explicitly differentiate itself from sibling tools like codegraph_repomap or codegraph_stats, but the purpose is not vague.

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

Usage Guidelines3/5

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

The intended use case is implied by 'Architecture overview' and the listed output categories, suggesting the tool is for high-level project understanding. However, there is no explicit when-to-use guidance, no exclusions, and no mention of alternatives among the many sibling tools.

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

codegraph_queryA

Execute a raw Cypher query against the code intelligence graph.

The graph contains: Project, File, Symbol, Package, Session nodes. Edges: HAS_FILE, DEFINES, DEPENDS_ON, MODIFIED, IN_PROJECT, TOUCHED, EDITED, CREATED, IMPORTS (File->File or File->Package), CALLS (File->Symbol), INHERITS (Symbol->Symbol).

Example queries:

  • MATCH (p:Project) RETURN p.name, p.path LIMIT 10

  • MATCH (f:File {project: 'my-app'}) RETURN f.path, f.lang LIMIT 20

  • MATCH (p:Project)-[:DEPENDS_ON]->(pkg:Package) WHERE pkg.name = 'react' RETURN p.name

  • MATCH (s:Session)-[:EDITED]->(f:File) RETURN f.path, COUNT(s) ORDER BY COUNT(s) DESC LIMIT 10

Args: query: Cypher query string

NameRequiredDescriptionDefault
queryYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden. It explains the tool's data model and provides example queries, which sets expectations about the graph structure. However, it does not disclose whether queries are read-only, performance implications, potential for heavy load, or error behavior on malformed queries. For a raw-query tool, this is a notable gap.

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 well-structured: a single sentence opens with the core function, then a structured list of graph components, followed by examples. It is slightly long but each element earns its place, especially the examples which are essential for an action with a single free-form parameter. Dense but not bloated.

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

Completeness4/5

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

The description covers the graph schema, edge types, and parameter semantics, and there is an output schema present (not shown) that may convey return structure. What is missing is guidance on performance, query limits, or security considerations. For a power-user tool, this is adequate but not fully comprehensive.

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

Parameters5/5

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

The schema only defines 'query' as a string with 0% description coverage. The description compensates fully by specifying that it is a Cypher query string, describing the available entities and edges, and offering multiple concrete examples that illustrate valid query syntax. This adds significant meaning beyond the bare 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 clearly states the tool executes a raw Cypher query against a code intelligence graph, specifying node types and edge types. This provides a precise verb and resource, and visually distinguishes it from siblings like source_search or kb_search, which are likely semantic. The examples solidify the intended scope.

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

Usage Guidelines3/5

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

The description conveys that this is for raw Cypher queries, which implies flexibility for complex or custom analyses. However, it does not explicitly state when to prefer this over sibling tools like codegraph_stats or source_search, nor does it mention any exclusions or recommended fallbacks. The usage context is clear but not contrastive.

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

codegraph_repomapA

Generate a YAML-formatted repository map showing the most important files and their symbols.

Helps understand the global structure of a project without reading all files.

Args: project: Project name (e.g. "my-app") limit: Maximum number of top files to include (default 20)

NameRequiredDescriptionDefault
limitNo
projectYes

TDQS

A4.1/5.0
Behavior3/5

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

Annotations are absent, so the description carries the full burden. The description explains the tool generates a YAML map, which implies a read-only operation, but it does not explicitly state that it is non-destructive, requires no special permissions, or has any side effects. No contradictions exist, but the description would benefit from an explicit statement that it only reads repository data.

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 well-structured with a concise intro and a clean 'Args:' section. Every sentence is purposeful, with no unnecessary verbosity. It is front-loaded with the core purpose and uses a list for parameters, making it easy to scan. A minor improvement would be to mention the output format once at the start, which it already does.

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

Completeness4/5

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

For a simple tool with two parameters and no output schema, the description is fairly complete. It explains the purpose, output format, and both parameters. It does not explicitly cover error conditions or prerequisites (e.g., the project must be indexed), but these are not critical for basic usage and are likely implied by the context of the codegraph system.

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 schema has 0% description coverage, so the description must compensate. It does so by explaining each parameter: 'project: Project name (e.g. "my-app")' and 'limit: Maximum number of top files to include (default 20)'. It adds examples and semantic meaning, although it leaves some ambiguity about 'most important' and how the limit is applied.

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 clearly states the tool's purpose: 'Generate a YAML-formatted repository map showing the most important files and their symbols.' It specifies the verb 'Generate', the resource 'repository map', and the output format (YAML). This distinguishes it from siblings like codegraph_query and codegraph_explain, which focus on querying or explaining code.

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

Usage Guidelines4/5

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

The description provides usage context: 'Helps understand the global structure of a project without reading all files.' This gives a clear scenario for when to use the tool. However, it does not explicitly mention when NOT to use it or contrast with alternative tools, which is a minor gap.

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

codegraph_sharedA

Packages shared across multiple projects in the code graph.

Returns list of packages with the projects that depend on them, sorted by number of projects (most shared first). Useful for finding common dependencies and potential shared infrastructure.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden. It discloses key behavioral traits: returns a list, includes dependent projects, and sorts by number of projects (most shared first). It does not describe side effects, but the nature ('Returns') implies a read-only query. Minor gaps like pagination or error handling are not critical for a zero-parameter tool.

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

Conciseness5/5

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

The description is concise and front-loaded: it opens with the core purpose ('Packages shared...') and then explains the output and sorting. Every sentence adds value, and there is no filler. It is appropriately sized for a simple tool.

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 the tool's simplicity (no parameters, no annotations) and the presence of an output schema, the description covers the essential information: what it returns, the ordering, and a use case. It does not explain what constitutes a 'package' or a 'project,' but these are likely defined elsewhere in the code graph context. Overall, it is sufficiently complete for an agent 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?

There are zero parameters, so the schema coverage is 100% by default. The baseline for zero parameters is 4, and the description offers no parameter details because none exist. This score reflects that there is nothing to explain and the description is not lacking in this area.

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 clearly states the specific resource ('packages shared across multiple projects') and the action ('Returns list...'). It is distinct from siblings like codegraph_stats or codegraph_query by focusing on shared dependencies across projects. The wording is unambiguous and directly conveys what the tool does.

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

Usage Guidelines4/5

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

The description provides explicit context for when to use the tool: 'Useful for finding common dependencies and potential shared infrastructure.' This gives clear use-case guidance. However, it does not explicitly mention when not to use it or name alternative tools, so it falls short of the highest score for explicit exclusions.

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

codegraph_statsA

Get code intelligence graph statistics.

Returns counts of projects, files, symbols, packages, sessions, and edge type breakdown.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.1/5.0
Behavior3/5

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

There are no annotations, so the description carries the full burden. It discloses that the tool returns statistics and counts, which implicitly indicates a read-only aggregation, but it does not explicitly state the absence of side effects, potential resource costs, or any error behavior. For a simple stats tool, this is adequate but not rich.

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 compact sentences: the first front-loads the core purpose, the second enumerates the returned metrics. Every word earns its place; no fluff or repetition.

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 no-argument statistics tool with no output schema, the description is complete: it lists the exact categories of counts returned. An agent can predict the shape and intent of the call without needing extra context.

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, so schema coverage is trivially 100%. Baseline for 0 parameters is 4; there is no parameter information needed beyond what is already empty.

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

Purpose5/5

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

The description names a specific verb ('Get') and a concrete resource ('code intelligence graph statistics'), then enumerates exactly what is returned (counts of projects, files, symbols, packages, sessions, edge type breakdown). This clearly distinguishes it from sibling tools like codegraph_query or codegraph_repomap, which target different purposes.

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

Usage Guidelines3/5

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

The description implies usage — if an agent needs aggregate counts or a breakdown of graph elements, this is the tool — but it does not explicitly state when to use it over alternatives or mention any exclusions. No sibling differentiation is provided in the text.

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

project_code_reindexA

Reindex a project's source code and docs into FalkorDB vectors.

Call this after significant code changes to update the search index. Uses sentence-transformers backend (safe for memory).

Args: project: Project name or path (e.g. "my-app", "~/projects/my-app")

NameRequiredDescriptionDefault
projectYes

TDQS

A4.2/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full behavioral burden. It does disclose the backend ('sentence-transformers'), notes that it is memory-safe, and implies an index mutation. However, it does not state whether existing vectors are replaced or cleared, whether the operation is expensive or blocking, or what permissions are needed.

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 compact and well-structured: a one-sentence purpose, a clear when-to-use instruction, a useful safety/backend note, and a simple Args section. Every sentence earns its place, and key information is front-loaded.

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 one-parameter tool, this is mostly adequate, but significant gaps remain because there are no annotations and no output schema. The description does not mention return values, the cost or duration of reindexing, whether the operation overwrites the existing index, or how to handle partial failures. These are relevant for a mutating indexing tool.

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

Parameters5/5

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

The only parameter, 'project', is described as 'Project name or path' with concrete examples ('my-app', '~/projects/my-app'). With 0% schema description coverage, this fully compensates for the missing schema-level detail and adds real meaning beyond the parameter's title.

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 ('Reindex'), a specific resource ('a project's source code and docs'), and a clear target ('FalkorDB vectors'). It clearly differentiates this tool from sibling search/query tools by framing it as the index-updating operation.

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

Usage Guidelines4/5

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

The description gives a clear usage condition: 'Call this after significant code changes to update the search index.' It does not explicitly name alternatives or exclusions, but the context is clear enough for an agent to know when to select this tool.

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

project_infoA

Get project information from the registry.

Without name: returns list of all active projects with stacks. With name: returns detailed info for one project.

Args: name: Project name (e.g. "my-app"). Omit for full list.

NameRequiredDescriptionDefault
nameNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

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

With no annotations provided, the description shoulders the full burden of disclosing behavior. It does describe the two return modes (list vs. detail) and implies a read-only operation, but it does not explicitly confirm safety, mention error handling (e.g., what happens if the name does not exist), or note any side effects or authentication requirements. The description adds some behavioral detail but is not comprehensive for an unannotated tool.

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

Conciseness5/5

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

The description is highly concise, front-loading the core purpose and then clearly delineating the two modes before listing the argument. Every sentence contributes value, with no filler. The structure is optimal for quick agent scanning.

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 the low complexity (single optional parameter) and the presence of an output schema (which handles return value documentation), the description covers the essential calling context: what the tool does and how the parameter alters the result. It could go further by noting expected error behavior or clarifying what 'active projects' means, but overall it is sufficient for correct invocation.

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 input schema only defines an optional 'name' field with a default null and anyOf string/null, providing no semantic meaning. The description compensates by explaining that omitting the name returns a list of all projects, while including it returns detailed info for one named project. This adds significant behavioral meaning beyond the raw schema, effectively covering the parameter's semantics despite 0% schema coverage.

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

Purpose4/5

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

The description clearly states the tool retrieves project information from a registry, with two explicit modes: listing all active projects (with stacks) when no name is given, and returning detailed info for a specific project when a name is provided. This is a specific verb-resource pairing. However, it does not differentiate itself from sibling tools like source_list or project_code_search, which could overlap in purpose or context.

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

Usage Guidelines3/5

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

The description explains when to omit the name (to get a full list) versus when to provide it (to get a single project's details), which is clear self-usage guidance. However, it does not explicitly tell the agent when to choose this tool over siblings, nor does it mention any exclusion criteria or alternatives. The guidance is contextually clear but lacks cross-tool comparison.

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

source_listA

List indexed external sources with document counts.

Shows all source graphs under ~/.solo/sources/ with their sizes. YouTube sources include video/chunk breakdown (videos, video_chunks fields).

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations provided, the description carries the disclosure burden. It adds useful behavioral context beyond the title: the storage location (~/.solo/sources/), that sizes are shown, and that YouTube sources include a videos/video_chunks breakdown. The verb 'List' strongly implies a read-only operation, though it does not explicitly state side-effect safety.

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 short sentences with no filler. The opening sentence gives the primary purpose, and the following sentences add specific and relevant details about location, sizes, and YouTube-specific fields. It is front-loaded and every sentence earns its place.

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

Completeness5/5

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

For a no-argument list tool with an output schema present, the description is complete: it states what is listed, where the data comes from, what measurements are included, and the special case for YouTube sources. No additional context appears necessary for an agent to select and invoke 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?

The input schema has zero parameters and schema coverage is 100%, so there is no parameter documentation burden. The 0-parameter baseline of 4 applies; the description adds no parameter meaning because none is needed.

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 ('List') and resource ('indexed external sources') and adds a document-count detail. It further clarifies scope by specifying all source graphs under ~/.solo/sources/, which distinguishes it from sibling tools like source_search, source_tags, and source_related as a global enumeration rather than a filtered query.

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

Usage Guidelines3/5

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

The description implies use when an overview of all indexed sources and their sizes/document counts is needed, but it does not explicitly say when not to use it or name alternatives. There is no explicit routing guidance against sibling tools, so the agent must infer the usage boundary from the word 'List' and the scope detail.

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

source_tagsB

List all auto-detected topics with video counts.

Tags are assigned automatically via zero-shot embedding similarity during video indexing. Shared across videos — enables topic clustering.

Args: source: Source name (default: "youtube")

NameRequiredDescriptionDefault
sourceNoyoutube

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.3/5.0
Behavior3/5

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

With no annotations, the description must carry behavioral disclosure. It adds useful context: tags are assigned automatically via zero-shot embedding similarity during video indexing, and are shared across videos. However, it does not clarify whether the operation is strictly read-only, how counts are computed, or any caveats such as staleness or re-indexing effects.

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

Conciseness5/5

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

The description is compact and front-loaded with the main purpose, followed by relevant mechanism context and a parameter note. Every sentence adds value and there is no redundancy or fluff.

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?

The tool is simple, and the output schema presumably covers return values. Yet the description leaves a notable gap: it does not tell the agent how to obtain valid source names or that source_list might need to be called first, and it omits any mention of pagination or limits. Overall it is adequate but not fully complete.

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

Parameters2/5

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 for the undocumented 'source' parameter. It merely restates 'Source name (default: "youtube")', which adds little beyond the schema's title and default. It does not provide valid source examples, format constraints, or how source affects the returned tags.

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

Purpose4/5

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

The description clearly states a specific action and resource: 'List all auto-detected topics with video counts.' It is unambiguous and distinct from siblings like source_list or source_search, but does not explicitly name or differentiate itself from them, 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?

The description implies usage through context: tags are auto-detected, shared across videos, and enable topic clustering. However, there is no explicit guidance on when to choose source_tags over sibling tools or any exclusions, leaving the agent to infer the appropriate context.

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

web_fetchA

Fetch a URL with browser-like headers to bypass basic bot protection.

Returns page content as plain text (HTML tags stripped) or raw HTML. Handles redirects, cookies, and common anti-bot headers automatically.

Args: url: URL to fetch max_length: Max content length in chars (default 20000) extract_text: Strip HTML tags and return plain text (default true) timeout: Request timeout in seconds (default 30)

NameRequiredDescriptionDefault
urlYes
timeoutNo
max_lengthNo
extract_textNo

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the full burden of behavioral disclosure. It reveals automatic handling of redirects, cookies, and anti-bot headers, and explains the dual output modes (plain text vs raw HTML). It stops short of describing failure modes or JavaScript-rendering limitations, but the core runtime behaviors are transparent.

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 compact and well organized: one sentence for the core purpose and behavior, another for return types, then a minimal Args list. Every sentence contributes meaningful information with no fluff or repetition.

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

Completeness4/5

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

For a simple fetch tool with four parameters and no output schema, the description covers the essential aspects: what it fetches, how it behaves, return types, and all parameters with defaults. It doesn't mention error handling or non-HTML responses, but those are minor omissions given the straightforward use case and sibling context.

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

Parameters5/5

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

The Args section adds meaningful semantics to every parameter: url, max_length (in chars), extract_text (strip HTML), and timeout (in seconds) with defaults. This fully compensates for the 0% schema description coverage, giving the agent a complete understanding beyond bare parameter names.

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 begins with a specific verb and resource — 'Fetch a URL' — and immediately adds distinctive behavior ('with browser-like headers to bypass basic bot protection'). It clearly distinguishes this tool from the source-code-oriented sibling tools by domain and use case.

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

Usage Guidelines4/5

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

The description clearly implies when to use the tool: when needing to retrieve web content, especially when basic bot protection may interfere. It doesn't explicitly mention when not to use it or name alternative tools, but among the listed siblings there is no competing fetch tool, so the intended context is clear.

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. 15 tool updatesv0.6.0
    • First observedcodegraph_explain
    • First observedcodegraph_query
    • First observedcodegraph_repomap
    • First observedcodegraph_shared
    • First observedcodegraph_stats
    • First observedkb_search
    • First observedproject_code_reindex
    • First observedproject_code_search
    • First observedproject_info
    • First observedsession_search
    • First observedsource_list
    • First observedsource_related
    • First observedsource_search
    • First observedsource_tags
    • First observedweb_fetch

TDQS

A3.9/5.0

Scored across 15 tools

Disambiguation5/5

Each tool targets a distinct resource and operation: codegraph stats/query/explain/repomap/shared, source list/search/tags/related, kb_search vs project_code_search vs session_search clearly separated by domain, project_info, web_fetch, and project_code_reindex. No two tools appear to do the same thing.

Naming Consistency4/5

Most tools follow a clear prefix_descriptive pattern (codegraph_, source_, kb_, session_, project_, web_) with snake_case. Some descriptors are nouns or adjectives (repomap, shared, tags, related) rather than verbs, but the pattern is predictable and uniform in style.

Tool Count5/5

15 tools is well within the optimal range for a server with this scope. Each tool serves a distinct purpose, covering stats, search, querying, and metadata across multiple knowledge domains without unnecessary bloat or missing essentials.

Completeness4/5

The server covers core read and query operations for code graphs, knowledge bases, sessions, external sources, and project metadata. It includes reindexing for code search, but lacks explicit create/update/delete operations—appropriate for a read-oriented server. Minor gaps exist (e.g., no direct session listing), but agents can work around them via search and query tools.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server enabling symbol-aware semantic search in Claude Code, allowing precise location of functions, types, and implementations via a symbol graph and embeddings.
    9
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Local MCP server that provides semantic search (RAG) over code repositories, enabling AI clients like Claude and Gemini to access project context without manual re-upload.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server providing RAG context and failure capture for Claude Code, enabling semantic search across project knowledge and storing/analyzing failures.
    1
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP server for local-first code intelligence, providing structural code graph, semantic search, and impact analysis to AI agents.
    2
    MIT