If your agent only learns one tool, make it this one. get_context
absorbs what would otherwise be five or six separate calls (file
docs, symbol signatures, ownership, last-change history, callers and
callees, centrality metrics, community membership, and freshness) into
a single call with a configurable include list. Pass multiple targets
at once.
This is not a source-body tool. There is no include=["source"]:
the triage card returns signatures, not bodies. For a whole file, ask
for it in one call with include=["skeleton"] (body-elided, every
signature, the most central symbols in full), or just Read it. Reach
for get_symbol for a single body a response
already named, never per signature in a loop.
When to call
- After
get_answerto verify or expand on cited files. - Before editing any file: check ownership, dependents, freshness, and governing decisions.
- Architectural questions: pair with
include=["metrics", "community"]to see centrality and cluster membership. - Always batch: one call with five targets is far cheaper than five calls with one target each.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
targetsrequired | string[] | — | File paths, module paths, or qualified symbol IDs (e.g. "src/auth/service.py::verify_token"). Pass as many as you need. |
include | string[] | ["docs", "freshness"] | Blocks to include, on top of the always-on "docs" and "freshness". Options: "full_doc", "ownership", "last_change", "callers", "callees", "metrics", "community", "decisions", "skeleton" (file targets only). No "source" option: this tool returns no source bytes, ever. |
compact | boolean | true | True returns signatures only (lighter). False adds the structure block, docstrings, and imported_by. |
repo | string | — | Repository alias. Usually omitted. |
Returns
The response is a targets map keyed by the target string. Each entry contains:
| Block | What it gives you |
|---|---|
docs | Wiki title, summary, and symbols list (name, kind, signature, line, docstring). Adds structure block and imported_by for files; child file pages for modules; qualified_name, used_by, candidate matches for symbols |
full_doc | Same as docs but with the full page content_md |
ownership | primary_owner, owner_pct, contributor_count, bus_factor, plus recent_owner if the active maintainer differs from the historical primary |
last_change | ISO date, author, days ago |
callers / callees | For a symbol target: up to 50 each, filtered to confidence ≥ 0.7. Each entry: symbol_id, name, kind, file, line, confidence, edge_type. For a file target: a rolled-up view instead, capped at 20, with a different shape: {file, imports?, inbound_calls?} (imports: true when that file imports this one, inbound_calls counting cross-file call edges into any symbol this file defines) |
metrics | pagerank, pagerank_percentile, betweenness, betweenness_percentile, in_degree, out_degree, community_id, community_label |
community | id, label, cohesion, top_members, neighbors with cross-edge counts |
freshness | confidence_score, freshness_status, is_stale |
hotspot | Always on. true when the target is a churn hotspot; a cue to follow up with get_risk |
fix_history | Always on, appears only on files with counted bug fixes: count, age, and a bug_magnet flag |
episodes | Always on. Count of dated episode records bound to this target |
decisions | Governing architectural decision records (if any); default returns titles only, include=["decisions"] returns full records |
skeleton | (file targets) The file with bodies elided: every signature, the import preamble, and the bodies of only the most central symbols (ranked by symbol PageRank / hotspot / query match), token-budgeted. Typically ~15% of the full file's tokens. Elision markers carry 1-indexed line ranges so anything can be range-read back |
Top-level fields:
truncated:trueif output was capped at the token budget.dropped_targets,dropped_symbols: what got evicted when the budget was exceeded._meta.omitted: when anything was dropped, the refs to get it back:{ refs, tokens, restore }. Resolve withrepowise expand <ref>from a shell orget_symbol("repowise#<ref>")from any MCP client; truncation is no longer silent.
Example
get_context(["src/auth/service.py"])
get_context(
["src/auth/service.py::verify_token"],
include=["callers"],
)
get_context(
["src/auth/", "src/payments/"],
include=["ownership", "metrics", "community"],
)
# Structure-level view of a large file at ~15% of the tokens
get_context(["src/big_module.py"], include=["skeleton"])Things worth knowing
- Token budget enforcement: ~8000 tokens (~32k chars) global cap. Truncation happens in stages: (1) strip heavy doc fields, (1.5) strip skeleton texts, largest first, (2) shrink symbol lists keeping query-matched symbols first, (3) drop whole targets. Largest targets are evicted first.
- Symbol prioritisation: within a target, symbols are ranked by exact name match → substring match → kind (class > function > method) → centrality. Navigationally important symbols survive truncation.
- Target resolution order: file_page → module_page → symbol
(exact then fuzzy) → file by
target_path. If none match, returns fuzzy path suggestions. freshnessis included by default: critical for the agent to detect stale indices.ownershipandlast_changeadd 200 to 500 bytes each; omit them on multi-turn sessions to save the cache.- Cross-repo enrichment (workspace mode): appends co-change partners and contract links (HTTP routes, gRPC services, topics) from other repos for files in a multi-repo workspace.
Pattern that works well: call get_answer first, then
get_context(targets=fallback_targets, include=["ownership", "last_change"])
on whatever the answer cited. Two calls, complete picture.