Metadata Inspector

Browse and explore .NET assembly metadata. Standalone command-line tool. The Community edition is free and fully featured for everyday inspection; the Enterprise edition adds natural-language queries, side-by-side assembly diff, an MCP server for AI-driven inspection, and structured JSON output — unlocked by your existing Demeanor Enterprise license key.

Overview

The Metadata Inspector is a standalone command-line tool for examining .NET assembly metadata. It ships as a separate global tool (WiseOwl.Inspector, command inspector) and runs without any license key for its Community feature set. Installing WiseOwl.Demeanor auto-installs Inspector on first use; you can also install it directly without ever buying Demeanor. It reads any .NET assembly (Framework, Core, .NET 5–10) and lets you explore its types, methods, fields, properties, events, custom attributes, IL code, and all 31 ECMA-335 metadata tables.

Some Inspector capabilities (--query, --diff, --mcp, --json) require a Demeanor Enterprise license key supplied via the DEMEANOR_LICENSE environment variable. The same key unlocks both Demeanor Enterprise and Inspector Enterprise — there is no separate Inspector license. See Community vs Enterprise below for the full split.

Use it to:

  • Understand the structure of any .NET assembly
  • Verify what an obfuscator preserved or renamed
  • Compare assemblies before and after obfuscation Enterprise
  • Audit assemblies for specific attributes, interfaces, or patterns
  • Decode custom attribute blobs without writing code

Community vs Enterprise

Inspector ships in two editions. Community is the default state when no license key is present — free, fully featured for everyday inspection, no time limit, commercial use permitted. Enterprise unlocks at runtime when the DEMEANOR_LICENSE environment variable is set to a valid Demeanor Enterprise key. The same key unlocks Demeanor Enterprise and Inspector Enterprise; there is no separate Inspector license to buy.

CapabilityCommunityEnterprise
Interactive REPL (inspector MyApp.dll)
One-shot summary (--summary)
Per-table dump for all 31 ECMA-335 metadata tables (--table <name>)
All metadata tables in one shot (--metadata)
Unified type view (--type), composable with --method and --il
Full IL disassembly (--il)
Cross-table find by name pattern (find in REPL)
Filter rows scoped or unscoped (--filter, --public-only)
Dependencies view (--dependencies)
Natural-language metadata queries (--query) — "show methods returning string", "which types implement IDisposable", "how many fields"
Side-by-side assembly diff (--diff) — added / removed / renamed types and members
MCP server (--mcp) — drive Inspector from Claude Code, Cursor, Windsurf, Continue.dev, or any MCP-capable assistant
Structured JSON output (--json) — for tooling and CI integration

To unlock Enterprise capabilities, set DEMEANOR_LICENSE to your Enterprise key on the machine where Inspector runs:

setx DEMEANOR_LICENSE "your-enterprise-key"      # Windows (persistent)
export DEMEANOR_LICENSE="your-enterprise-key"    # Linux / macOS

Close and reopen your terminal afterward so the new variable is picked up. If the variable is unset or invalid, Inspector continues to run with Community features and will tell you so on stderr if you try an Enterprise-only flag. See pricing for Enterprise license details.

Installation

Installing Demeanor auto-installs the inspector the first time you run demeanor, so inspector is already on your PATH if you followed Getting Started. To install the inspector on its own (no Demeanor required):

dotnet tool install -g WiseOwl.Inspector

Then run:

inspector MyApp.dll

Two Ways to Use It

One-shot mode (CLI flags)

Pass flags to get a specific view and exit:

inspector MyApp.dll --summary
inspector MyApp.dll --table typedef
inspector MyApp.dll --type WeatherForecast
inspector MyApp.dll --query "show public methods returning string"

Interactive mode (REPL)

Launch without flags to enter the interactive prompt. Type queries directly:

inspector MyApp.dll

inspector> summary
inspector> show public methods
inspector> which types implement IDisposable
inspector> describe OrderService
inspector> quit

Query Language Enterprise

The inspector understands structured English queries beyond the Community-tier summary and find commands. You don't need to memorize command syntax — describe what you want to see. The inspector shows how it interpreted your query before displaying results. The natural-language query engine documented below is part of the Enterprise edition (one-shot via --query / -q, or interactively in the REPL when a valid DEMEANOR_LICENSE is set).

Showing items

QueryWhat it does
summaryAssembly identity, version, and row counts
show typesList all types
show methodsList all methods
show fieldsList all fields
show propertiesList all properties
show eventsList all events
show resourcesList embedded resources
show assembly referencesList referenced assemblies
show custom attributesList custom attributes
show interfacesList interface types

Filtering by accessibility

QueryWhat it does
show public typesOnly public types
show public methodsOnly public methods
show internal typesOnly internal types
show private methodsOnly private methods

Filtering by signature

