docs
MCP Server

Knowledge and code MCP tools

Reference for ask_knowledge_graph, search_code, blast_radius and get_data_model: inputs, outputs, scope and limits.

nima's knowledge and code MCP tools answer four questions about your product: why and who (ask_knowledge_graph), where (search_code), what depends on it (blast_radius) and what the data looks like (get_data_model). All four are read-only, need the knowledge:read scope, and are available to every member of the workspace.

On for every workspace. The three code tools (search_code, blast_radius, get_data_model) are declared under a plan feature; see Plan feature for the code tools.

Knowledge and code tools at a glance

Four tools share the scope knowledge:read. Each one is a loopback call to a REST route, so the same guards, throttling and workspace scoping apply as for a direct API call. To connect a client, see the MCP server overview. Each route is documented in the REST reference: Knowledge graph and Code intelligence.

ToolRouteAsksMetered
ask_knowledge_graphGET /v1/knowledge-graph/askWhy and who: decisions, customers, how things connectOne question embedding, plus one translation call for a non-Latin-script question
search_codeGET /v1/code-intel/searchWhere: ranked files with symbols and line rangesYes, LLM cost per repository
blast_radiusGET /v1/code-intel/blast-radiusWhat a change to a file or symbol reachesNo LLM call
get_data_modelGET /v1/code-intel/data-modelTables, columns, relations and enums parsed from ORM code and SQLNo LLM call

All four carry the hints readOnlyHint: true and openWorldHint: false. They sit on the soft rate-limit tier (300 requests per 10 seconds); see Rate limits. None of them paginates: each caps its own output, as described below. None returns file contents or source code.

For the history of one signal, beacon, spec or PR, use get_history from the pipeline tools.

ask_knowledge_graph tool

ask_knowledge_graph takes a natural-language question and returns the entities in your workspace's knowledge graph that match it, with their facts, relationships and unresolved conflicts. The graph is nima's organizational memory: it holds what your connected tools told nima, nothing else. See The knowledge graph for what feeds it.

qstringrequired

The question, 2 to 500 characters. Describe the thing the way its summary would read: "what do customers say about billing" or "why did we drop the legacy importer". Naming a literal (a file path, a symbol, a SCREAMING_SNAKE constant, a ticket key, a quoted string) returns every entity that carries it first.

limitinteger

How many entities to return, 1 to 20. Defaults to 8.

modeenum

Only the value agent is accepted. It returns compact JSON instead of markdown. Any other value is rejected.

Read the markdown answer from ask_knowledge_graph

Without mode, the answer is markdown (text/markdown). It opens with Knowledge graph results for: "<q>". If nima translated your question, a line before it reads Searched in English: followed by the translation. The graph is English: questions written mostly in a non-Latin script (Hebrew, Arabic, Russian, Chinese) are translated before searching, other questions are searched as typed, and the answer content stays English.

Each entity is a block with these parts:

  • A header: ### <name> (<entityType>) [<modality>] (<match tag>) ยท id: <entity id>. The modality is one word: implemented or fixed (evidence it is in the code), proposal (asked for or specced, never confirmed built) or problem (a report of something wrong). It is omitted when unknown. Never read a proposal as what the product does today.
  • The match tag: (exact) or (exact: fact <key>) when the entity carries a literal your question named, (no exact match) when nothing named does. (mentioned in fact <key>) appears when a fact only uses an all-lowercase hyphenated word you named (such a word may be prose, so it is not an exact match). Ordinary semantic hits carry no tag. When the question names something and no entity in the graph has that name, the answer opens with a warning that everything below is a semantic neighbour, not the thing you asked for.
  • References: N | Similarity: 0.NNN. Similarity is cosine, three decimals. A hit found by literal text, not by embedding, shows Similarity: 0.000.
  • Superseded by <names> before the summary when a newer entity replaced this one. Its facts describe how things used to work. Superseded entities rank below current ones.
  • For an entity that is a pull request, a NOT SHIPPED line when the PR closed unmerged, or NOT SHIPPED YET when it is still open. Merged renders nothing.
  • Summary:, followed by a stale-summary warning when the summary is out of date.
  • Facts:, up to 5 lines, each with its source and the date learned, A fact is marked ASSUMED when the source hedged it and (confirmed) when a person confirmed it; otherwise it has no mark. A signal source carries an origin tag: [customer], [external], [internal] or [internal channel]. Overflow reads N more facts omitted.
  • contradicted: lines for unresolved conflicts, up to 5.
  • Relations:, up to 5. An outgoing edge reads relationType โ†’ Name (type); an incoming edge reads โ† Name (type) relationType this.

