{"id":32431125,"url":"https://github.com/kernelerr/dnspy.extension.mcp","last_synced_at":"2026-04-16T19:12:54.777Z","repository":{"id":320353725,"uuid":"1079631184","full_name":"KernelErr/dnSpy.Extension.MCP","owner":"KernelErr","description":"MCP extension for dnSpy.","archived":false,"fork":false,"pushed_at":"2025-10-23T09:01:09.000Z","size":55,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-23T11:09:52.138Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KernelErr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-20T06:21:23.000Z","updated_at":"2025-10-23T06:01:07.000Z","dependencies_parsed_at":"2025-10-23T11:10:02.678Z","dependency_job_id":"34672f97-054e-4d12-b450-01aa41175ed1","html_url":"https://github.com/KernelErr/dnSpy.Extension.MCP","commit_stats":null,"previous_names":["kernelerr/dnspy.extension.mcp"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/KernelErr/dnSpy.Extension.MCP","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KernelErr%2FdnSpy.Extension.MCP","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KernelErr%2FdnSpy.Extension.MCP/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KernelErr%2FdnSpy.Extension.MCP/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KernelErr%2FdnSpy.Extension.MCP/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KernelErr","download_url":"https://codeload.github.com/KernelErr/dnSpy.Extension.MCP/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KernelErr%2FdnSpy.Extension.MCP/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281026226,"owners_count":26431753,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-25T02:00:06.499Z","response_time":81,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-25T21:55:13.422Z","updated_at":"2026-04-16T19:12:54.766Z","avatar_url":"https://github.com/KernelErr.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dnSpy MCP Extension\n\n[![Build](https://github.com/KernelErr/dnSpy.Extension.MCP/actions/workflows/build.yml/badge.svg)](https://github.com/KernelErr/dnSpy.Extension.MCP/actions/workflows/build.yml)\n[![Release](https://github.com/KernelErr/dnSpy.Extension.MCP/actions/workflows/release.yml/badge.svg)](https://github.com/KernelErr/dnSpy.Extension.MCP/actions/workflows/release.yml)\n\nA [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) extension for [dnSpyEx](https://github.com/dnSpyEx/dnSpy) that exposes .NET assembly analysis tools to AI assistants like Claude.\n\nChinese / 中文说明: see [README.zh-CN.md](README.zh-CN.md).\n\n## Features\n\n### MCP Tools (10 total)\n\n1. **list_assemblies** — list all loaded assemblies with metadata\n2. **get_assembly_info** — detailed info about a specific assembly (paginated namespaces)\n3. **list_types** — all types in an assembly or namespace (paginated)\n4. **get_type_info** — fields, properties, and paginated methods for a type\n5. **get_type_fields** — filter fields by wildcard pattern (e.g. `*Bonus*`)\n6. **get_type_property** — detailed info about a property including getter/setter\n7. **find_path_to_type** — BFS over fields/properties to connect two types\n8. **decompile_method** — decompile a method to C#\n9. **search_types** — wildcard / substring type search across all assemblies\n10. **generate_bepinex_plugin** — BepInEx plugin template with Harmony hooks\n\n### MCP Resources (6 total)\n\nEmbedded BepInEx documentation served over `resources/list` / `resources/read`:\n\n1. **plugin-structure**\n2. **harmony-patching** (Prefix / Postfix / Transpiler)\n3. **configuration**\n4. **common-scenarios**\n5. **il2cpp-guide**\n6. **mono-vs-il2cpp**\n\nAll docs ship inside the DLL — no network required.\n\n## Installation\n\n### Recommended: all-in-one zip\n\nHead to [Releases](https://github.com/KernelErr/dnSpy.Extension.MCP/releases) and download the bundle that matches your system — **the extension is already placed inside, no paths to figure out**:\n\n| File | Contents | Runtime requirement |\n|------|----------|---------------------|\n| `dnSpy-MCP-win-x64.zip` | dnSpy .NET 10 self-contained x64 + MCP extension | None — runtime is bundled |\n| `dnSpy-MCP-win-x86.zip` | dnSpy .NET 10 self-contained x86 + MCP extension | None — runtime is bundled |\n| `dnSpy-MCP-net48.zip` | dnSpy .NET Framework 4.8 build + MCP extension | .NET Framework 4.8 (default on Windows 10+) |\n\n1. Download and unzip anywhere.\n2. Double-click `dnSpy.exe`.\n3. Open **Edit → Settings → MCP Server**, tick **Enable Server**, click OK.\n\nThat's it. If you already use dnSpy and just want the plugin, see \"Plugin-only\" below.\n\n### Plugin-only (for users who already have dnSpy installed)\n\n1. Download the DLL matching your dnSpy runtime:\n   - `dnSpy.Extension.MCP-net48.dll` — .NET Framework 4.8 dnSpy\n   - `dnSpy.Extension.MCP-net10.0-windows.dll` — .NET 10 dnSpy\n2. Rename to `dnSpy.Extension.MCP.x.dll` (the `.x` suffix is required by dnSpy's extension loader).\n3. Create the folder `dnSpy.Extension.MCP` under `\u003cdnSpy-Install\u003e\\bin\\Extensions\\` and put the DLL inside.\n4. Restart dnSpy.\n\n**The final path must look exactly like this** — same folder name as the DLL stem, `.x.dll` suffix present, one level deep under `Extensions\\`:\n\n```\n\u003cdnSpy-Install\u003e\\\n└── bin\\\n    └── Extensions\\\n        └── dnSpy.Extension.MCP\\           ← folder (create if missing)\n            └── dnSpy.Extension.MCP.x.dll  ← DLL with the .x suffix\n```\n\nConcrete example if dnSpy is installed at `C:\\Tools\\dnSpy`:\n\n```\nC:\\Tools\\dnSpy\\bin\\Extensions\\dnSpy.Extension.MCP\\dnSpy.Extension.MCP.x.dll\n```\n\nIf the DLL ends up directly under `bin\\Extensions\\` (no subfolder), or without the `.x` suffix, dnSpy silently skips it and the MCP Server settings page will not appear.\n\n### From source\n\n```bash\n# Clone dnSpyEx (submodules are required)\ngit clone --recursive https://github.com/dnSpyEx/dnSpy.git\ncd dnSpy\n\n# Clone this extension into the Extensions directory\ngit clone https://github.com/KernelErr/dnSpy.Extension.MCP.git Extensions/dnSpy.Extension.MCP\n\n# Build (both TFMs)\ncd Extensions/dnSpy.Extension.MCP\ndotnet build -c Release\n\n# Deploy\ncp bin/Release/net10.0-windows/dnSpy.Extension.MCP.x.dll \\\n   \u003cdnSpy-Install\u003e/bin/Extensions/dnSpy.Extension.MCP/\n```\n\n## Configuration\n\nSettings live under **Edit → Settings → MCP Server**:\n\n- **Enable Server** — starts/stops the HTTP server immediately when toggled and applied.\n- **Port** — preferred TCP port (default `3000`). If the port is already in use, the server automatically tries `port + 1`, up to 20 attempts, and logs which port it actually bound to. Check the Server Log pane (or `%TEMP%\\…` fallback log) for the resolved port.\n- **Host** — bind address (default `localhost`).\n\n## Transports\n\nBoth transports run on the same `HttpListener` on the same port.\n\n### Plain HTTP JSON-RPC\n\nOne-shot request/response — POST JSON-RPC to `/` and read the response from the same HTTP response body.\n\n```bash\ncurl -s http://localhost:3000/health\n# {\"status\":\"ok\",\"service\":\"dnSpy MCP Server\"}\n\ncurl -s -X POST http://localhost:3000/ \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\"}'\n```\n\n### Server-Sent Events (MCP 2024-11-05)\n\nTwo-endpoint transport: a long-lived SSE stream, plus a POST endpoint for client messages.\n\n1. `GET /sse` — opens `text/event-stream`. The first event (`event: endpoint`) carries the URL the client should POST to (`/message?sessionId=\u003cid\u003e`).\n2. `POST /message?sessionId=\u003cid\u003e` — accepts a JSON-RPC request, returns `202 Accepted`, and writes the real JSON-RPC response onto the corresponding SSE stream as an `event: message`.\n\n```bash\n# Terminal A: open the stream and keep it open\ncurl -N http://localhost:3000/sse\n# event: endpoint\n# data: /message?sessionId=\u003csessionId\u003e\n# ... (later, once POST arrives) ...\n# event: message\n# data: {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":...}\n\n# Terminal B: send a request on that session\ncurl -X POST \"http://localhost:3000/message?sessionId=\u003csessionId\u003e\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\"}'\n# HTTP 202 Accepted — the response appears on Terminal A's SSE stream\n```\n\n### Claude Desktop configuration\n\n```json\n{\n  \"mcpServers\": {\n    \"dnspy\": {\n      \"command\": \"http\",\n      \"args\": [\"http://localhost:3000\"]\n    }\n  }\n}\n```\n\n## Development\n\n```bash\n# Single-TFM builds for fast iteration\ndotnet build -c Debug -f net48\ndotnet build -c Debug -f net10.0-windows\n```\n\n### Project layout\n\n```\ndnSpy.Extension.MCP/\n├── .github/workflows/      GitHub Actions (build, release)\n├── McpServer.cs            HttpListener HTTP + SSE server + port fallback\n├── McpProtocol.cs          JSON-RPC 2.0 / MCP DTOs\n├── McpTools.cs             10 MCP tools (wraps dnSpy services)\n├── McpSettings.cs          Settings view-model + persistence + file log\n├── McpSettingsPage.cs      IAppSettingsPageProvider for dnSpy settings dialog\n├── BepInExResources.cs     Embedded BepInEx docs (6 resources)\n├── TheExtension.cs         IExtension entry point; starts server on Loaded\n└── dnSpy.Extension.MCP.csproj\n```\n\n### Architecture notes\n\n- **Targets**: `net48` and `net10.0-windows` (inherited from `DnSpyCommon.props`).\n- **Transport**: a single `HttpListener` serves both the plain HTTP JSON-RPC path and the SSE path. Kestrel is intentionally **not** used — dnSpy's self-contained .NET bundle does not ship ASP.NET Core, so any `Microsoft.AspNetCore.*` reference would cause a silent `TypeLoadException` during MEF composition and the extension's `IExtension` part would never instantiate.\n- **MEF**: services use `[Export(typeof(T))]` + `[ImportingConstructor]`. Don't `new` up `McpServer` / `McpSettings` / `McpTools`.\n- **Error codes**: `ArgumentException` inside a tool handler → JSON-RPC `-32602` (invalid params); any other exception → `-32603` (internal error).\n- **Logging**: `McpSettings.Log(...)` writes to both the in-UI log pane and an on-disk fallback file. The on-disk log is authoritative — it survives when the dispatcher isn't yet running or when the Settings dialog is closed.\n\n## Protocol\n\nImplements [MCP](https://modelcontextprotocol.io/) version `2024-11-05` over JSON-RPC 2.0.\n\nSupported methods: `initialize`, `ping`, `tools/list`, `tools/call`, `resources/list`, `resources/read`, and `notifications/*`.\n\n## CI / Release\n\n- `.github/workflows/build.yml` — builds both TFMs on every push/PR.\n- `.github/workflows/release.yml` — builds release DLLs and attaches them to the GitHub release on tag push (`v*.*.*`).\n\n```bash\ngit tag v1.0.0\ngit push origin v1.0.0\n```\n\n## Technical details\n\n- **Dependencies**: `dnSpy.Contracts.DnSpy`, `dnSpy.Contracts.Logic`, `dnlib`, `System.Text.Json` (package on `net48`, in-box on `net10.0-windows`).\n- **BFS path finding**: `find_path_to_type` does breadth-first search over each type's fields and properties.\n- **Decompilation**: uses dnSpy's default decompiler (usually C#) via `IDecompilerService`.\n\n## Troubleshooting\n\n### Settings page shows but the server never starts\n\nMost commonly a MEF composition failure for the `IExtension` part while `IAppSettingsPageProvider` (the settings page) composes fine. Symptoms: the MCP Server page exists and lets you toggle Enable Server, but nothing happens on click and no log ever appears. Root cause is usually a missing runtime dependency — check the on-disk fallback log first, and make sure you deployed the DLL matching your dnSpy TFM.\n\n### Port already in use\n\nThe server automatically falls back to `port + 1` (up to 20 tries). Look for `Port N is in use; falling back to M` in the log — clients should connect to the fallback port.\n\n### Build errors\n\n- Ensure you cloned dnSpyEx with `--recursive` (submodules must be initialized).\n- Run `dotnet restore` in the dnSpyEx repo root.\n- Requires .NET 10 SDK (previous dnSpy versions used .NET 8; `DnSpyCommon.props` is the source of truth).\n\n## License\n\nSame as dnSpyEx — see the [dnSpyEx repository](https://github.com/dnSpyEx/dnSpy).\n\n## Acknowledgments\n\n- [dnSpyEx](https://github.com/dnSpyEx/dnSpy) — .NET debugger and assembly editor\n- [Model Context Protocol](https://modelcontextprotocol.io/) — Anthropic's MCP specification\n- [BepInEx](https://github.com/BepInEx/BepInEx) — Unity game modding framework\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkernelerr%2Fdnspy.extension.mcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkernelerr%2Fdnspy.extension.mcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkernelerr%2Fdnspy.extension.mcp/lists"}