Content
# dotnet-dll-inspector
**A token-efficient MCP server and CLI for exploring .NET DLL and EXE metadata.**
Instead of decompiling an assembly or pasting a large PowerShell reflection dump into an LLM conversation, give the model a local assembly path. It can discover the relevant types first and request members only for the small API surface it needs.
> Status: early public release. Works with managed assemblies that expose CLI metadata. Some runtime-specific or ReadyToRun assemblies may not be supported by the underlying metadata parser yet.
## Why it exists
LLMs are good at reasoning about APIs, but inefficient when the context is a large binary, decompiled source tree, or an unfiltered reflection report. This tool turns a local .NET assembly into compact, structured metadata over the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/).
It is useful for:
- DLLs from internal applications when source is unavailable.
- NuGet package assemblies.
- Legacy .NET integrations.
- API discovery before writing code against an unfamiliar dependency.
## Acknowledgements and upstream project
The core .NET PE/CLI metadata parsing capability comes from [nickbclifford/dotnetdll](https://github.com/nickbclifford/dotnetdll), the Rust library this project depends on. `dotnet-dll-inspector` is a focused MCP/CLI integration built around that library's metadata model and parsing APIs.
`dotnetdll` is licensed under the GNU General Public License, version 3 or later. Because this project distributes a binary linked with that library, `dotnet-dll-inspector` is likewise licensed under GPL-3.0-or-later. See [NOTICE](NOTICE) and [LICENSE](LICENSE).
## Install
Download `dotnet-dll-inspector-windows-x86_64.exe` from the repository's **Releases** page and put it on your `PATH`.
Or build it yourself:
```powershell
git clone https://github.com/AndriiHavrylov/Dotnet_dll_inspector_mcp.git
cd Dotnet_dll_inspector_mcp
cargo build --release
```
The binary is created at `target\release\dotnet-dll-inspector.exe`.
## Use with Codex
Add the server to `%USERPROFILE%\.codex\config.toml` for all projects, or to `.codex/config.toml` for one project:
```toml
[mcp_servers.dotnet_dll_inspector]
command = 'C:\Tools\dotnet-dll-inspector-windows-x86_64.exe'
args = ["--mcp"]
```
Restart Codex after changing the configuration. Codex will expose this MCP tool:
| Tool | What it does |
| --- | --- |
| `inspect_dotnet_assembly` | Lists matching types and, when requested, their properties, methods, and fields. |
### Recommended prompt sequence
1. “Inspect `C:\packages\Example.dll`; list types containing `Invoice`.”
2. “For `Example.InvoiceService`, include members.”
3. “Show me how to create an invoice using the methods found.”
This progressive narrowing keeps the model context focused.
## Tool contract
| Argument | Required | Default | Description |
| --- | --- | --- | --- |
| `path` | Yes | — | Absolute or server-working-directory-relative DLL/EXE path. |
| `type_filter` | No | all types | Case-insensitive substring matched against fully-qualified type names. |
| `include_members` | No | `false` | Includes properties, methods, and fields for each matching type. |
| `max_types` | No | `100` | Limits results from 1 to 1,000; responses say when they were truncated. |
The response is structured JSON. A typical detailed result looks like:
```json
{
"types": [{
"name": "Example.InvoiceService",
"methods": [{
"name": "Create",
"return_type": "Invoice",
"parameters": ["Customer", "decimal"]
}]
}],
"total_matches": 1,
"truncated": false
}
```
## CLI
The direct CLI remains available for scripts and diagnostics:
```powershell
# List type names
dotnet-dll-inspector --file C:\path\to\library.dll
# Filter a type and emit JSON with members
dotnet-dll-inspector --file C:\path\to\library.dll --match-str InvoiceService --json
# Run the MCP stdio server
dotnet-dll-inspector --mcp
```
## Token and cost comparison
The tool does not magically make an LLM's reasoning free; it reduces the **assembly-discovery context** the model must consume. The following example compares a common reflection workflow with a two-step MCP workflow.
### Illustrative inspection: find one service in a medium-sized NuGet assembly
Assumptions:
- PowerShell returns an unfiltered type/API report and the agent receives all of it.
- The assembly has about 1,500 types, with an API dump of roughly 180,000 characters.
- The MCP flow first lists matching type names, then requests members for one type.
- Token estimates use `characters ÷ 4`, a deliberately simple cross-model approximation. Tool-call arguments and model reasoning are included as conservative estimates.
| Step | Default PowerShell + broad text return | Approx. tokens | Custom MCP tool | Approx. tokens |
| --- | --- | ---: | --- | ---: |
| Locate the DLL | Directory/package search output | 800 | `path` argument | 80 |
| Discover API surface | Full reflection/type dump (~180k characters) | 45,000 | `type_filter` type inventory | 3,500 |
| Select the relevant API | Model reads and narrows the broad output | 2,000 | Model selects a short matching list | 500 |
| Inspect members | Broad `Get-Member`/reflection output | 8,000 | One detailed matching type | 1,500 |
| **Total** | **Multiple shell turns and large text payloads** | **55,800** | **Two focused MCP calls** | **5,580** |
That example avoids approximately **50,220 tokens (about 90%)** before the model starts solving the actual coding problem.
### Approximate input-cost impact
Use the table with your own provider's current **input** price. It models only the assembly-inspection portion of a task, not the model's final answer or any cached-token discounts.
| Input price per 1M tokens | Broad PowerShell flow (55,800 tokens) | Focused MCP flow (5,580 tokens) | Approximate saving |
| ---: | ---: | ---: | ---: |
| $1 | $0.0558 | $0.0056 | **$0.0502** |
| $5 | $0.2790 | $0.0279 | **$0.2511** |
| $15 | $0.8370 | $0.0837 | **$0.7533** |
For a rough binary-only upper bound, Base64-encoding a DLL costs about `DLL bytes ÷ 3` tokens, while a targeted JSON response costs roughly `JSON characters ÷ 4`. Do not send binaries to a model as a replacement for local inspection.
These are transparent planning estimates—not a claim about any specific model tokenizer, provider price, caching behavior, or every DLL. Measure actual request usage in your environment when cost matters.
## Releases
Pushing a tag such as `v0.1.0` runs the release workflow on Windows. It builds the optimized executable and attaches both of these assets to the GitHub Release:
| Asset | Purpose |
| --- | --- |
| `dotnet-dll-inspector-windows-x86_64.exe` | Downloadable Windows executable. |
| `SHA256SUMS.txt` | SHA-256 integrity checksum for the executable. |
## Development
```powershell
cargo fmt -- --check
cargo clippy -- -D warnings
cargo test
cargo build --release --locked
```
Pull requests and pushes to `main` run the same checks in GitHub Actions.
## Security and privacy
The server reads the assembly path supplied by the MCP client and returns metadata to that client. Treat DLL paths and their metadata as potentially sensitive. Do not enable the server for clients you do not trust, and avoid passing paths outside the intended workspace.
To report a security issue privately, see [SECURITY.md](SECURITY.md).
## Contributing
Contributions are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) before opening an issue or pull request.
## License
GNU General Public License v3.0 or later. See [LICENSE](LICENSE) and [NOTICE](NOTICE).