dnre-mcp
A standalone MCP (Model Context Protocol) server for .NET assembly reverse engineering. Provides decompilation and analysis tools to AI assistants like Claude, powered by ICSharpCode.Decompiler (the same engine behind ILSpy).
Why
The previous workflow required launching dnSpyEx with an MCP extension, manually loading assemblies, and connecting Claude to the dnSpy MCP server. This was fragile and heavyweight. dnre-mcp replaces all of that with a single CLI tool that speaks MCP over stdio -- no GUI needed.
Installation
From PyPI (recommended)
dnre-mcp is published as a Windows wheel that bundles a framework-dependent
DnreMcp binary behind a small Python launcher, so it installs through uv/pip
like any other MCP server:
# run on demand (fetched + cached on first launch)
uvx dnre-mcp
# or install the CLI persistently
uv tool install dnre-mcp
The wheel is tagged py3-none-win_amd64 — it works on any Python 3, but the
bundled binary is Windows x64 and requires the .NET 10 runtime on the host:
winget install --id Microsoft.DotNet.Runtime.10 --exact
Pre-built release (no .NET SDK required)
Download the latest release for your platform from the Releases page:
- Windows x64:
dnre-mcp-<version>-win-x64.zip - Linux x64:
dnre-mcp-<version>-linux-x64.tar.gz
Extract the archive and point your MCP config to the executable:
Windows:
Expand-Archive dnre-mcp-v0.1.0-win-x64.zip -DestinationPath C:\tools\dnre-mcp
Linux:
mkdir -p ~/tools/dnre-mcp
tar xzf dnre-mcp-v0.1.0-linux-x64.tar.gz -C ~/tools/dnre-mcp
chmod +x ~/tools/dnre-mcp/DnreMcp
Build from source
Requires .NET 10 SDK or later.
dotnet build src/DnreMcp/DnreMcp.csproj
To create a self-contained publish:
dotnet publish src/DnreMcp/DnreMcp.csproj -c Release -r win-x64 --self-contained -o ./publish
# or
dotnet publish src/DnreMcp/DnreMcp.csproj -c Release -r linux-x64 --self-contained -o ./publish
Configuration
Claude Code
Add to your MCP settings (.claude/settings.json or project-level):
Using the PyPI wheel via uvx (recommended):
{
"mcpServers": {
"dnre": {
"command": "uvx",
"args": ["dnre-mcp"]
}
}
}
Using a pre-built release:
{
"mcpServers": {
"dnre": {
"command": "C:/tools/dnre-mcp/DnreMcp.exe"
}
}
}
Using dotnet run (requires .NET SDK):
{
"mcpServers": {
"dnre": {
"command": "dotnet",
"args": ["run", "--project", "/path/to/dnre-mcp/src/DnreMcp/DnreMcp.csproj"]
}
}
}
Claude Desktop
Add to claude_desktop_config.json:
Using a pre-built release:
{
"mcpServers": {
"dnre": {
"command": "C:/tools/dnre-mcp/DnreMcp.exe"
}
}
}
Using dotnet run (requires .NET SDK):
{
"mcpServers": {
"dnre": {
"command": "dotnet",
"args": ["run", "--project", "/path/to/dnre-mcp/src/DnreMcp/DnreMcp.csproj"]
}
}
}
MCP Tools
Assembly Management
| Tool | Description |
|---|---|
load_assembly |
Load a .NET assembly (dll/exe) from disk for analysis |
list_assemblies |
List all currently loaded assemblies |
get_assembly_info |
Assembly provenance: assembly/file/informational version, culture, public-key token, module name/MVID, target framework/runtime, referenced assemblies |
Type Analysis
| Tool | Description |
|---|---|
list_types |
List all types in an assembly, optionally filtered by namespace prefix |
search_types |
Search for types by name (case-insensitive substring match) |
get_type_info |
Get full metadata for a type: base class, interfaces, fields, properties, methods, events, nested types |
decompile_type |
Decompile an entire type to C# source code, or (with name_regex) just the members whose name matches |
Method Analysis
| Tool | Description |
|---|---|
search_methods |
Search for methods by name across all types in an assembly |
get_method_info |
Get method signature details: parameters, return type, accessibility, virtual/abstract/override |
decompile_method |
Decompile a specific method to C# source (handles overloads) |
Cross-Reference Analysis
Backed by a metadata-level IL index (call graph, field access, string table) that is built once per assembly on first use and cached. This is the cross-referencing a decompile-by-name tool can't do: it navigates an obfuscated binary by behavior, not by (meaningless) member names.
| Tool | Description |
|---|---|
find_callers |
Every method whose IL calls a given method, across the whole assembly (includes all overloads) |
find_field_readers |
Every method whose IL reads a given field (ldfld/ldsfld) |
find_field_writers |
Every method whose IL writes a given field (stfld/stsfld) |
list_string_literals |
String literals in method bodies with the type/method each lives in; filter by substring or regex |
Namespace Browsing
| Tool | Description |
|---|---|
list_namespaces |
List all namespaces in an assembly |
Tool Parameters
All tools that operate on a loaded assembly take an assembly parameter -- this is the assembly name (e.g. Assembly-CSharp), not the file path. You must call load_assembly first to make an assembly available by name.
Type-specific tools take a type_full_name parameter using the dotted namespace format (e.g. MyNamespace.MyClass). Method tools additionally take a method_name parameter.
Parameter Reference
load_assembly(path)
list_assemblies()
get_assembly_info(assembly)
list_types(assembly, namespace_filter?)
search_types(assembly, pattern)
get_type_info(assembly, type_full_name)
decompile_type(assembly, type_full_name, name_regex?)
search_methods(assembly, pattern)
get_method_info(assembly, type_full_name, method_name)
decompile_method(assembly, type_full_name, method_name)
find_callers(assembly, type_full_name, method_name)
find_field_readers(assembly, type_full_name, field_name)
find_field_writers(assembly, type_full_name, field_name)
list_string_literals(assembly, pattern?, regex?, max_results?)
list_namespaces(assembly)
Example Workflow
A typical reverse engineering session with Claude:
-
Load the assembly
"Load the assembly at
C:/Games/MyGame/Managed/Assembly-CSharp.dll" -
Explore namespaces
"What namespaces are in Assembly-CSharp?"
-
Find types of interest
"Search for types containing 'Player'"
-
Inspect a type
"Show me the type info for
GameLogic.PlayerController" -
Decompile
"Decompile the
Updatemethod fromGameLogic.PlayerController" -
Cross-reference (the key move in an obfuscated binary)
"Who calls
SocketManager.PlayerDataChange?" —find_callers"Find the string literalrace finishedand tell me which method it's in" —list_string_literals"What writes theisConnectedfield onSocketManager?" —find_field_writers
Project Structure
dnre-mcp/
dnre-mcp.sln
src/DnreMcp/
DnreMcp.csproj
Program.cs -- Host setup, MCP server registration
Services/
AssemblyManager.cs -- Manages loaded assemblies; per-assembly locking (thread safety)
CrossReferenceIndex.cs -- IL-level call graph / field access / string literal index
Tools/
AssemblyTools.cs -- load_assembly, list_assemblies, get_assembly_info
TypeTools.cs -- list_types, search_types, get_type_info, decompile_type
MethodTools.cs -- search_methods, get_method_info, decompile_method
AnalysisTools.cs -- find_callers, find_field_readers, find_field_writers, list_string_literals
NamespaceTools.cs -- list_namespaces
Dependencies
| Package | Version | Purpose |
|---|---|---|
| ModelContextProtocol | 1.0.0 | Official C# MCP SDK |
| Microsoft.Extensions.Hosting | 10.0.3 | Application host and DI |
| ICSharpCode.Decompiler | 9.1.0.7988 | .NET decompilation engine (ILSpy) |
License
MIT
Release files for dnre-mcp 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dnre_mcp-0.2.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
Release files / dnre_mcp-0.2.0-py3-none-win_amd64.whl
| Download URL | dnre_mcp-0.2.0-py3-none-win_amd64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
f83df5a3a632ddd7cf080e6581a1c37ac24999528365e7ce1e1957935c18944c
|
|
BLAKE2b-256 checksum How to use checksums |
f300c2701c05140adf1fe949b0c62361b42fde059d7c8d73eb44c2772b5fdfff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|