Skip to main content
Glama

Find callers (reverse dependencies)

find_callers
Read-onlyIdempotent

Find all code that references, calls, extends, or implements a specific function, method, or class to assess refactoring impact and detect dead code.

Instructions

Read-only reverse dependency lookup. Use this to find all code that references, calls, extends, or implements a specific entity. Answers 'who uses this code?' by querying the graph database. Differs from search tools by providing exact dependency tracking.

Usage: Use for impact analysis before refactoring or to detect dead code. Do NOT use this for semantic feature discovery—use 'search_hybrid_context' instead.

Matching is precedence-based: exact FQN (containing '.' or '::') → FQN suffix (Type.member) → exact name → signature prefix (accept(List) → name prefix (queries under 4 characters) → fuzzy substring (queries of 4+ characters). A trailing parameter list of types addresses one overload: 'Foo.bar(int, int)' resolves 'Foo.bar' through the tiers above and keeps only the overloads whose declared parameter types match (simple type names; generic arguments compared only when written; 'name: Type' accepted); when none matches, the response lists the declared overloads. Overloads sharing an FQN are labelled by their parameter list in the target list and '### Target:' headers. The first tier that matches wins, so an exact name never returns fuzzy noise. Queries shorter than 4 characters resolve by anchored name prefix instead of substring, avoiding substring noise on short strings. Pass a qualified name (Namespace.Type.Member) to disambiguate homonyms. Responses state which tier matched and flag fuzzy results explicitly.

Behaviour & Return: Read-only graph traversal with no side effects. Returns Markdown grouped by relationship type (Calls, Extends, Implements, References, Overridden by, Overrides, Dispatched calls) with exact file paths and line numbers. When every reference and target belongs to one repository, the 'Found N reference(s)' line names it once as (repo: name); otherwise each caller entry and each resolved target states its repository, so rows are attributable when multiple repositories are in scope. For JVM code (Java/Kotlin/Groovy) and C#, 'Overridden by' lists method implementations/overrides in subtypes and 'Overrides' lists the supertype methods a method implements/overrides. 'Dispatched calls' lists callers bound to an override or to a supertype method of the target (dynamic dispatch), each under the method it is statically bound to, so an interface method called only through its implementation is never reported as unused. When the query resolves to more than one entity with that name (homonyms, e.g., 'find_nearest_entity_by_line' in orphans.rs vs rust.rs), results are grouped by target entity showing which specific target each caller references — even when only one of the homonyms has callers. Each caller entry is one line: name, kind, file_path:line_number and, when it is not empty, its signature. When multiple targets exist, each group shows the target's location and signature. References made from test code (test files, Rust #[cfg(test)]) are included in every count but listed only with include_tests=true; each group then ends with '+N in tests'. A file's <module> row (its import) is folded into the other rows of that file.

Entity-kind scope: target resolution is code-only by default — documentation, configuration, build-system and Kubernetes/Helm metadata (markdown_section, config_property, build_dependency, cargo_package, project_identity, k8s_*, helm_*, …) can never be presented as resolved targets. When the filter removed matches, the response says so ('Non-code matches hidden — N entities …'), never silently. Pass kinds='all' (or '*') to disable the filter, or a comma-separated allow-list of exact kinds/aliases ('callable', 'config', 'docs', 'rust_function', 'build_dependency', …) to scope resolution explicitly. The response's resolution.kind_filter field states which scope applied ('code_default', 'any', 'explicit').

Relationship coverage: the buckets cover every edge type the pipeline produces — Calls, Extends, Implements, References, Macro calls (MACRO_CALLS), DOM references (JS → HTML id), CSS class usage (JS → CSS class), script/stylesheet imports, the VCL edges (uses backend/probe/acl, includes, imports vmod, declared-unused) and HTTP routes (ROUTES_TO: the endpoint serving a handler) — plus Overridden by / Overrides / Dispatched calls, and 'HTTP callers (heuristic: client call → endpoint)': the HTTP client calls (OpenFeign, MicroProfile REST Client, Spring @HttpExchange, RestTemplate, WebClient, RestClient; test code excluded) of any indexed repository linked to the target endpoint or handler by HTTP_CALLS — matched by verb, path, service name and context path, never linked when several endpoints match equally well.

Truncation & completeness: the queried name is first resolved to concrete targets (capped at 25 by default). When more targets match than fit the cap, the response states 'Truncated — N targets matched; showing the first M by FQN' and 'Counts below are partial — they cover only the M of N targets shown', so bucket counts are never mistaken for the complete impact set. Raise 'max_targets' (up to 500) to retrieve more targets when the notice reports truncation.

Parameter guidance: 'entity_name' supports exact names or signature fragments (e.g., 'handleRequest' or 'handle(Request'). Include 'repo_name' to filter results to the specific codebase being analyzed.

Supports Java, Kotlin, C#, Rust, and TypeScript codebases.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "entity_name": "<entity_name>"
    },
    "name": "find_callers"
  }
}

Input Schema

