Skip to content

Add an MCP for for PDB analysis#49

Merged
sivadeilra merged 8 commits intomicrosoft:mainfrom
sivadeilra:ardavis/pdb-mcp
Feb 27, 2026
Merged

Add an MCP for for PDB analysis#49
sivadeilra merged 8 commits intomicrosoft:mainfrom
sivadeilra:ardavis/pdb-mcp

Conversation

@sivadeilra
Copy link
Copy Markdown
Contributor

This adds a rudimentary MCP for PDB analysis. Claude says it's useful.

New workspace member pdb-mcp — an MCP (Model Context Protocol) server
that provides structured access to PDB files via 18 tools:

Session: open_pdb, close_pdb, list_pdbs
Metadata: pdb_info (full PDBI), pdb_streams, read_stream (raw data)
Modules: list_modules (dual regex filters), module_symbols, module_source_files
Symbols: find_global (GSI), find_public (PSI), find_public_by_addr, search_symbols
Types: find_type, dump_type
Sections: section_headers, coff_groups
Stats: pdb_stats

Built with rmcp 0.1.5 (official Rust MCP SDK), communicates via stdio.
Includes comprehensive safety guidance for prompt injection defense —
PDB data (symbol names, paths, SourceLink URLs) is treated as untrusted.
New standalone tool:
- undecorate: demangle C++/Rust symbol names without requiring an open PDB.
  Supports MSVC C++ (?-prefix), Rust legacy (_ZN), Rust v0 (_R), and
  Itanium C++ (_Z) mangling schemes.

New optional parameter on symbol tools:
- find_global, find_public, find_public_by_addr, search_symbols, and
  module_symbols all accept undecorate=true to show both decorated and
  undecorated names in a single query, saving an inference cycle.

Dependencies: msvc-demangler 0.11, rustc-demangle 0.1, cpp_demangle 0.5
New tool that follows the full S_PROCREF → S_GPROC32 indirection in a single
call. Given a function name, resolves it through the GSI to the actual
procedure record in the module stream and walks the scope hierarchy.

Input: name (GSI lookup) or module+offset (direct). Boolean flags control
which details are included in the output.

Output (text, structured):
- Always: name, address, code length, debug start/end, type signature, flags, module
- params=true (default): parameter names + types from S_LOCAL with fIsParam
- locals=true: local variable names + types
- inlinees=true: S_INLINESITE inlinee ItemIds
- blocks=true: S_BLOCK32 scope nesting with addresses

Type resolution: walks TPI for named types (structs, enums, unions, pointers,
arrays, modifiers, procedures). Primitives use dump_primitive_type_index.

Tested against KernelBase.pdb:
- CreateFileW: 7 params resolved with correct types
- GetLastError: 0xa bytes, 0 params, returns T_ULONG
- CreateProcessInternalW: params + locals + inlinees
Three new tools for address resolution:

- rva_to_section: Convert RVA to section:offset using COFF section headers
- section_to_rva: Convert section:offset to RVA
- addr_to_line: Full symbolic resolution — given an RVA or section:offset,
  returns module (via section contributions binary search), enclosing
  function (via module symbol scan), source file and line number (via C13
  line data). The equivalent of a debugger's 'ln' command.

Tested against KernelBase.pdb:
- CreateFileW at [1:000564d0] → fileopcr.c line 1209
- GetLastError at [1:000b8d60] → perf.c line 47
@sivadeilra sivadeilra merged commit b5b3944 into microsoft:main Feb 27, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant