1. Conduid
  2. Developer Tools
  3. Dnspy MCP
MCP server · Developer Tools

Dnspy MCP

MCP extension for dnSpy

Unclaimed devtools
44Fair

Scored 7 days ago · breakdown

About Dnspy MCP

Dnspy MCP is an MCP server published by tuna1999 in the Developer Tools category: mCP extension for dnSpy.

The repository has 72 stars and 17 forks, with the last commit 18 days ago. Recent commit activity is the strongest signal that reported issues will get attention.

Install

From source
git clone https://github.com/tuna1999/dnspy-mcp

This server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.

Ask AI

✦

Ask AI about Dnspy MCP

Powered by Claude · Grounded in docs

I know everything about Dnspy MCP. Ask me about installation, configuration, usage, or troubleshooting.

Security checks

Static checks derived from the repository 7 days ago. Heuristics on the source, not an audit.

  • ✓README presentThe repository ships documentation.
  • !License declaredNo license file. Legally you have no right to use it in a product.
  • ✓Tests presentA test suite exists in the repository.
  • !Dependencies pinnedNo lockfile. Installs can pull different code over time.
  • ✓No dynamic code executionSource scan found no eval, dynamic Function, or shell execution.

1 check has not been run yet.

Releases

v2.1.0v2.1.0 · 7 Oct 2026dnSpy MCP v2.1.0 Changes chore(release): bump version to 2.1.0 feat(debugger): runtime value inspection tools feat(debugger): add dnSpy control tools and fix target launch 1. Download the zip matching your dnSpy version: 2. Extract BOTH…
v2.0.4v2.0.4 · 15 Sep 2026dnSpy MCP v2.0.4 Changes fix(server): cancel tool timeout CTS deterministically on TimeoutException chore(release): bump version to 2.0.4 fix(docs): tool-count guard fails closed, batch/SDK claims match reality fix(extension): start-guard…
v2.0.3v2.0.3 · 14 Sep 2026dnSpy MCP v2.0.3 Changes chore(release): bump version to 2.0.3 chore: zero-warning build, async test assert, docs tree drift fix(security): reject drive-by/DNS-rebinding requests (Host + Origin gate) fix: harden server startup host capture…
v2.0.2v2.0.2 · 14 Sep 2026dnSpy MCP v2.0.2 Changes fix: ship Core.dll with extension, optional MEF imports, pane log mirroring (2.0.2) 1. Download the zip matching your dnSpy version: 2. Extract BOTH `dnSpy.MCP.x.dll` and `dnSpy.MCP.Core.dll` to…
v2.0.1v2.0.1 · 3 Sep 2026dnSpy MCP v2.0.1 Changes fix(ci): suppress warnings, pin MessagePack 2.5.301, bump 2.0.1 docs: fix CLAUDE.md Architecture section corrupted by conflict bulk-write Installation 1. Download the zip matching your dnSpy version:…

README

dnSpy MCP Server

Build

A Model Context Protocol (MCP) server for dnSpy — the .NET debugger and assembly editor — enabling AI agents to decompile, analyze, search, and patch .NET assemblies directly through dnSpy's engine.

Highlights

  • 55 MCP tools — static analysis, IL patching, and integrated debugger control (36 tools in headless)
  • Byte-identical decompiler output — powered by the same ICSharpCode.Decompiler pipeline dnSpy.exe uses
  • Two hosts, one core — run as a dnSpy extension (HTTP) or a standalone headless exe (stdio); identical tools and output
  • Zero-drag transport — the extension uses a minimal TcpListener-based HTTP transport, avoiding version conflicts with dnSpy's runtime
  • Hardened by default — loopback bind, constant-time token auth, concurrency caps, request-size limits, per-tool timeouts, serialized mutations
  • Batch-ready — JSON-RPC batch requests (send an array, get ordered results); requests run sequentially per connection, so use several connections for throughput

How It Works

Two hosts share one tool core (dnSpy.MCP.Core):