NameRequiredDescriptionDefault
kindsNoOptional entity-kind scope for target resolution. Omit for the default code-only scope (docs/config/build metadata are hidden from the target list and the response discloses them). Use 'all' (or '*') to disable filtering, or a comma-separated allow-list of exact kinds or aliases ('callable', 'class', 'config', 'docs', 'rust_function', 'build_dependency', ...).
repo_nameNoOptional but HIGHLY RECOMMENDED: repository scope. Accepts a single repository name (`'my-repo'`), a comma-separated list (`'repo-a,repo-b'`), or `'all'` (or `'*'`) to query every indexed repository. If you know the repository you are working on, include it in your FIRST query to avoid mixed results from other indexed projects. Omit to search across all repositories.
entity_nameYesThe name of the function, method, or class to find callers for
max_targetsNoMaximum number of resolved targets to include (default: 25, max: 500). Raise this when the response reports a truncated target list and you need the complete impact set.
include_testsNoList the references made from test code (test files, Rust #[cfg(test)]) instead of only counting them. Default false: counts always include them.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv1.15.1
    • addedInput schema / properties / include_tests
      Added value: +{
      +  "description": "List the references made from test code (test files, Rust #[cfg(test)]) instead of only counting them. Default false: counts always include them.",
      +  "type": [
      +    "boolean",
      +    "null"
      +  ]
      +}
  2. Changed2 schema fields changedv1.9.6
    • addedInput schema / properties / kinds
      Added value: +{
      +  "description": "Optional entity-kind scope for target resolution. Omit for the default code-only scope (docs/config/build metadata are hidden from the target list and the response discloses them). Use 'all' (or '*') to disable filtering, or a comma-separated allow-list of exact kinds or aliases ('callable', 'class', 'config', 'docs', 'rust_function', 'build_dependency', ...).",
      +  "maxLength": 1024,
      +  "minLength": 1,
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / max_targets
      Added value: +{
      +  "default": 25,
      +  "description": "Maximum number of resolved targets to include (default: 25, max: 500). Raise this when the response reports a truncated target list and you need the complete impact set.",
      +  "maximum": 500,
      +  "minimum": 1,
      +  "type": [
      +    "integer",
      +    "null"
      +  ]
      +}
  3. Changed1 schema field changedv1.9.4
    • changedInput schema / properties / repo_name / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
  4. Changed1 schema field changedv1.8.1
    • changedInput schema / properties / repo_name / description
      Previous value: -"Optional but HIGHLY RECOMMENDED: repository name to filter results to a specific codebase (e.g., 'my-java-repo'). If you know the repository you are working on, include this in your FIRST query to avoid mixed results from other indexed projects. Omit only to search across all repositories."New value: +"Optional but HIGHLY RECOMMENDED: repository scope. Accepts a single repository name (`'my-repo'`), a comma-separated list (`'repo-a,repo-b'`), or `'all'` (or `'*'`) to query every indexed repository. If you know the repository you are working on, include it in your FIRST query to avoid mixed results from other indexed projects. Omit to search across all repositories."
  5. Addedv1.4.0
  6. Removedv1.3.8
  7. Added
  8. Removedv1.3.2
  9. Addedv1.2.8
  10. Removedv1.2.7
  11. Addedv0.8.4
  12. Removedv1.0.0
  13. First observedv0.1.0

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already cover safety (readOnlyHint, idempotent, non-destructive), yet the description adds substantial non-duplicative behavior: precedence-based matching tiers, what each response bucket means, the 25-target cap with an explicit truncation notice, repo attribution rules, heuristic HTTP-caller linking, and the code-only entity-kind default with disclosure when filtering removes matches. This is exactly the context annotations cannot express.

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

Conciseness3/5

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

Purpose and usage are correctly front-loaded and labeled sections help navigation, but the body balloons into an exhaustive catalogue of every edge type and HTTP-client framework, plus repeated explanations of overload matching, truncation, and homonym grouping. Much of that is reference material an agent only needs after the first call, so it dilutes the actionable guidance.

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?

There is no output schema, so the description must carry the return contract, and it does: Markdown grouped by relationship type, one-line caller entries with file_path:line, '### Target:' headers for overloads, '+N in tests' markers, and resolution.kind_filter. Combined with the truncation and hiding-disclosure rules, an agent knows precisely what it will get back.

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 baseline is 3, but the description genuinely adds meaning: entity_name accepts signature fragments and qualified names to disambiguate homonyms, repo_name scopes results, max_targets raises the cap when truncation is reported, and kinds toggles the code-only default. Some of this (the kinds and max_targets restatement) overlaps the schema, which keeps it below 5.

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?

Opening sentence gives a specific verb+resource ('reverse dependency lookup') and enumerates exactly what counts as a caller (references, calls, extends, implements). It explicitly contrasts itself with search tools ('Differs from search tools by providing exact dependency tracking'), so an agent can separate it from search_hybrid_context without reading 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?

Provides positive conditions ('impact analysis before refactoring', 'detect dead code') and an explicit exclusion with a named alternative ('Do NOT use this for semantic feature discovery—use search_hybrid_context instead'). This is the when/when-not/alternative trifecta.

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