Skip to main content
Glama

Find Dead Code

find_dead_code
Read-onlyIdempotent

List dead-code suspects on two axes. kinds='type': types with no incoming reference in the reverse type fan-in, the source find_usages reads. kinds='method' (the default): PRIVATE methods whose recorded caller list is empty.

Instructions

List dead-code suspects on two axes. kinds='type': types with no incoming reference in the reverse type fan-in, the source find_usages reads. kinds='method' (the default): PRIVATE methods whose recorded caller list is empty. kinds='all': both.

The default axis skips a private method a framework may call ([RelayCommand] or other framework attributes, partial methods, markup or designer event handlers, static Main, record PrintMembers, ShouldSerialize/Reset) or whose callers were not measured (unresolved references, explicit interface implementations). A nameof in a method's attribute (CanExecute) is a call. *.Designer.cs and *.g.cs files are read for references, never judged.

Returns scope, a 'note' first when there is one, methodsScanned, deadMethods and - when the type axis ran - typesScanned and deadTypes: at most 200 items each (methods: name, declaringType, namespace; types: name, kind, accessibility, namespace, and publicApi:true on a library's public type: outside consumers go unseen, see publicApiNote). Counters, each omitted at zero: what was not judged - methodsIneligible and typesIneligible, each split by reason (methodsIneligibleNotPrivate, -FrameworkInvoked, -UnanalyzedCallers; typesIneligibleStructural, -TestScaffolding, -FrameworkActivated, -MarkupReferenced), typesUnexamined (what the type axis would have judged had it run) - and the candidates the test filter removed, testMethodsFiltered and testTypesFiltered.

A listed candidate is a suspect: the note names what a zero fan-in does not prove and how to confirm one. The type axis exempts what it cannot see being used: interfaces, static classes, *Extensions types, test scaffolding, framework- or reflection-activated and markup-referenced types. An empty answer without a note means at least one axis judged an eligible population and found nothing; for the method axis read methodsIneligible against methodsScanned.

Read-only; works on a recalled session. Test projects are excluded by default. Any other non-blank kinds value runs both axes.

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": {
      "sessionId": "<sessionId>"
    },
    "name": "find_dead_code"
  }
}

Input Schema

NameRequiredDescriptionDefault
kindsNo'method' (default): private methods with a measured, empty caller list - see the description for what that axis does not judge; 'type': types with no incoming reference; 'all': both.method
scopeNo'solution' (default) or a namespace prefix (e.g. 'MyApp.Core') to narrow scope.solution
sessionIdYesThe session_id returned by analyze_solution. Also takes an absolute .sln/.slnx/.slnf path, analyzed on first use.
includeTestsNoInclude test-project methods/types (default false - production dead-code; a private test-helper without callers is not production dead code).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changedv0.5.46513
    • changedInput schema / properties / kinds / description
      Previous value: -"'method' (default) private methods with no caller · 'type' types with no incoming reference · 'all' both."New value: +"'method' (default): private methods with a measured, empty caller list - see the description for what that axis does not judge; 'type': types with no incoming reference; 'all': both."
    • changedInput schema / properties / sessionId / description
      Previous value: -"The session_id returned by analyze_solution."New value: +"The session_id returned by analyze_solution. Also takes an absolute .sln/.slnx/.slnf path, analyzed on first use."
  2. First observed

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already declare read-only/idempotent/closed-world, and the description still adds substantial behavior beyond them: what the default axis deliberately skips (framework attributes, partial methods, Main, PrintMembers), that nameof in an attribute counts as a call, that designer/generated files are read but never judged, the 200-item cap, and the meaning of the counters and publicApi. Nothing about how the tool behaves is left implicit.

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?

The opening sentence is well front-loaded, but the body is a dense, run-on block with stacked parentheticals and enumerations that repeat schema-level facts (the kinds values are already described in the schema). For a four-parameter tool it is overlong and visually unstructured, even though most sentences carry genuine detail.

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, yet the description enumerates the return shape (scope, note, methodsScanned, deadMethods, typesScanned/deadTypes, eligibility counters) and explains the zero-omission rule. Combined with the disclosed exclusion rules and the empty-answer interpretation, an agent has everything needed to call and interpret 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?

Schema coverage is 100%, so the baseline is 3, but the description adds real semantics: the precise inclusion criteria behind kinds='method', the fact that an unrecognized kinds value falls back to both axes (a behavior not visible in the schema), and the intent of scope and includeTests. That is meaningful added meaning on top of the schema rather than duplication.

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

Purpose5/5

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

Opens with a concrete verb+resource ('List dead-code suspects') and immediately partitions the resource into two named axes with their own definitions. It also positions itself relative to the sibling it consumes ('the reverse type fan-in, the source find_usages reads'), so an agent knows what it is and how it relates to neighboring tools.

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?

Gives explicit selection guidance for the main knob: kinds='method' is the default, kinds='type' runs the other axis, kinds='all' runs both, and any other non-blank value runs both. It also explains the empty-result semantics and how to confirm a suspect. It stops short of saying when to prefer this tool over siblings like coverage_gaps or impact_of_change, so it is strong context without full alternative routing.

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