QueryWhat it does
show methods returning stringMethods whose return type contains "string"
show methods returning voidMethods returning void
show methods that take intMethods with a parameter type containing "int"
show static methodsStatic methods only
show virtual methodsVirtual methods only
show abstract methodsAbstract methods only

Filtering by owner / location

QueryWhat it does
show methods on CalculatorMethods declared on types matching "Calculator"
show fields on OrderServiceFields on types matching "OrderService"
types in namespace MyApp.ModelsTypes in a specific namespace

Filtering by type hierarchy

QueryWhat it does
which types implement IDisposableTypes implementing a specific interface
types that inherit from ExceptionTypes with a specific base class
types with attribute SerializableTypes decorated with a specific attribute
show generic typesTypes with generic parameters
show sealed typesSealed types

Counting

QueryWhat it does
how many typesCount of types
how many methodsCount of methods
how many fieldsCount of fields
how many propertiesCount of properties
count resourcesCount of embedded resources

Detail views

QueryWhat it does
describe OrderServiceFull type detail: base type, interfaces, fields, methods, properties
show type CalculatorSame as describe
what is WeatherForecastSame as describe

Searching

QueryWhat it does
find CalculatorSearch all types, methods, fields, and properties for "Calculator"
find DisposeSearch across all tables for "Dispose"

How matching works

All name matching is case-insensitive and uses substring containment by default. show methods on Order matches OrderService, OrderRepository, and ReorderQueue.

Driving the inspector from an AI assistant Enterprise

This section is optional. The inspector’s primary interface is the CLI documented above — the REPL and one-shot commands cover every capability, and the structured English query language needs no AI to work.

If you already use an MCP-capable assistant (Claude Code, Claude Desktop, Cursor, Windsurf, Continue.dev, or any other MCP client), the inspector’s built-in MCP server (--mcp) lets the assistant answer the same questions in conversation on your behalf. The inspector auto-registers with detected MCP clients the first time you install it — nothing to configure, no separate API key. Everything runs locally over stdio; no assembly data leaves your machine. The MCP surface exposes 9 tools (inspect_query, inspect_summary, inspect_types, inspect_methods, inspect_fields, inspect_properties, inspect_attributes, inspect_find, inspect_diff) the assistant can call.

The MCP server requires a valid DEMEANOR_LICENSE Enterprise key. Requires your own Claude subscription — not included with Demeanor. Any other MCP-capable assistant works the same way with its own subscription.

Ask it anything

What should I exclude before obfuscating this assembly?
The assistant inspects serializable types, data-bound properties, reflection usage, and public API surfaces, then recommends exclusions with rationale.
Which types implement IHostedService?
The assistant queries the metadata and lists the matching types with a brief note on how each one is used.
Compare the pre- and post-obfuscation builds — did anything framework-critical get renamed?
The assistant diffs the two assemblies, separates public from internal renames, and flags anything that should have been frozen but wasn’t.
After obfuscation I’m getting a JSON deserialization error. What went wrong?
The assistant reads both builds, identifies which original type was renamed into the conflict, and suggests the fix.

See the conversational walkthrough for an end-to-end conversation where the assistant drives both the inspector and Demeanor’s audit surface in the same session.

One-Shot CLI Options

All options work from the command line for scripting and CI/CD integration.

Options marked Enterprise require a valid DEMEANOR_LICENSE environment variable. Unmarked options work in the Community edition with no key.

Display options

OptionDescription
--summaryAssembly identity and statistics
--metadataDisplay all metadata tables
--table <name>Display specific table(s). Repeatable.
--ilIL disassembly for all methods
--dependenciesAssembly, type, and member references
--type <pattern>Unified type view: fields, methods, properties, events, attributes, MethodImpls
--diff <other.dll> EnterpriseCompare against another assembly
--query <text>, -q EnterpriseNatural language query (one-shot)

Filters and formatting

OptionDescription
--filter <text>Filter rows by name substring. Supports scoped queries: type=Foo, parent=Bar, sig=string
--public-onlyRestrict output to public symbols
--json EnterpriseOutput structured JSON for tooling. Forces one-shot mode. Top-level licensedTo field carries the licensee identity.

MCP server Enterprise

OptionDescription
--mcpStart as an MCP server on stdio so an MCP-capable AI assistant can drive the inspector. Exposes 9 tools (inspect_query, inspect_summary, inspect_types, inspect_methods, inspect_fields, inspect_properties, inspect_attributes, inspect_find, inspect_diff). See Driving the inspector from an AI assistant.

Metadata Tables

The inspector can display any of the 31 ECMA-335 metadata tables. Use --table <name> in one-shot mode.

Core tables

Table nameContents
typedefTypes defined in this assembly (classes, interfaces, structs, enums, delegates)
methoddefMethods defined in this assembly
fielddefFields defined in this assembly
paramdefMethod parameters with names and default values
propertyProperties with getter/setter references
eventEvents with add/remove/fire accessors

Reference tables

