dotnet-decompiler-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@dotnet-decompiler-mcpdecompile MyNamespace.MyClass from MyApp.dll"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
dotnet-decompiler-mcp
An MCP server that decompiles and inspects .NET assemblies to C# source, wrapping the ICSharpCode.Decompiler engine (ILSpy, v9.0.0.7889) behind a set of callable tools.
Point an MCP client at any .NET DLL and ask an LLM to "decompile Foo.Bar,
then list its public methods" — it returns structured results (C# source, type
summaries, symbol matches) the model can reason over.
What it does
Decompile a whole type or a single member to readable C# source (with comments — the ILSpy "gold standard" output).
Inspect an assembly: list types, list namespaces with counts, get a detailed member summary of one type (methods, fields, properties, events, attributes, base type).
Search for symbols by name across one or more assemblies (case-insensitive substring, filterable by kind).
A
check_envdiagnostic tool reports the active Python, .NET runtime, and engine version.
All .NET access is via reflection through pythonnet on CoreCLR; no .NET SDK install is required on the host beyond the runtime.
Related MCP server: GhidraMCP
Requirements
Python ≥ 3.14
.NET 8 runtime on the host (the decompiler targets
net8.0; the bundled CoreCLR runtime pack is8.0.6, the minimum host runtime is8.0.17).uv to run the project.
Install
git clone <repo-url> dotnet-decompiler-mcp
cd dotnet-decompiler-mcp
uv syncThe ILSpy engine DLL ships in lib/ICSharpCode.Decompiler.dll — nothing else
to download.
Environment variables
These are set automatically at runtime by the bootstrap
(runtime/clr.py); you normally do not need to configure them. They are listed
for completeness / troubleshooting.
Variable | Value | Purpose |
|
| Selects CoreCLR over Mono. |
| path to a temp | Tells CoreCLR which framework ( |
If the runtime fails to start, run check_env (below) — it reports the
resolved versions.
MCP client registration
The server speaks MCP over stdio. Register it with any MCP client.
ZCode / OpenCode (.zcode/config.json)
{
"mcp": {
"servers": {
"dotnet-decompiler": {
"type": "stdio",
"command": "uv",
"args": [
"run",
"--project",
"/absolute/path/to/dotnet-decompiler-mcp",
"python",
"-m",
"dotnet_decompiler_mcp"
],
"env": {}
}
}
}
}Write this to the workspace .zcode/config.json or the user-level
~/.zcode/v2/config.json, then restart the client.
Generic mcpServers (Claude Desktop and others)
{
"mcpServers": {
"dotnet-decompiler": {
"command": "uv",
"args": [
"run",
"--project",
"/absolute/path/to/dotnet-decompiler-mcp",
"python",
"-m",
"dotnet_decompiler_mcp"
]
}
}
}You can also run it directly to smoke-test the stdio server:
uv run python -m dotnet_decompiler_mcpIt should start without errors and wait on stdin. Ctrl+C to exit.
Tools
Seven tools are registered. asm_paths (where present) is an optional list of
extra assembly search directories used to resolve cross-DLL references; pass it
when the target assembly depends on types in other DLLs.
Tool | Arguments | Returns | Purpose |
| (none) |
| Startup diagnostics: Python, .NET runtime, engine version, lib dir. |
|
|
| Decompile a whole type to C# source. |
|
|
| Decompile a single method/field/property/event. |
|
|
| List types, optionally filtered by namespace prefix. |
|
|
| Distinct namespaces with type counts. |
|
|
| Detailed public-member breakdown of one type. |
|
|
| Case-insensitive symbol search across one or more DLLs. |
Notes:
type_nameis a fully-qualified, case-sensitive name (e.g.ICSharpCode.Decompiler.DecompilerSettings).namespaceis a prefix filter —ICSharpCodematchesICSharpCode.Decompilerbut notICSharpCodeX; empty string = all types.search_symbolkindis one oftype/method/field/property/event/any(defaultany).
Usage examples
These target the engine DLL bundled in lib/ — the same cases the test suite
pins, so they are known to work. Replace the path with any .NET assembly you
want to explore.
check_env
→ EnvInfo(decompiler_version="9.0.0.7889", net_tfm_target="net8.0", ...)
decompile_type("lib/ICSharpCode.Decompiler.dll",
"ICSharpCode.Decompiler.DecompilerSettings")
→ DecompileResult(source="public class DecompilerSettings : ...", ...)
decompile_member("lib/ICSharpCode.Decompiler.dll",
"ICSharpCode.Decompiler.DecompilerSettings",
"GetMinimumRequiredVersion")
→ MemberDecompileResult(source="public static Version ...", ...)
get_type_summary("lib/ICSharpCode.Decompiler.dll",
"ICSharpCode.Decompiler.DecompilerSettings")
→ TypeSummary(base_type="System.Object",
events=[EventInfo(name="PropertyChanged", ...)], ...)
search_symbol(["lib/ICSharpCode.Decompiler.dll"], "GetMinimum", kind="method")
→ SearchResult(matches=[SymbolMatch(kind="method",
name="GetMinimumRequiredVersion", type="...DecompilerSettings")])Errors
The engine raises typed exceptions; the tool layer does not catch them, so
they surface to the MCP client as is_error responses with the exception
message. All engine errors inherit from DecompilerError.
Error | Meaning |
| The |
|
|
|
|
| A reflected .NET call raised; the original exception text is appended as |
| An argument was rejected (e.g. an unknown |
Development
uv run pytest # 65 tests (incl. real-.NET integration tests)
uv run ruff check # lint (D/E/F/W, Google docstring convention)Architecture
Four one-way layers, no cycles:
config.py constants (single source of truth)
runtime/ CoreCLR bootstrap via pythonnet (init_runtime, ensure_initialised)
engine/ CSharpDecompiler reflection wrappers (cache, decompile, metadata, version, errors)
tools/ thin async wrappers (list[str]|None -> tuple|None), errors bubble up
server.py FastMCP assembly + tool registration
models/ Pydantic response DTOs (anemic, serialization only)Dependency direction: server → tools → engine → runtime/models/config.
Status
Milestones M0–M4 complete: runtime bootstrap, decompile (type/member), inspect (list/summary) + search, error handling, and documentation.
Available Tools
7 toolscheck_envA
Startup diagnostics: verify runtime / DLL / versions are ready.
Checks that the .NET runtime (CoreCLR) is loaded, the bundled
ICSharpCode.Decompiler.dll is present in lib/, and returns
version info for all components.
The asm_search_dirs field shows which directories the decompiler
searches automatically for dependency resolution — typically the
lib/ folder. The target DLL's own directory is also always searched.
Example::
check_env()
# Returns: {"python_version": "3.14.3", "decompiler_version": "9.0.0.7889", ...}Returns: EnvInfo: Python version, .NET runtime version, decompiler version, and library directory status.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| python_version | Yes | |
| python_executable | Yes | |
| net_runtime_version | Yes | |
| net_tfm_target | Yes | |
| decompiler_version | Yes | |
| lib_dir | Yes | |
| lib_present | Yes | |
| asm_search_dirs | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Covers key behaviors: checks runtime and DLL presence, returns version info, explains asm_search_dirs. No annotation contradictions. Could mention it's non-destructive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with example and returns section. Front-loaded purpose. Slightly verbose but earned.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, behavior, return values, and field meanings. Output schema exists; description complements it. Fully sufficient for a parameterless diagnostic tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters, so baseline 4 applies. Description adds value with example output and field descriptions beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Startup diagnostics: verify runtime / DLL / versions are ready', specifying a unique diagnostic purpose distinct from sibling tools that handle decompilation and symbol search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implied as startup diagnostics but lacks explicit guidance on when to use versus alternatives. No mention of prerequisites or when not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
decompile_memberA
Decompile a single member (method/field/property/event/ctor) to C#.
Lighter than decompile_type — use this when you only need one method
or property from a large type.
Tip: run get_type_summary first to see available member names.
Examples::
# Decompile a method
decompile_member(
dll="Backend/GameData.dll",
type_name="GameData.Domains.Character.Character",
member_name="ChangeHealth",
)
# Decompile a constructor
decompile_member(
dll="Managed/Assembly-CSharp.dll",
type_name="Game.Views.Combat.ViewCombat",
member_name=".ctor",
)
# Decompile a property getter
decompile_member(
dll="Backend/GameData.dll",
type_name="GameData.Domains.Combat.CombatCharacter",
member_name="get_Name",
)Args:
dll (str): Absolute path to the assembly.
type_name (str): Fully-qualified owning type name (case-sensitive).
member_name (str): Simple member name, e.g. ToString,
ChangeHealth, .ctor (constructor), get_Name.
asm_paths (list[str] | None): Extra directories for dependency
resolution. Almost always None — see decompile_type.
Returns: MemberDecompileResult: The member's C# source plus metadata.
Raises:
DllNotFoundError: dll does not exist.
TypeNotFoundError: type_name not found.
MemberNotFoundError: member_name not found on the type.
DecompilationFailedError: Internal decompiler error.
| Name | Required | Description | Default |
|---|---|---|---|
| dll | Yes | ||
| type_name | Yes | ||
| member_name | Yes | ||
| asm_paths | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| source | Yes | |
| type | Yes | |
| member | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. While it lists raised exceptions (DllNotFoundError, etc.), it does not explicitly state the tool is read-only or mention any side effects. The behavior is implied but could be more explicit regarding permissions or effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is moderately lengthy but well-structured with sections for summary, tip, examples, args, returns, and raises. Each sentence adds value, though some duplication could be trimmed slightly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the input schema lacks descriptions, the description covers all necessary aspects: purpose, usage, parameters, return type (via output schema existence), and possible exceptions. It is complete and self-contained for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, but the description compensates with a detailed 'Args' section explaining each parameter (dll, type_name, member_name, asm_paths). Examples illustrate usage, adding substantial meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it decompiles a single member (method/field/property/event/ctor) to C#. It distinguishes itself from the sibling tool `decompile_type` by being lighter and targeting a single member, which provides specificity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says to use this tool when only one method or property from a large type is needed, contrasting it with `decompile_type`. It also suggests running `get_type_summary` first to find member names, providing clear context on when to use and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
decompile_typeA
Decompile a whole .NET type to C# source (with comments).
The decompiler automatically resolves dependencies from the target DLL's
own directory and the bundled lib/ folder, so asm_paths is almost
never needed for typical Unity/Godot games.
Tip: use list_types first to discover available types, then pass the
exact namespace.TypeName here.
Examples::
# Decompile an entire class
decompile_type(
dll="Backend/GameData.dll",
type_name="GameData.Domains.Character.Character",
)
# Decompile an enum
decompile_type(
dll="Backend/GameData.dll",
type_name="GameData.Domains.Combat.CombatCharacterStateType",
)Args:
dll (str): Absolute path to the assembly (.dll or .exe).
type_name (str): Fully-qualified type name, case-sensitive,
e.g. GameData.Domains.Taiwu.TaiwuDomain.
asm_paths (list[str] | None): Extra directories for dependency
resolution. The DLL's own folder and the bundled lib/ are
searched automatically, so this can almost always be None.
Only needed when a referenced assembly lives outside those paths.
Returns: DecompileResult: The decompiled C# source plus type/dll metadata.
Raises:
DllNotFoundError: dll does not exist or is not readable.
TypeNotFoundError: type_name was not found (check spelling/case).
DecompilationFailedError: Decompiler encountered an internal error.
| Name | Required | Description | Default |
|---|---|---|---|
| dll | Yes | ||
| type_name | Yes | ||
| asm_paths | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| source | Yes | |
| type | Yes | |
| dll | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description carries full burden. It discloses automatic dependency resolution, specific error types raised, and that output includes decompiled source plus metadata. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with a clear summary, tips, examples, and parameter descriptions. Slightly verbose due to examples and detailed parameter text, but the organization makes it easy to parse. Could be trimmed slightly without losing value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (3 params, output schema exists, sibling tools), the description is very complete. It covers usage, behavior, parameter semantics, error handling, and return values (via output schema). No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so description compensates thoroughly. It explains each parameter: 'dll' (absolute path), 'type_name' (fully-qualified, case-sensitive, with examples), and 'asm_paths' (optional, default None, when needed). Adds significant meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Decompile a whole .NET type to C# source (with comments),' specifying the verb (decompile), resource (.NET type), and output (C# source). It distinguishes from sibling tools like 'decompile_member' and 'list_types' by focusing on whole type decompilation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance: use 'list_types' first to discover types, pass exact 'namespace.TypeName', and notes that 'asm_paths' is almost never needed due to automatic dependency resolution. This helps the agent choose when and how to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_type_summaryA
Get a detailed member summary of a single type (public members only).
Shows all public methods, fields, properties, and events with their
signatures. Use this to find the exact member name before calling
decompile_member.
Example::
get_type_summary(
dll="Backend/GameData.dll",
type_name="GameData.Domains.Character.Character",
)
# Returns all ~800 public methods with their signaturesArgs:
dll (str): Absolute path to the assembly to inspect.
type_name (str): Fully-qualified type name (case-sensitive),
e.g. GameData.Domains.Character.Character.
asm_paths (list[str] | None): Extra dependency dirs (almost never
needed — see decompile_type).
Returns: TypeSummary: Base type, attributes, and public member lists (methods/fields/properties/events).
Raises:
DllNotFoundError: dll does not exist.
TypeNotFoundError: type_name not found (check spelling/case).
| Name | Required | Description | Default |
|---|---|---|---|
| dll | Yes | ||
| type_name | Yes | ||
| asm_paths | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| type | Yes | |
| base_type | Yes | |
| attributes | Yes | |
| methods | Yes | |
| fields | Yes | |
| properties | Yes | |
| events | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses public-only members, includes signatures, lists exceptions (DllNotFoundError, TypeNotFoundError), and describes return type. Could mention caching or performance, but not required for this static tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with summary, example, Args, Returns, Raises. Front-loaded with purpose. No fluff. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no annotations and 0% schema coverage, the description is complete: covers tool purpose, parameter details, return type, errors, and usage context. Output schema exists but description still provides useful summary.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 0% description coverage, but the description adds full semantics: dll is absolute path, type_name is fully-qualified case-sensitive, asm_paths is extra dependency dirs (almost never needed). This adds significant meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it gets a detailed member summary of a single type (public members only), lists what it returns (methods, fields, properties, events), and provides an example. It distinguishes itself from siblings like decompile_member and decompile_type.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says to use this tool to find exact member names before calling decompile_member. Provides an example and notes that asm_paths is almost never needed, with alternative tools listed in siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_namespacesA
List distinct namespaces in an assembly with their type counts.
Use this as the first step when exploring an unknown game/mod DLL: it
shows you what high-level modules exist (e.g. GameData.Domains.Combat,
Game.Views.Building) and how many types each contains.
Example::
list_namespaces(dll="Backend/GameData.dll")
# Returns: [{"name": "GameData.Domains.Combat", "count": 177}, ...]Args:
dll (str): Absolute path to the assembly to inspect.
asm_paths (list[str] | None): Extra dependency dirs (almost never
needed — see decompile_type).
Returns: NamespaceListResult: Namespaces (sorted by name) and total type count.
Raises:
DllNotFoundError: dll does not exist or is not readable.
| Name | Required | Description | Default |
|---|---|---|---|
| dll | Yes | ||
| asm_paths | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| namespaces | Yes | |
| total_types | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description fully bears the burden. It discloses error conditions (DllNotFoundError), return format (NamespaceListResult with sorted namespaces and total count), and the dll parameter requirement (absolute path, readable file). This is comprehensive and beyond minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with example and parameter docs, but it is somewhat verbose with the docstring format including Args/Returns/Raises. Could be slightly tighter without losing clarity, but earns high marks for organization.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema so return values are covered by that; the description adds error handling and parameter constraints. Given the tool's moderate complexity and the presence of an output schema, the description is complete and leaves no gaps for an AI agent to misinterpret.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description adds full meaning: dll is 'Absolute path to the assembly to inspect' and asm_paths is 'Extra dependency dirs (almost never needed — see decompile_type)'. This compensates entirely for the schema's lack of descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists distinct namespaces with type counts, using specific verbs and resources. It distinguishes itself from siblings by positioning it as the first step for exploring unknown DLLs, unlike list_types, decompile_type, etc.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises use as a first step for exploring unknown game/mod DLLs and provides an example. It also notes when asm_paths is rarely needed and directs to decompile_type for context, giving clear guidance on when to use and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_typesA
List types in an assembly, optionally filtered by namespace prefix.
The namespace filter is a prefix match: "GameData.Domains"
matches GameData.Domains.Character, GameData.Domains.Combat, etc.
Pass "" (default) to list all types — but beware that large games
(e.g. Unity Assembly-CSharp.dll) may have 5000+ types.
Recommended exploration flow::
1. list_namespaces(dll) → see available namespaces
2. list_types(dll, namespace="Foo") → see types in that namespace
3. get_type_summary(dll, "Foo.Bar") → inspect a type's members
4. decompile_type(dll, "Foo.Bar") → get full C# sourceExamples::
# All types in a DLL (may be large)
list_types(dll="Backend/GameData.dll")
# Only types under a specific namespace
list_types(
dll="Backend/GameData.dll",
namespace="GameData.Domains.Combat.Ai",
)Args:
dll (str): Absolute path to the assembly (.dll or .exe).
namespace (str): Namespace prefix filter. "" lists all types.
asm_paths (list[str] | None): Extra dependency dirs (almost never
needed — see decompile_type).
Returns: TypeListResult: Matching types (name, namespace, base type, member counts) with total/filtered counts.
Raises:
DllNotFoundError: dll does not exist or is not readable.
| Name | Required | Description | Default |
|---|---|---|---|
| dll | Yes | ||
| namespace | No | ||
| asm_paths | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| dll | Yes | |
| total | Yes | |
| filtered | Yes | |
| types | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, but description fully discloses behavior: namespace filter is prefix match, default lists all types (potentially large), asm_paths purpose, exceptions like DllNotFoundError, and return type summary. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear sections: purpose, filter explanation, warnings, workflow, examples, Args/Returns/Raises. Each sentence adds value. Front-loaded with main action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Comprehensive coverage: purpose, usage, parameters, return type, errors, workflow integration. Output schema exists but description still summarizes return. No gaps given tool complexity and sibling context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but description adds full meaning: dll is absolute path, namespace is prefix filter with default '', asm_paths is optional dependency dirs. Clarifies types and defaults beyond schema titles.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'List types in an assembly, optionally filtered by namespace prefix.' Verb 'list' and resource 'types in an assembly' are specific. Differentiates from siblings like list_namespaces (lists namespaces) and decompile_type (decompiles).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a recommended exploration flow (list_namespaces -> list_types -> get_type_summary -> decompile_type), warns about large results with empty filter, and gives concrete examples. Explains when to use namespace filter and that asm_paths is rarely needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_symbolA
Search for symbols by name across one or more assemblies.
Matching is case-insensitive substring on the symbol name. You can
search a single DLL or multiple at once — useful when you're not sure
which assembly contains a type (e.g. ["GameData.dll", "Assembly-CSharp.dll"]).
Examples::
# Search all symbol kinds for "MakeLove" in one DLL
search_symbol(
dlls=["Backend/GameData.dll"],
query="MakeLove",
)
# Search only types named "Combat*" across multiple DLLs
search_symbol(
dlls=[
"Backend/GameData.dll",
"Managed/Assembly-CSharp.dll",
],
query="Combat",
kind="type",
)
# Search only methods containing "ChangeHealth"
search_symbol(
dlls=["Backend/GameData.dll"],
query="ChangeHealth",
kind="method",
)Args:
dlls (list[str]): One or more assembly paths to search.
query (str): Case-insensitive substring to match against symbol names.
kind (str): Category filter. One of:
- "any" (default) — all categories
- "type" — only type names
- "method" — only method names
- "field" — only field names
- "property" — only property names
- "event" — only event names
asm_paths (list[str] | None): Extra dependency dirs (almost never
needed — see decompile_type).
Returns: SearchResult: All matches across all DLLs (with owning type info for member matches).
Raises:
InvalidArgumentError: If kind is not a valid category.
DllNotFoundError: If any DLL in dlls does not exist.
| Name | Required | Description | Default |
|---|---|---|---|
| dlls | Yes | ||
| query | Yes | ||
| kind | No | any | |
| asm_paths | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | Yes | |
| kind | Yes | |
| matches | Yes | |
| total | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the matching behavior (case-insensitive substring), that it returns all matches across DLLs, and lists raised exceptions. It does not explicitly state that the tool is read-only, but that is implied by the search nature. Overall, it provides sufficient behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with sections, examples, and parameter listings. It is concise yet comprehensive, with every sentence adding value. The examples are particularly helpful for quick understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (4 parameters, no annotations, output schema existing), the description covers all necessary aspects: purpose, parameters, behavior, return type, and errors. It mentions the return object includes owning type info, which is useful for interpretation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds full meaning to all four parameters beyond the schema titles. It explains dlls and query clearly, lists all valid values for kind with descriptions, and explains asm_paths as an advanced parameter. Given the 0% schema description coverage, the description fully compensates.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Search for symbols by name across one or more assemblies.' It uses a specific verb ('search') and resource ('symbols'), and distinguishes itself from sibling tools like decompile_type by focusing on search across assemblies rather than decompiling specific types.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides examples and hints about when to use this tool, such as when you're not sure which assembly contains a type. It also refers to decompile_type for asm_paths context. However, it does not explicitly state when not to use or provide a direct comparison with all sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
7 tool updates
v0.1.0- First observed
check_env - First observed
decompile_member - First observed
decompile_type - First observed
get_type_summary - First observed
list_namespaces - First observed
list_types - First observed
search_symbol
TDQS
Scored across 7 tools
Each tool has a clearly distinct purpose: environment checking, decompiling types, decompiling members, getting type summaries, listing namespaces, listing types, and searching symbols. No overlap or ambiguity.
All tool names follow a consistent verb_noun snake_case pattern: check_env, decompile_member, decompile_type, get_type_summary, list_namespaces, list_types, search_symbol. The pattern is uniform and predictable.
Seven tools is an ideal size for a decompiler MCP server, covering diagnostics, exploration, and decompilation without being overwhelming or insufficient.
The tools cover the core exploration and decompilation workflow (list namespaces, types, summary, decompile type/member, search). However, missing are options for decompilation settings (e.g., with/without comments, debug info), which would make it fully complete.
Maintenance
Related MCP Connectors
An MCP server that gives your AI access to the source code and docs of all public github repos
Capability registry for the agentic economy. Semantic search over verified MCP server listings.
Driflyte MCP server which lets AI assistants query topic-specific knowledge from web and GitHub.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceILSpy for LLM coding agents. Reflection-based MCP server with 31+ tools to explore .NET assemblies, NuGet packages, types, members, attributes, and XML docs.8MIT
- AlicenseNot gradedqualityFmaintenanceMCP server that allows LLMs to autonomously reverse engineer applications using Ghidra, exposing tools like decompilation, renaming, and listing methods.27Apache 2.0
- AlicenseAqualityCmaintenanceMCP server for .NET assembly analysis. Vendor-neutral wrapper around AsmResolver and ILSpy for parsing and decompiling .NET assemblies.111MIT
- AlicenseNot gradedqualityCmaintenanceMCP server that exposes an AI decompiler via an OpenAI-compatible API, enabling decompilation, explanation, and variable renaming of disassembly for binary analysis.MIT