┌─ Extension (in dnSpy) ─────────────────┐   ┌─ Headless (standalone exe) ─────────┐
│ dnSpy loads extension → MCP Server     │   │ dotnet dnspy-mcp-headless.dll       │
│ menu → Start → TcpListener on :5150    │   │ --load foo.dll (repeatable, globs)  │
│              ↕                         │   │              ↕                      │
│   AI agent — HTTP POST (JSON-RPC 2.0)  │   │   AI agent — stdio (MCP SDK)        │
└────────────┬───────────────────────────┘   └──────────────┬──────────────────────┘
             └──────────► dnSpy.MCP.Core ◄──────────────────┘
                         (36 tools + decompiler bridge,
                          output identical to dnSpy.exe)
  • Extension — runs inside dnSpy with full UI integration (tree view, tabs, Output pane). Started manually from the MCP Server menu so WPF is fully initialized before any tool call touches the UI thread.
  • Headless — standalone stdio MCP server for batch analysis: same tools, same decompiled output, no UI, no dnSpy install required at analysis time (only the vendored decompiler DLLs in deps/).

Tools (55 total · 36 in headless)

Decompiler

Tool Description
decompile_method Decompile a method to C#. Accepts full name (Namespace.Class::Method), metadata token (0x06000001), or partial name
decompile_type Decompile an entire type (all members) to C#
decompile_assembly Decompile all types in the assembly (limited to 10 for brevity)

Search

Tool Description
search_types Search types by name pattern. Use regex: prefix for regex matching
search_methods Search methods by name, optionally scoped to a specific type
search_strings Search string literals in method bodies
grep Multi-scope search across types, methods, and strings

Analysis

Tool Description
get_method_il Raw IL instructions with exception handlers
get_method_signatures Method metadata: parameters, return type, flags, generic params
get_type_hierarchy Inheritance chain, interfaces, member counts
get_method_body IL bytes with MaxStack/InitLocals info
get_il_opcodes_formatted Formatted IL opcodes with offsets and line indices
update_method_body Patch a method body using C# statements (dry-run supported)

Cross-References

Tool Description
get_xrefs_to Find all references to a method or field
get_callees Methods and fields called by a method

Assembly

Tool Description
load_assembly Load a .NET DLL/EXE into dnSpy by absolute path
close_assembly Unload an assembly by simple name (case-insensitive)
list_loaded_assemblies List all loaded binaries: name, MVID, type count, path
assembly_overview Module info, version, entry point, type count, references
assembly_list_namespaces All namespaces in the loaded assembly
assembly_list_types Type listing with optional regex filter
assembly_get_references Assembly references (DLLs, NuGet packages)

Resources & Metadata

Tool Description
get_resources List embedded resources
get_resource_data Raw bytes of a specific resource
get_metadata PE headers, MVID, runtime version, sections

Type Inspection

Tool Description
get_type_members List all members of a type with optional filter
get_fields Detailed field info: type, access, static/const, values
get_properties Property details: getter/setter, type, access

Custom Attributes

Tool Description
get_attributes Attributes on assembly/type/method/field with filter
get_method_attributes Shortcut: attributes on a specific method

Constants & Enums

Tool Description
get_enum_values Enum members with name + value (hex + decimal)
search_constants Search const/literal fields across assemblies
get_global_namespaces List all types in the global namespace

UI & Navigation (Extension only)

Tool Description
get_selected_node Get the currently selected node in dnSpy tree view
refresh_ui Refresh tree view UI after metadata changes

Rename

Tool Description
rename_namespace Rename a namespace across matching types (dry-run supported)
rename_class Rename one class in an assembly+namespace (dry-run supported)
rename_method Rename methods by exact or partial match (dry-run supported)

Debugger (Extension only — needs the dnSpy host; not in headless)

Tool Description
debug_get_state Session state: debugging/running, processes, current thread, last break
debug_list_processes Attachable .NET processes (pid, name, runtime, arch, filename)
debug_start Start an EXE or managed DLL (runtime: auto/netfx/dotnet); omitted/empty working_dir uses the target folder; break-at-entry by default
debug_attach Attach to a running .NET process by pid
debug_stop Stop the session — stop (default) / detach / terminate (terminate is dry-run by default)
debug_continue Run all debuggee processes
debug_break_all Request a break in all debuggees
debug_step Step the current thread (into/over/out)
debug_wait_paused Block until paused (timeout_ms), then return the state
debug_set_breakpoint Breakpoint on Namespace.Type::Method — binds on module load, no PDB needed
debug_delete_breakpoint Delete an MCP breakpoint by id
debug_list_breakpoints List MCP breakpoints
debug_get_callstack Actual runtime stack; optional pid/thread_id, no GUI selection change
debug_list_threads Paused threads with process, OS/managed IDs and current-thread marker
debug_get_locals Bounded runtime locals, arguments and this for an exact paused frame
debug_get_value Safe instance-field/array page from a pause-scoped value ID
debug_dismiss_dialog Dismiss dnSpy modal error dialogs after a failed launch

