Install
$ agentstack add mcp-tadis174-ilens ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
ILens
An MCP server that lets AI agents inspect compiled .NET assemblies — list types, decompile methods, run cross-reference analysis — without burning tokens on full-file dumps.
Why
The default fallback for an AI agent inspecting a compiled .NET assembly is to shell out to ildasm (IL dump) or ilspycmd (full-C# decompile). Both dump an entire file as text, and that output stays in the agent's context as input tokens on every subsequent turn — quickly thousands of tokens spent inspecting a single class.
| Task | ilspycmd cost | ILens tool | ILens cost | |------|----------------:|------------|-----------:| | List the public types in a namespace | 1,041,476 tokens | list_types | 1,196 tokens | | See the API surface of one mid-sized class | 1,041,476 tokens | summarize_type | 895 tokens | | Find which types expose a given method | 1,041,476 tokens | find_methods | 618 tokens |
Measured against ICSharpCode.Decompiler.dll 9.1.0.7988 on 2026-06-23; token figures are character counts divided by 4, not a real tokenizer.
ILens turns assembly inspection into bounded, targeted lookups: list types in a namespace, summarize one type's public surface, find methods by name, decompile a single method body, run cross-reference analysis (callers, overrides, implementations, extension methods, attribute usage). Each call returns a focused response — making it cheap enough to leave registered as an always-available tool.
Scope
ILens is built for inspecting C# assemblies, and its output is C#. The metadata-driven tools (list_types, search_types, list_members, find_methods, analyze) read language-agnostic metadata and work on an assembly from any .NET language. The decompiling tools (decompile_type, decompile_method, decompile_property, decompile_event, summarize_type) always emit C# — for an assembly compiled from F#, VB.NET, or C++/CLI they still run, but constructs without a C# equivalent may render unfaithfully.
Built on ILSpy
ILens would be nothing without ILSpy. The decompiler, the analyzer, the type system that lets ILens speak about a .NET assembly in C# terms at all — none of that is ILens's. It belongs to the ILSpy team. The two libraries ILens links — ICSharpCode.Decompiler for the decompiler proper, ICSharpCode.ILSpyX for the analyzer infrastructure — represent more than a decade of careful work; this project is, candidly, a thin MCP shim on top.
That work is MIT-licensed, which is the only reason ILens can exist. If ILens is useful to you, please consider giving ILSpy a star. They earned it.
To be clear: bug reports and feature requests about ILens belong on the ILens issue tracker, not ILSpy's. Please don't take downstream problems to the upstream maintainers — they have enough work of their own.
Installation
System requirements: Windows 10/11, x64. The binary is self-contained — no separate .NET runtime install required.
winget install Tadis.ILens
Standard winget portable install. The binary lands under %LOCALAPPDATA%\Microsoft\WinGet\Packages\ and ilens becomes available on your user PATH automatically. No admin elevation needed.
See the user guide for alternative installers, updating, and installation troubleshooting.
Setup
Step 1: Register the server
Add an entry to .mcp.json in your project root. The installer adds ilens to your PATH, so the command field references the binary by name — no full path needed:
{
"mcpServers": {
"ilens": {
"command": "ilens",
"args": [
"--allow-root", "C:\\path\\to\\dlls"
]
}
}
}
Each --allow-root flag adds a directory tree from which assemblies may be loaded. Without any --allow-root flags, the server cannot load any assemblies. Tool calls supply the assembly path per request; the server validates that the path is inside one of the configured roots, rejects path traversal (..), resolves symbolic links and junctions before re-checking containment, and bounds total memory with an aggregate budget (default 200 MB, --max-total-size ).
Tool calls then specify which assembly to inspect:
list_types(assembly="C:\\path\\to\\dlls\\MyApp.dll", namespaceName="MyApp.Models")
The list_allowed_roots tool surfaces the configured roots so the agent can discover what's reachable.
> Heads up — a first install needs a full restart, not just a new session. Windows captures PATH per-process at launch, so an already-running Claude app holds a stale environment whenever ilens is a brand-new entry on user PATH (true for a first-ever winget portable install, or any install.ps1 run). Claude Code reads .mcp.json only at session start, so the new server isn't registered in any running session either. Recipe: close Claude app entirely → install ILens → relaunch Claude app → start a new Claude Code session in the relaunched app. Resumed sessions survive a Claude app restart and still hold the old environment, so they won't find ilens. Subsequent winget upgrade Tadis.ILens runs don't change PATH; they only need a fresh Claude Code session.
Step 2: Tell Claude to use it
Without this, Claude won't actually pick ILens — it'll keep reaching for ildasm via Bash, reading assembly files directly, or web-searching for source. Drop the following block into your project's CLAUDE.md and replace `` with the directory configured above:
````markdown
Inspecting .NET assemblies
Assemblies under ` are reachable through the ilens MCP server. Prefer ILens tools over running ildasm / ilspycmd` via Bash, reading assembly files directly, or web-searching for source.
- Discovery:
search_types(substring match),list_types(whole namespace),
find_methods (signature search).
- Reading:
summarize_type(public surface, no bodies),list_members
(filtered surface), decompile_type (full C#), decompile_method (single method body), decompile_property / decompile_event (full property or event declaration with accessor bodies, by unprefixed name).
- Cross-references:
analyzewithkindset to one ofUsedBy,
InstantiatedBy, ExposedBy, ExtensionMethods, AppliedTo, OverriddenBy, ImplementedBy, Uses, Implements, ReadBy, AssignedBy. Valid kinds depend on the symbol category.
- Comparing two builds:
list_changed_types(what differs between two
assemblies), compare_type (per-type member and body diff), compare_method (one method's body as C# or IL).
````
Per-line walkthrough
- The first paragraph is the load-bearing prefer-MCP rule. Without it, models default to
Bash. - The discovery bullet routes "I don't know the full name" tasks to the right tool: a partial name goes to
search_types, a known namespace goes tolist_types, a method shape goes tofind_methods. - The reading bullet escalates from cheapest to most expensive:
summarize_typefirst,list_memberswhen only part of the surface is needed,decompile_methodfor one method body (ordecompile_property/decompile_eventfor the whole property or event without having to know the IL accessor prefix),decompile_typeonly when full source is required. - The
analyzebullet enumerates thekindenum so the model picks values the schema accepts — using one that does not apply to the symbol category produces an error likeAnalysis kind 'ReadBy' is not valid for Method. - The comparison bullet is for "did this change between two builds?" work:
list_changed_typesto find what differs,compare_typefor one type's member and body diff,compare_methodto read a single differing body.
Full reference
A self-contained HTML user guide covers what this README does not:
- Per-tool reference — every tool, every parameter (with
required/optionalflags and types), return shape, and full list of error conditions - Alternative integration paths —
claude mcp addCLI command, Claude Desktop config - Security model — what's enforced (
--allow-rootmandatory, no traversal, no network, 200 MB cap, read-only), and what's not - Troubleshooting — error string → likely cause mapping
Read it online at https://tadis174.github.io/ILens/guide.html, or open the bundled guide.html from the release ZIP.
Building from source
If you'd rather build the binary yourself:
dotnet build -c Release
dotnet publish -c Release
The publish target produces Build/dist/ILens.exe along with LICENSE, README.md, guide.html, and third-party-licenses/. The working tree must be clean before publishing, and Build/doc/guide.html must exist (run the project's /doc skill to regenerate it).
License
ILens is released under the [MIT License](LICENSE). Third-party dependencies are documented in third-party-licenses/INDEX.md, included in each release alongside the per-source license texts.
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: tadis174
- Source: tadis174/ILens
- License: MIT
- Homepage: https://tadis174.github.io/ILens/guide.html
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.