Skip to main content
Glama

Find Symbols by Attribute

find_by_attribute
Read-onlyIdempotent

Find C# types, methods, properties, and fields by attribute name, including normalized suffix/namespace matches, to locate obsolete, auth, test, or JSON members that name-only searches miss.

Instructions

Find symbols (types, methods, properties or fields) that carry a given ATTRIBUTE - a cross-cutting query that find_symbol (name-only) cannot do. The attribute name is matched format-independently: the last name segment, with an optional 'Attribute' suffix stripped, case-insensitive. So 'Obsolete', 'ObsoleteAttribute' and 'System.ObsoleteAttribute' all match the same symbols (types store the fully-qualified attribute class, methods/properties/fields store the source-syntax name - this reconciles both). The raw stored attribute list travels with each hit so you see the ground truth. kinds = 'all' (default - types + methods + properties + fields) / 'type' / 'method' / 'property' / 'field'. Member scanning surfaces a member-level attribute like a CommunityToolkit '[ObservableProperty]' (on a backing field or a modern partial property) or a '[JsonProperty]' that a type/method-only scan misses. Use it for '[Obsolete]', '[ApiController]', '[Authorize]', test attributes, etc. The 'method' axis includes constructors and accessors with a body (named .ctor / get_X / set_X), so a [JsonConstructor] or an [Obsolete] setter is found. A partial type is one type row; 'fullName' marks namesake type rows (Foo, Foo), 'project' the twin rows of a linked file. Deterministic from Roslyn - works on recalled sessions. Capped at 200.

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>",
      "attribute": "<attribute>"
    },
    "name": "find_by_attribute"
  }
}

Input Schema

NameRequiredDescriptionDefault
kindsNoWhich symbol kinds to search: 'all' (default - types + methods + properties + fields), 'type', 'method', 'property', or 'field'.all
scopeNo'solution' (default) or a namespace prefix (e.g. 'MyApp.Api') to narrow scope.solution
attributeYesThe attribute to find (e.g. 'Obsolete', 'ApiController', 'Fact'). Suffix/namespace are normalized away - required.
sessionIdYesThe session_id returned by analyze_solution. Also takes an absolute .sln/.slnx/.slnf path, analyzed on first use.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv0.5.46513
    • 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.3/5.0
Behavior3/5

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

Annotations already declare readOnlyHint/true, idempotentHint/true and destructiveHint/false, so the safety profile is covered by structured data. The description still adds real context the annotations cannot: deterministic Roslyn resolution, works on recalled sessions, and a hard cap of 200 results. Baseline 3 is appropriate since the added value is moderate rather than deep.

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 scoping constraint are front-loaded, but the middle is dense and repetitive: the kinds values are re-listed even though the schema enumerates them, and attribute examples appear twice ('[Obsolete]', '[ApiController]'). Several clauses about partial types and linked-file twins feel like output detail packed into a sentence that reads as run-on.

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?

No output schema exists, yet the description explains what comes back: the raw stored attribute list travels with each hit, 'fullName' marks namesake type rows and 'project' the twin rows of a linked file, plus the 200-item cap. An agent has enough to call it and interpret the response without guessing.

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 description coverage is 100%, so the baseline would be 3, but the description goes further by spelling out the attribute-name normalization ('Obsolete', 'ObsoleteAttribute', 'System.ObsoleteAttribute' all match) and clarifying that the 'method' axis includes constructors and accessors named .ctor/get_X/set_X. Those semantics are not derivable from the schema alone. The kinds enumeration is largely duplicated from the schema, which keeps it from a 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?

A specific verb plus resource ('Find symbols ... that carry a given ATTRIBUTE') and an explicit contrast with the sibling find_symbol ('a cross-cutting query that find_symbol (name-only) cannot do'). An agent can distinguish it from find_symbol and find_by_semantics without opening a 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?

States when to reach for it and names the alternative it replaces: find_symbol is name-only, this one is attribute-based. Concrete triggers are supplied ('[Obsolete]', '[ApiController]', '[Authorize]', test attributes, '[ObservableProperty]', '[JsonProperty]') and it explains why member scanning is needed when a type/method-only scan misses attributes.

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