For modern .NET, managed images run through dotnet.exe; native apphost EXEs launch directly. For an apphost, load its companion managed DLL before setting method breakpoints. debug_start checks the actual process state, not just whether dnSpy accepted the asynchronous launch request.

Runtime inspection requires a fully paused managed frame. thread_id requires pid; omitted selectors use the current thread without changing GUI selection. frame_index=0 is the top frame. Pages use start_index >= 0, count=1..256 (default 64), with at most 4,096 retained values and 4,096 UTF-16 units per formatted field. Strings retain the engine's preview limit.

A successful debug_get_locals replaces the single snapshot and invalidates previous value_ids. Resume, step, stop and detach invalidate them even after another pause. debug_get_value does not evaluate expressions, getters, ToString, debugger displays/proxies or enumerators. Static/Results/Dynamic groups are blocked; static reads can trigger type initialization in this engine. Unavailable/optimized-out values retain provider errors rather than fake nulls.

Tips

  • Multiple assemblies? Call list_loaded_assemblies first; search tools accept an optional assembly parameter to scope results.
  • Method identifiers — all method-accepting tools resolve hex tokens, plain tokens, full names, then short names via one shared resolver. Prefer full names (Namespace.Class::Method) to avoid ambiguity.
  • Mutating tools (rename_*, update_method_body) are dry-run by default — pass dryRun: false to apply.

Getting Started

Prerequisites

  • dnSpy (.NET 10 build, e.g. dnSpyEx v6.6.0+)
  • .NET 10.0 SDK
  • deps/ folder with these DLLs synced from a dnSpy install (run pwsh scripts/sync-deps.ps1 -DnSpyBin <dnSpy>\bin):
    • dnSpy.Contracts.DnSpy.dll, dnSpy.Contracts.Logic.dll
    • ICSharpCode.Decompiler.dll, dnlib.dll
    • Headless-only: dnSpy.Decompiler.dll, dnSpy.Decompiler.ILSpy.Core.dll, ICSharpCode.NRefactory.dll, ICSharpCode.NRefactory.CSharp.dll, ICSharpCode.NRefactory.VB.dll

Configure DnSpyBin path

The project resolves dnSpy contract DLLs via the <DnSpyBin> MSBuild property in dnSpy.MCP.csproj:

<DnSpyBin>..\..\deps</DnSpyBin>

Default path resolves to <repo>/deps/. To change it, edit this property or pass it at the command line:

dotnet build -p:DnSpyBin="D:\path\to\dnSpy\bin"

Build & Deploy

# 1) Build only (Release default)
pwsh scripts/build.ps1 -DnSpyPath "D:\tools\dnSpy"

# 2) Clean + build
pwsh scripts/build.ps1 -DnSpyPath "D:\tools\dnSpy" -Clean

# 3) Build + deploy into <DnSpyPath>\bin\Extensions
pwsh scripts/build.ps1 -DnSpyPath "D:\tools\dnSpy" -Deploy

# 4) Build + deploy to a custom folder
pwsh scripts/build.ps1 -DnSpyPath "D:\tools\dnSpy" -Deploy -DeployDir "D:\tools\dnSpy\bin\Extensions"

# 5) Debug build + deploy
pwsh scripts/build.ps1 -DnSpyPath "D:\tools\dnSpy" -Configuration Debug -Deploy

The script syncs deps/ from the dnSpy install, builds the solution, and deploys the extension. dnSpy must be closed before -Deploy.

Option Effect
-DnSpyPath "<path>" Required: dnSpy folder (DLLs synced from its bin\)
-Clean Clean before build
-Deploy Deploy after build
-DeployDir "<path>" Custom deploy target (used with -Deploy)
-Configuration Debug Build Debug instead of Release
-PublishHeadless Publish the headless exe bundle

