MCP server for .NET assembly inspection, decompilation, and analysis using dnlib. Provides tools for inspecting types, methods, fields, IL code, and performing advanced analysis on .NET assemblies.
DnSpyMCP provides 15 tools for .NET assembly inspection and decompilation with consistent naming (verb_noun pattern), reasonable descriptions, and explicit parameter validation. Tool names follow action-first conventions (list_, decompile_, get_, search_, trace_, find_). All tools have input schemas with typed parameters and descriptions. However, there are notable gaps: (1) No output schemas documented, tools return ToolCallResult with text + JSON metadata, but the structure is not formally declared for LLM planning; (2) Limited error guidance, errors include exception messages but rarely guide recovery (no 'Try X instead' patterns); (3) No idempotency semantics declared; (4) Some parameters lack granular constraints (e.g., 'depth' and 'maxDepth' are unbounded integers); (5) Descriptions are functional but generic, they state WHAT but not WHEN to use each tool relative to others. Example: decompile_type, decompile_method, and get_method_il all extract code; the descriptions don't explain when to pick each (IL format vs C#, single method vs type). The server implements proper parameter validation in code (ValidateRequired), but this is not exposed in the schema itself as constraints or enums. All 15 tools are explicitly registered via [McpTool] attributes with schemas, so no inference penalty applies.
Decompile one method into C#. Supports overload selection.
Decompile a type from an assembly into C#.
Compare two types side-by-side to see field offset and signature differences.
Find and resolve enum values. Search by magic number, hex value, partial name, or dump a specific enum.
Scan a class to find all Unity UI component references (Image, Text, TMPro) and custom UI classes, listing methods that modify them.
Get raw IL for one method. Supports overload selection.
Export a type as a C/C++ struct with precise memory padding (_pad) automatically calculated for cheat development.
No output schemas documented. Tools return ToolCallResult(text, jsonObject) but LLMs cannot plan downstream calls without knowing field names, types, and structures. E.g., list_types returns 'text' + JSON with 'assemblyPath', 'typeFullName', etc., but this is not formally declared.
Unbounded numeric parameters invite absurd values. 'depth' in trace_field_consumers, 'maxDepth' in search_by_inheritance, and 'maxResults' in search_members have no min/max constraints in schema. An LLM could pass depth=999999, causing runaway recursion.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | B | 72 | 2025-06-18+ | v2 |
Show base class, interfaces, and type hierarchy for a type.
List fields for a given type with type info and offsets.
List methods for a given type with signatures (helps overload targeting).
List all types in a .NET assembly.
Generate a C++ function pointer typedef matching a game method's signature for MinHook or Frida.
Find all classes that inherit from a base type and optionally filter by field names.
Search matching type/member names inside an assembly.
Trace the full call graph of methods that read or write a specific field. Answers 'Who ultimately uses this field?'
Error responses lack recovery guidance. All tools catch exceptions and return ToolCallResult with ex.Message and ex.StackTrace. No actionable next steps (e.g., 'Try search_members() first to find the type'). Pattern: recovery-guide.
Overlapping tool semantics without disambiguation. decompile_type (full type in C#), decompile_method (single method in C#), and get_method_il (raw IL bytes) all extract code. Descriptions don't explain WHEN to pick each. LLM will guess and may pick wrong tool.
Generic descriptions lack context. E.g., search_members: 'Search matching type/member names inside an assembly.' Does not explain when to use search_members vs list_methods vs list_types. No guidance on discovery workflow.
No result limits declared or enforced. search_members accepts 'maxResults' but no default cap stated in description. list_types could return thousands of types with no mention of result limits or pagination. High-volume results could blow context window.