Table nameContents
typerefTypes referenced from other assemblies
memberrefMethods and fields referenced from other assemblies
assemblyrefReferenced assemblies (dependencies)
typespecInstantiated generic types (e.g., List<string>)
methodspecInstantiated generic methods
modulerefReferenced modules (P/Invoke DLLs)

Relationship tables

Table nameContents
interfaceimplWhich types implement which interfaces
nestedclassNested type relationships
methodimplExplicit method overrides (.override directives)
methodsemanticsProperty/event accessor mappings
propertymapType → property group mappings
eventmapType → event group mappings
customattrCustom attributes on any metadata row

Generic tables

Table nameContents
genericparamGeneric type/method parameters (T, TKey, etc.)

Interop and layout tables

Table nameContents
implmapP/Invoke mappings (unmanaged function imports)
classlayoutExplicit class size and packing
fieldlayoutExplicit field offsets
fieldrvaFields with data stored at fixed RVAs
fieldmarshalMarshalling descriptors for interop
declsecurityDeclarative security attributes
standsigStand-alone signatures (local variable types)

Assembly-level tables

Table nameContents
resourceEmbedded and linked manifest resources
exportedtypeTypes forwarded to other assemblies
fileFiles in a multi-file assembly
constantCompile-time constants (field/param/property defaults)

Examples

Quick overview of an assembly

inspector MyApp.dll --summary

Compare before and after obfuscation

inspector obfuscated/MyApp.dll --diff original/MyApp.dll

Find all types that implement a specific interface

inspector MyApp.dll -q "which types implement IHostedService"

Audit for specific attributes

inspector MyApp.dll -q "types with attribute JsonSerializable"

Check what an obfuscator preserved

inspector obfuscated/MyApp.dll -q "show public properties"

Explore interactively

inspector MyApp.dll

inspector> summary
  Assembly:   MyApp
  Types:      142
  Methods:    891
  ...

inspector> show types implementing IDisposable
  -> Show types implementing IDisposable
  public class MyApp.Data.DbContext : System.Object
  public class MyApp.Services.HttpClientPool : System.Object
  (2 type(s))

inspector> describe DbContext
  -> Show details of type DbContext
  === MyApp.Data.DbContext ===
  Base: System.Object
  Implements: System.IDisposable
  Fields (3): ...
  Methods (12): ...

inspector> show methods on DbContext
  -> Show methods on DbContext
  ...

inspector> quit

Script-friendly JSON output

inspector MyApp.dll --json --summary

Drive from an AI assistant (optional)

If you already use an MCP-capable assistant, the inspector can be driven conversationally. See Driving the inspector from an AI assistant.

# Ask (if you use an MCP-capable assistant):
# "Show me all public methods that accept a CancellationToken and return Task"
# The assistant queries the inspector and answers in context.

How Query Translation Works

Under the hood, every query (whether typed as English or passed via --table) is converted into a structured InspectQuery object with these fields:

FieldPurposeValues
VerbWhat to doShow, Find, Count, Detail, List
TargetWhat metadata to queryTypes, Methods, Fields, Properties, Events, CustomAttributes, Interfaces, Resources, AssemblyRefs, Summary, All
FiltersWhich items to includeZero or more filter predicates (see below)
LimitMax resultsAny positive integer, or unlimited
FormatOutput formatTable, Detail, Json, IL

Available filter fields

Each filter has a field, an operator, and a value. Not every field applies to every target — the inspector validates compatibility and rejects mismatched combinations.

Filter fieldApplies toExample
NameAll targetsMethods named "Dispose"
FullNameTypes, MethodsTypes with full name containing "Models"
NamespaceTypesTypes in namespace "MyApp.Data"
ReturnTypeMethodsMethods returning "string"
ParameterTypeMethodsMethods taking "CancellationToken"
FieldTypeFieldsFields of type "Dictionary"
PropertyTypePropertiesProperties of type "string"
BaseTypeTypesTypes inheriting from "Exception"
ImplementsTypesTypes implementing "IDisposable"
HasAttributeTypes, MethodsTypes with [Serializable]
AccessibilityTypes, MethodsPublic, private, internal, protected
OwnerMethods, FieldsMethods on type "Calculator"
IsStaticTypes, Methods, FieldsStatic methods
IsAbstractTypes, MethodsAbstract types or methods
IsSealedTypesSealed types
IsGenericTypesGeneric types (with type parameters)
IsVirtualMethodsVirtual methods
TextAll (search mode)Free-text search across all names

Filter operators

OperatorMeaning
ContainsValue appears anywhere in the field (default, case-insensitive)
EqualsExact match (case-insensitive)
StartsWithField starts with the value
EndsWithField ends with the value
NotField does NOT contain the value
GreaterThanNumeric comparison (for count fields)
LessThanNumeric comparison (for count fields)

In the CLI, the -> interpretation line shows you how your English was parsed before execution. When driving the inspector from an AI assistant, the assistant constructs queries using these same fields and operators.