Build output paths

  • Build output (Release default): src/dnSpy.MCP/bin/Release/net10.0-windows/dnSpy.MCP.x.dll
  • Build output (Debug override): src/dnSpy.MCP/bin/Debug/net10.0-windows/dnSpy.MCP.x.dll
  • Runtime deploy (default): <DnSpyPath>/bin/Extensions/dnSpy.MCP.x.dll
  • Runtime deploy (custom -DeployDir): <DeployDir>/dnSpy.MCP.x.dll

Only these files should be copied to dnSpy's Extensions folder:

  • dnSpy.MCP.x.dll
  • dnSpy.MCP.Core.dll (required — hard dependency of dnSpy.MCP.x.dll; without it dnSpy silently fails to load the extension)
  • dnSpy.MCP.x.deps.json
  • dnSpy.MCP.x.pdb (optional for debugging)
  • dnSpy.MCP.Core.pdb (optional for debugging)

Do not copy the whole build/Extensions folder recursively into dnSpy (avoid nested Extensions/Extensions/ and stale dependency files).

Troubleshooting: if the extension loaded before but breaks after swapping DLL versions, delete dnSpy's cached MEF composition at %LOCALAPPDATA%\dnSpy\Startup64\net\dnSpy-mef-info.bin and restart dnSpy. The cache is keyed by extension DLL identity (path + timestamp + size + MVID); replacing a dependency (e.g. dnSpy.MCP.Core.dll) does not invalidate it.

Usage (Extension)

  1. Start dnSpy.exe
  2. Open a .NET assembly (.exe/.dll)
  3. Menu → MCP Server → Start
  4. Open View → Output (Alt+2) → select MCP Server to see logs
  5. Connect from an AI agent via http://127.0.0.1:5150/
Menu Item Action
Start Start the MCP HTTP server
Stop Stop the MCP HTTP server
Status Show running/stopped state and port
Show Log Display recent log entries
Clear Log Clear log file and output window

Project Structure

dnspy_mcp/
├── src/
│   ├── dnSpy.MCP.Core/        # Shared library: 36 tools, McpContext, decompiler bridge
│   │   ├── Abstractions/      # IAssemblyLoader, ISourceDecompiler, IUIThreadScheduler,
│   │   │                      # ILogSink, ITreeRefreshNotifier
│   │   ├── Adapters/          # DnSpyDecompilerSourceProvider (shared by both hosts)
│   │   ├── Mcp/               # McpContext, ToolRegistry, McpServerHost (HTTP), JsonRpc
│   │   ├── Helpers/           # MethodResolver
│   │   └── Tools/             # 13 instance tool classes ([Description] methods)
│   ├── dnSpy.MCP/             # Extension (net10.0-windows, WPF, MEF) — HTTP transport
│   │   ├── Adapters/          # dnSpy-backed adapter implementations
│   │   ├── Tools/TreeViewTools.cs  # 2 UI-only tools (get_selected_node, refresh_ui)
│   │   └── TheExtension.cs    # MEF entry, composes McpContext
│   ├── dnSpy.MCP.Headless/    # Standalone exe (stdio MCP transport via MCP SDK)
│   │   ├── Program.cs         # Host + fail-fast startup + stdio server
│   │   ├── CliOptions.cs      # --load (globs) / --config / --help
│   │   └── Adapters/          # dnlib loader, reflection decompiler loader,
│   │                          # stderr log sink, mutation-lock filter
│   └── dnSpy.MCP.Tests/       # Unit + headless E2E tests (spawn real server process)
│       └── TestData/SampleLibrary/  # E2E fixture assembly
├── deps/                      # Vendored dnSpy DLLs (sync via scripts/sync-deps.ps1)
├── scripts/                   # build.ps1, sync-deps.ps1, verify-tool-count.ps1, mcp-probe.js
└── skills/                    # AI agent workflow guides

Headless Mode

For batch analysis without dnSpy running: same 36 tools, decompiler output byte-identical to dnSpy.exe, stdio transport (Claude Desktop / Cursor / VS Code can auto-spawn it).

# Build & publish
pwsh scripts/build.ps1 -DnSpyPath "D:\tools\dnSpy" -PublishHeadless

# Run directly from build output
dotnet src/dnSpy.MCP.Headless/bin/Release/net10.0-windows/dnspy-mcp-headless.dll --load path\to\target.dll

