Metadata-Version: 2.4
Name: dnre-mcp
Version: 0.1.1
Summary: A Model Context Protocol server for .NET assembly reverse engineering (ILSpy/ICSharpCode.Decompiler)
Author-email: "Ryan Johnson (ntninja)" <ryan@ntninja.com>
License-Expression: MIT
Project-URL: Repository, https://gitlab.com/ntninja-dev/dnre-mcp
Project-URL: Bug Tracker, https://gitlab.com/ntninja-dev/dnre-mcp/-/issues
Keywords: dotnet,decompiler,ilspy,mcp,reverse-engineering,windows
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: Microsoft :: Windows
Classifier: Topic :: Software Development :: Disassemblers
Classifier: Topic :: Security
Classifier: Environment :: Console
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# 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](https://github.com/icsharpcode/ILSpy) (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:

```powershell
# 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:

```powershell
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](../../-/releases):

- **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:**
```powershell
Expand-Archive dnre-mcp-v0.1.0-win-x64.zip -DestinationPath C:\tools\dnre-mcp
```

**Linux:**
```bash
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](https://dotnet.microsoft.com/download) or later.

```bash
dotnet build src/DnreMcp/DnreMcp.csproj
```

To create a self-contained publish:

```bash
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):
```json
{
  "mcpServers": {
    "dnre": {
      "command": "uvx",
      "args": ["dnre-mcp"]
    }
  }
}
```

Using a pre-built release:
```json
{
  "mcpServers": {
    "dnre": {
      "command": "C:/tools/dnre-mcp/DnreMcp.exe"
    }
  }
}
```

Using `dotnet run` (requires .NET SDK):
```json
{
  "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:
```json
{
  "mcpServers": {
    "dnre": {
      "command": "C:/tools/dnre-mcp/DnreMcp.exe"
    }
  }
}
```

Using `dotnet run` (requires .NET SDK):
```json
{
  "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 |

### 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 |

### 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) |

### 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()
list_types(assembly, namespace_filter?)
search_types(assembly, pattern)
get_type_info(assembly, type_full_name)
decompile_type(assembly, type_full_name)
search_methods(assembly, pattern)
get_method_info(assembly, type_full_name, method_name)
decompile_method(assembly, type_full_name, method_name)
list_namespaces(assembly)
```

## Example Workflow

A typical reverse engineering session with Claude:

1. **Load the assembly**
   > "Load the assembly at `C:/Games/MyGame/Managed/Assembly-CSharp.dll`"

2. **Explore namespaces**
   > "What namespaces are in Assembly-CSharp?"

3. **Find types of interest**
   > "Search for types containing 'Player'"

4. **Inspect a type**
   > "Show me the type info for `GameLogic.PlayerController`"

5. **Decompile**
   > "Decompile the `Update` method from `GameLogic.PlayerController`"

## Project Structure

```
dnre-mcp/
  dnre-mcp.sln
  src/DnreMcp/
    DnreMcp.csproj
    Program.cs                  -- Host setup, MCP server registration
    Services/
      AssemblyManager.cs        -- Manages loaded assemblies and decompiler instances
    Tools/
      AssemblyTools.cs          -- load_assembly, list_assemblies
      TypeTools.cs              -- list_types, search_types, get_type_info, decompile_type
      MethodTools.cs            -- search_methods, get_method_info, decompile_method
      NamespaceTools.cs         -- list_namespaces
```

## Dependencies

| Package | Version | Purpose |
|---------|---------|---------|
| [ModelContextProtocol](https://www.nuget.org/packages/ModelContextProtocol) | 1.0.0 | Official C# MCP SDK |
| [Microsoft.Extensions.Hosting](https://www.nuget.org/packages/Microsoft.Extensions.Hosting) | 10.0.3 | Application host and DI |
| [ICSharpCode.Decompiler](https://www.nuget.org/packages/ICSharpCode.Decompiler) | 9.1.0.7988 | .NET decompilation engine (ILSpy) |

## License

MIT
