Skip to content

Objdiff CLI MCP Server - #400

Draft
HaydnTrigg wants to merge 5 commits into
encounter:mainfrom
HaydnTrigg:objdiff-mcp
Draft

Objdiff CLI MCP Server#400
HaydnTrigg wants to merge 5 commits into
encounter:mainfrom
HaydnTrigg:objdiff-mcp

Conversation

@HaydnTrigg

Copy link
Copy Markdown
Contributor

MCP server for AI-driven decomp matching.

Important

  • Benchmarking of this MCP server has been limited. Testing so far has used Anthropic models exclusively due to other AI models being incapable of producing usable output on tested projects.
  • A future experiment (not part of this PR scope) is switching to a TOML/Markdown output format, which reportedly could cut token usage further.

Usage

Usage: objdiff-cli mcp [--transport <transport>] [--bind <bind>] [--project <project>]

Starts an MCP server exposing objdiff's diffing for decompilation matching.

Options:
      --transport <transport>  Transport: "stdio" or "http". (Default: stdio)
      --bind <bind>            Bind address for the http transport. (Default: 127.0.0.1:3001)
      --project <project>      Optionally remember a project directory on startup.

Runs persistently over stdio (--transport stdio) or a shared HTTP instance (--transport http --bind ...). State (loaded project + diff config) is shared across sessions for the life of the process.

Tools:

  • open_project / list_units - load objdiff.json, refer to units by name
  • list_units(filter?) - units + resolved target/base paths
  • diff_function(symbol, unit | target+base, config?) - side-by-side per-instruction diff + match% for one function
  • diff_overview(unit | target+base, only_mismatches?, limit?, config?) - functions ranked worst-match-first
  • build(unit, target?) - run the project's build command for a unit (via objdiff-core run_make)
  • set_config(key, value) - persistent diff/disassembly config overrides
  • list_symbol_mappings(unit) - manual target=base mappings
  • set_symbol_mapping(unit, target_symbol?, base_symbol?)
  • version()

diff_function / diff_overview accept either a project unit or explicit target/base object paths, plus per-call config overrides.

Testing

This code has been tested for over a month across two extremely large decompilation projects. Using three Claude Max 20x subscriptions using models Opus 4.8, Opus 5, Fable 5 in Ultracode mode. Rough estimates put token usage 30–50% lower than the command-line and logging workflow depending on context.

This seems to be caused by the models having short-circuits to use MCP servers compared to thinking about command line usage (we've switched over to a few other MCP servers before this and saw similar token usage reductions). Due to Anthropic mostly being a black box one can only speculate.

camden-smallwood and others added 5 commits August 16, 2026 10:30
New workspace crate `objdiff-mcp` exposing objdiff's diffing over the
Model Context Protocol (rmcp 2.1) so a model can drive matching without UI.

Runs persistently over stdio (--transport stdio) or a shared HTTP instance
(--transport http --bind ...). State (loaded project + diff config) is shared
across sessions for the life of the process.

Tools:
- open_project / list_units: load objdiff.json, refer to units by name
- diff_function: side-by-side per-instruction diff + match% for one function
- diff_overview: functions ranked worst-match-first
- build: run the project's build command for a unit (via objdiff-core run_make)
- set_config: persistent diff/disassembly config overrides
- version

diff_function / diff_overview accept either a project unit or explicit
target/base object paths, plus per-call config overrides.

Added to workspace members (not default-members) to keep default builds lean.
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.

2 participants