# Or from the published bundle
dotnet publish\headless\dnspy-mcp-headless.dll --load "path\to\*.dll"
  • --load, -l <path> — pre-load assemblies (repeatable, supports */? globs)
  • --config, -c <json> — reserved, currently unused
  • Logging goes to stderr only (stdout carries the MCP JSON-RPC frames)
  • Parallel mutation calls (rename_*, update_method_body) are serialized via a shared lock, mirroring the Extension transport

Client config (stdio):

{
  "mcpServers": {
    "dnspy-headless": {
      "command": "dotnet",
      "args": [
        "D:\\path\\to\\publish\\headless\\dnspy-mcp-headless.dll",
        "--load", "D:\\path\\to\\target.dll"
      ]
    }
  }
}

Configuration

Defaults live in src/dnSpy.MCP/Settings/McpSettings.cs and are editable in dnSpy via Options → MCP Server:

Setting Default Description
Host 127.0.0.1 Loopback only by default; 0.0.0.0 binds all interfaces
Port 5150 TCP port for the HTTP transport
AutoStart off Start the server when dnSpy launches
RequireAuth / ApiToken off Require Authorization: Bearer <token> on every request
AllowedOrigins empty CORS origins allowed to call the server (empty = CORS disabled)
MaxConcurrency 4 Max simultaneous in-flight requests
MaxRequestSizeMB 1 Request body cap
ToolTimeoutSeconds 30 Per-tool-call timeout (in-flight work is cancelled on expiry)

Security

  • Loopback by default — the server binds 127.0.0.1; binding 0.0.0.0 exposes it to the network, so pair it with RequireAuth.
  • Auth fail-closed — if RequireAuth is on but the token is empty, the server refuses to start. Tokens are compared in constant time (CryptographicOperations.FixedTimeEquals).
  • Mutation serialization — destructive tools (rename_*, update_method_body) run under an exclusive lock so parallel batch requests can't race on dnlib metadata.
  • Roslyn sandbox — IL patch compilation references only 5 core BCL assemblies plus the target assembly.
  • Cancellation — per-tool timeouts cancel the actual decompilation work, not just the HTTP response.

Logging

Logs are written to three destinations:

  • File: mcp-server.log in the dnSpy bin folder (rotates at 5 MB, keeps 3 backups)
  • In-memory: Viewable via MCP Server → Show Log
  • Output Window: View → Output → MCP Server (in dnSpy)

Connecting AI Agents

This MCP server exposes dnSpy's decompilation and analysis tools via the standard MCP protocol over HTTP at http://127.0.0.1:5150/. Most modern AI agents support HTTP MCP servers natively — no bridge package needed.

Claude Code (recommended)

Use the claude mcp add command to add the server. Choose a scope:

# Local scope (default) — only this project, stored in ~/.claude.json
claude mcp add --transport http dnspy http://127.0.0.1:5150

# Project scope — shared with team via .mcp.json (check into git)
claude mcp add --transport http dnspy --scope project http://127.0.0.1:5150

# User scope — all your projects
claude mcp add --transport http dnspy --scope user http://127.0.0.1:5150

Project scope generates a .mcp.json at the project root:

{
  "mcpServers": {
    "dnspy": {
      "type": "http",
      "url": "http://127.0.0.1:5150"
    }
  }
}

Local/User scope writes to ~/.claude.json under the project path:

{
  "projects": {
    "/path/to/your/project": {
      "mcpServers": {
        "dnspy": {
          "type": "http",
          "url": "http://127.0.0.1:5150"
        }
      }
    }
  }
}

Other useful commands:

claude mcp list          # list all configured servers
claude mcp get dnspy     # show config for a server
claude mcp remove dnspy  # remove a server

Other AI Editors

Editor Config file Format
Cursor ~/.cursor/mcp.json { "mcpServers": { "dnspy": { "url": "http://127.0.0.1:5150/" } } }
VS Code (Cline/Roo) .vscode/mcp.json Same as above

Verification

  1. Start dnSpy and open an assembly
  2. Menu → MCP Server → Start
  3. Check GET http://127.0.0.1:5150/health returns status and tool count, or list tools from your agent — you should see 38 MCP tools (decompile_method, search_types, grep, get_xrefs_to, assembly_overview, …)