Entities do not come back strictly by similarity. Exact-literal carriers come first, a name or alias match in the question boosts an entity, and entities built only from the code index or replaced by a newer entity are demoted. Indexer bookkeeping facts are hidden.

An empty result is a normal 200 whose text reads No product entities found for: followed by your question. It means the graph is silent, not that nobody asked: a workspace connected recently has an almost empty graph.

Read the agent-mode JSON from ask_knowledge_graph

With mode set to agent, the answer is JSON: query, identifiers (the literals detected in the question), optional queryTranslation, and entities. Each entity has id, name, entityType, similarity, summary, facts, relations, conflicts, supersededBy, prLifecycle, modality and match.

  • match is exact, semantic or none. matchedFactKey and matchVia say which fact carried the literal.
  • Each fact has key, value, confidence, sourceType, sourceUrl, sourceExcerpt, learnedAt (YYYY-MM-DD), confirmationState (assumed, confirmed or null) and, for signals, origin.
  • Each relation has relationType, targetName, targetType, targetEntityId, evidence, direction (out or in), prLifecycle (merged, closed_unmerged, open or null) and prMergeSha.
  • Agent mode has no cap on facts and relations, and no stale-summary flag.

The full line format and an example live on Knowledge graph API.

Confidence floor and soft tier for ask_knowledge_graph

An entity has to reach a cosine similarity of 0.6 to come back by meaning alone. Name and alias matches and exact-literal carriers bypass that floor, and a literal-text fallback can return entities at 0.000. A confident "nothing found" is not proof that nobody asked for something. The route needs no plan feature and sits on the soft tier.

search_code tool

search_code searches every indexed repository in your workspace with nima's retrieval pipeline and returns ranked files with a summary, the top symbols and their line ranges. It returns where code is, never the code itself. It searches only repositories whose index is ready, and indexes follow each repository's default branch.

qstringrequired

What to find, 2 to 300 characters, in plain English or as identifiers: "where is the beacon rank computed" or SpecGenLauncher. Over raw HTTP the route checks only the minimum length; the tool enforces the 300 maximum.

repositoryIduuid

Search only this repository. Take the id from repositories in an earlier result. Omit it to search all of them.

limitinteger

How many file hits, 1 to 20. Defaults to 8. Over HTTP, values above 20 or below 1 are clamped rather than rejected, and 0 or a non-number means the default.

Read the search_code response

The response is JSON with four parts.

  • repositories: every in-scope repository with id, repoFullName, indexStatus, lastCommitSha, lastSyncedAt and indexWarnings. Compare lastCommitSha with your HEAD before trusting structure: a stale index answers about the commit it was built from.
  • results: the hits, each with repositoryId, repoFullName, filePath, score, summary, matchedChannels, match and up to 8 symbols. A symbol has name, kind (function, class, interface, type, enum, route, entity or decorator), signature, lineStart and lineEnd.
  • match: for a query shaped like a path or a single identifier, exact means the path equals it or a symbol of that name is in the file, semantic means a path or symbol channel matched, and none means no channel confirmed that the literal exists, so the thing you asked for may not exist. Natural-language queries are always semantic.
  • droppedRepositories: repositories whose search failed or ran past its 45-second budget. Missing hits from dropped or unavailable repositories do not prove code is absent.

With no ready index the call returns 200 with empty results. A repositoryId from another workspace returns 404.

Cost of search_code

search_code is metered. Each repository searched costs one query embedding and one rerank call on the summary model, plus two to three more model calls when the query is complex. blast_radius and get_data_model cost no model calls.

blast_radius tool

blast_radius takes a file path, a symbol name or the changed files of a diff, and returns what a change there reaches: dependent modules, dependent files by distance, covering tests and the specs that govern the code. It reads the existing index, calls no model and is not metered. Use it before editing, to review a PR's reach, or to pick tests to run.

pathsstring[]

Repository-relative file paths, each 1 to 400 characters. A shorter suffix of an indexed path also matches. Pass a diff's changed files here.

symbolstring

An exported symbol to start from, 1 to 200 characters. Comma-separate a few. Send paths, symbol or both; a call with neither returns 400.

repositoryIduuid

Limit the walk to one repository. Omit it to look across all of them.

depthinteger

How many hops to walk, 1 to 4. Defaults to 2.

modeenum

Accepted for parity with ask_knowledge_graph; agent has no effect and any other value returns 400.

paths and symbol together may name at most 50 targets per call; more returns 400.

Read the blast_radius response

The response is JSON with these fields.

  • targets: the files your input resolved to. unresolved: inputs that matched nothing.
  • dependentModules: modules that depend on the targets, with edgeCount, relations and depth.
  • dependentFiles: source files that depend on the targets, with depth (1 means it imports a target directly), relations, moduleName and callers. Each caller is a symbol in that file that calls into the target, with symbol, lineStart, lineEnd and calls.
  • coveringTests: the same shape as dependentFiles, for test files. Paths under a __tests__/, tests/ or test/ folder, and JavaScript or TypeScript files named *.spec.* or *.test.*, land here.
  • governingSpecs: specs tied to the touched files or modules through the knowledge graph, with documentId, title, status, updatedAt and viaEntities.
  • callGraph: coveredTargets, importOnlyTargets and a note.
  • truncated: true when the walk hit its cap of 400 impacted files, so the answer is a prefix.

The walk follows reverse imports, calls, inherits and injects edges.

Language limits of blast_radius

Callers are extracted only for TypeScript and JavaScript files (.ts, .tsx, .js, .jsx, .mjs, .cjs). For every other language, dependents are import-level and callers is empty. An empty callers there means no parser, not no callers; callGraph.importOnlyTargets lists those targets. The response carries no commit stamp: it answers about the commit the index was built from, so check search_code's lastCommitSha against HEAD.

get_data_model tool

get_data_model returns the tables, collections, columns, relations, indexes and enums that your repositories' ORM definitions and SQL DDL declare, each with the file and line. It is deterministic: parsed at index time, no model call, not metered.

repositoryIduuid

Only this repository. A malformed id returns 400. Omit it for every indexed repository.

tablestring

A table, collection or model name to return in full, 1 to 200 characters, case-insensitive: users, User or billing.invoices. Omit it for a summary of every table.

Read the get_data_model response

The response is JSON: table (your query or null) and repositories. Every repository entry has repositoryId, repoFullName, commitSha, extractedAt, orms, tableCount, enumCount and warningCount.

  • Without table, the mode is summary. Each repository lists tables with name, schema, entityName, orm, kind, filePath, lineStart, columnCount and relationTargets. At most 400 tables per repository are listed, and truncated says when there were more.
  • With table, the mode is detail. matchedBy is exact (the table name, schema.name or declaring class equals the query), substring (the table name or declaring class contains it) or none. totalMatches counts the matches. Each repository entry also carries mode: summary or detail. Each table carries full columns (type as written and normalized, nullability, primary key, unique, default, enum values), relations (kind, foreign-key columns, target table, on-delete, join table), indexes, and file and line. At most 20 tables per repository are returned, plus up to 50 matching enums.
  • Table kinds are table, view, collection and embedded. Relation kinds are one_to_one, one_to_many, many_to_one and many_to_many.

extractedAt: null means nothing has been extracted for that repository yet. An empty model means no supported ORM or DDL was found, not that the app stores no data. Compare commitSha with HEAD before trusting it.

ORMs and files get_data_model reads

Supported ORMs: Prisma, Drizzle, TypeORM, Sequelize, MikroORM and Mongoose for TypeScript and JavaScript; SQLAlchemy, SQLModel, Django, Peewee and Tortoise for Python; GORM, ent and Bun for Go; and CREATE TABLE and ALTER TABLE statements in .sql files. Ruby, Java, Rust and C# ORMs (ActiveRecord, Hibernate, Diesel, Entity Framework) are not extracted.

Plan feature for the code tools

search_code, blast_radius and get_data_model are declared under the plan feature code_intelligence. A workspace whose plan lacks that feature can get a 403 INSUFFICIENT_PERMISSIONS with details.feature set to code_intelligence; handle it as "this workspace needs a plan with Code Intelligence". ask_knowledge_graph has no plan feature. Nobody is billed today.

Repositories are indexed automatically when GitHub is connected and when a repository is added to the installation, and a push to the default branch updates the index incrementally. Connect GitHub on the Integrations page; see GitHub. For how the index is built, see Code intelligence.