If the agent does not auto-discover the tools, tell it: "Use the dnSpy MCP server at http://127.0.0.1:5150/ to access decompilation and analysis tools."

Adding New Tools

Tools are discovered at runtime via reflection. To add a new tool:

  1. Create a public sealed class in src/dnSpy.MCP.Core/Tools/ under the dnSpy.MCP.Core.Tools namespace, with a constructor taking McpContext
  2. Add instance methods public string MyTool(...) with a [Description("...")] attribute
  3. Parameters use [Description("...")] for documentation
  4. Run pwsh scripts/verify-tool-count.ps1 to keep docs and code in sync
using System.ComponentModel;
using dnSpy.MCP.Core.Mcp;

namespace dnSpy.MCP.Core.Tools {
    public sealed class MyTools(McpContext ctx) {
        [Description("Describe what this tool does")]
        public string MyTool(
            [Description("Parameter description")] string param1) {
            // Access loaded modules via the abstraction — works in both
            // Extension (dnSpy) and Headless (dnlib) hosts
            var docs = ctx.AssemblyLoader.GetDocuments();
            return $"Result: {param1} ({docs.Count} assemblies loaded)";
        }
    }
}

Method names are automatically converted to snake_case for the MCP protocol (e.g., MyTool → my_tool).

Architecture Notes

Why a custom TcpListener transport instead of MCP SDK?

The official MCP SDK (ModelContextProtocol 1.4.0) pulls Microsoft.Extensions.* 10.x dependencies that conflict with the versions dnSpy ships on its .NET runtime. This is a hard version conflict that cannot be resolved with binding redirects. The solution is a minimal custom HTTP transport over System.Net.Sockets.TcpListener. The headless exe runs in its own process, so it uses the MCP SDK's stdio transport without conflict.

Standalone build

The project references pre-built DLLs from deps/, enabling fast iteration without cloning the full dnSpy source. For integrated builds as part of dnSpy.sln, clone dnSpyEx and copy src/dnSpy.MCP/ into Extensions/.

Thread safety

MCP tools run on background threads. All WPF TreeView/UI access marshals to the UI thread via the IUIThreadScheduler abstraction (Dispatcher.Invoke in the Extension). Metadata mutation tools auto-refresh the tree view after changes.

Skills

The skills/ directory contains reusable workflow guides for AI agents working with this MCP server. These skills teach the AI how to think about common analysis tasks — it dynamically picks tools based on what it discovers, rather than following rigid steps.

Available Skills

Skill Description
deobfuscate-dotnet Deobfuscate .NET binaries: string decryption, symbol renaming, control flow analysis, proxy call resolution, anti-tamper removal

Skill Structure

Each skill is a folder containing a SKILL.md file:

skills/
└── deobfuscate-dotnet/
    └── SKILL.md          # Skill definition (YAML frontmatter + instructions)

Installing Skills for Claude Code

Claude Code auto-discovers skills from .claude/skills/. To install:

# Install a specific skill
cp -r skills/deobfuscate-dotnet .claude/skills/

# Or install all skills
cp -r skills/* .claude/skills/

After installing, the skill activates automatically when you describe a matching task — for example:

# These will trigger the deobfuscation skill:
"Giúp tôi decrypt các string trong binary này"
"Rename lại các class/method bị obfuscate"
"Binary này bị protect bằng gì? Phân tích giúp tôi"

No restart needed — Claude Code picks up new skills on the next message.

For Other AI Editors

If your AI editor supports custom instructions or system prompts, paste the content of SKILL.md directly into your configuration. The skill content is self-contained and editor-agnostic.

License

This project is licensed under GPLv3, consistent with dnSpy's license.

README fetched from the repository 7 days ago. The original is authoritative.

Questions

About Dnspy MCP

How do I install Dnspy MCP?

No package has been published for this server, so install it from source: clone the repository and follow its README.

Is Dnspy MCP safe to use with an AI agent?

Its trust score is 44 out of 100 (fair). It passes 3 of the 5 static security checks run so far; the failures are listed above. It has no ConduID identity yet, so agent calls to it are not receipted.

Is Dnspy MCP still maintained?

Yes — the latest release is v2.1.0 (7 Oct 2026), and the last commit was 18 days ago. The repository has 72 stars.