Skip to main content
Glama
ouonet

x64dbg MCP Server

by ouonet
README.md
# x64dbg MCP Server

A production-level [Model Context Protocol](https://modelcontextprotocol.io) server that exposes **x64dbg** reverse-engineering and debugging capabilities to AI assistants over **STDIO** or **Streamable HTTP**.

It is designed for practical debugger automation, not just toy examples:

- Auto-detects PE architecture and launches `x32dbg` or `x64dbg` as needed
- Supports both `load_executable` and `attach_to_process`
- Exposes debugging, memory, analysis, and security triage tools through MCP
- Uses a lightweight bridge plugin and talks to `x64bridge.dll` directly via `ctypes`
- Does not depend on `x64dbgpy`

## Quick Start

### Recommended path

```bash
npm install -g x64dbg-mcp
x64dbg-mcp setup
x64dbg-mcp doctor
```

After that, choose one transport:

- **STDIO**: let your MCP host launch `x64dbg-mcp` directly
- **Streamable HTTP**: start a long-running server with:

```powershell
x64dbg-mcp --transport streamable-http --host localhost --port 3000
```

The HTTP endpoint is fixed at `http://localhost:3000/mcp`.

`stdio` and `streamable-http` are the supported startup transports. The SDK still ships a standalone SSE server transport, but it is deprecated and this project does not expose it as a separate mode.

## Requirements

- **Windows** only, because x64dbg is Windows-only
- **Node.js 20+**
- **Python 3.10+**
- **CMake 3.15+** plus MSVC or MinGW only if you need to build the C loader from source

`npm install` downloads x64dbg automatically if it is not already available. The `iced_x86` Python package is also installed automatically into detected Python environments; if that installation fails, the bridge falls back to x64dbg's own disassembly APIs.

## Installation

### Global npm install

```bash
npm install -g x64dbg-mcp
```

The global install path is the simplest one. Its `postinstall` step handles the usual setup work:

| Step | What happens |
| --- | --- |
| x64dbg | Downloads the latest snapshot if not found locally |
| Plugin files | Deploys the loader and Python bridge files into the x64dbg plugins directories |
| Bridge auth | Generates `BRIDGE_AUTH_TOKEN` and writes `x64dbg_mcp_bridge.token` |
| Python | Detects Python install paths and records `PYTHON_HOME_X64` / `PYTHON_HOME_X86` |
| `iced_x86` | Installs it into detected Python environments if needed |
| `.env` | Creates a config file with detected values and defaults |

Before continuing, review the configuration values in the next section if your x64dbg install path, Python install path, or HTTP port should differ from the detected defaults.

Then run:

```bash
x64dbg-mcp setup
x64dbg-mcp doctor
x64dbg-mcp
```

If you need to rebuild and redeploy the loader manually, use:

```bash
x64dbg-mcp install-plugin
```

### Source checkout

Use this path if you are developing on the project itself:

```bash
git clone https://github.com/ouonet/x64dbg-mcp.git
cd x64dbg-mcp
npm install
npm run build
```

Then review the configuration section below, especially if `X64DBG_PATH`, Python paths, or the default HTTP port need to change.

```bash
npm run setup
npm run install-plugin
npm run doctor
npm start
```

To run HTTP mode from a source checkout:

```powershell
node .\dist\server.js --transport streamable-http --host localhost --port 3000
```

If you want the `x64dbg-mcp` command in a source checkout too, run `npm link` after `npm run build`.

If x64dbg already exists in a non-default location, set `X64DBG_PATH` in `.env` before `npm run install-plugin`.

### Manual plugin installation

Most users should not need this. Use it only if you want to build and copy the loader manually instead of running `install-plugin`.

```powershell
cd plugin\loader

# 64-bit
cmake -B build64 -A x64
cmake --build build64 --config Release
$p64 = "C:\x64dbg\release\x64\plugins"
Copy-Item build64\Release\x64dbg_mcp_loader.dp64 $p64
Copy-Item ..\x64dbg_mcp_bridge.py                $p64
Copy-Item ..\x64dbg_bridge_sdk.py                $p64

# 32-bit
cmake -B build32 -A Win32 -DBUILD_32BIT=ON
cmake --build build32 --config Release
$p32 = "C:\x64dbg\release\x32\plugins"
Copy-Item build32\Release\x64dbg_mcp_loader.dp32 $p32
Copy-Item ..\x64dbg_mcp_bridge.py                $p32
Copy-Item ..\x64dbg_bridge_sdk.py                $p32
```

`npm run install-plugin` performs the same work for both architectures by default. Pass `-No32` if you want to skip the 32-bit build.

## Configuration

`npm install` creates `.env` automatically. Edit that file directly, or run `setup` again if you want the interactive flow.

```env
# x64dbg path (auto-detected)
X64DBG_PATH=C:\x64dbg

# Python install directories used by the C loader
PYTHON_HOME_X64=C:\Python314
PYTHON_HOME_X86=C:\Python312-32

# Bridge
BRIDGE_HOST=127.0.0.1
BRIDGE_PORT=27042
BRIDGE_AUTH_TOKEN=<auto-generated>

# MCP transport defaults
MCP_TRANSPORT=stdio
MCP_HTTP_HOST=127.0.0.1
MCP_HTTP_PORT=3000

# Logging / limits
LOG_LEVEL=info
MAX_SESSIONS=1
SESSION_TIMEOUT_MS=3600000
```

| Variable | Default | Description |
| --- | --- | --- |
| `X64DBG_PATH` | auto-detected | x64dbg installation directory |
| `PYTHON_HOME_X64` | auto-detected | Preferred Python 64-bit install directory |
| `PYTHON_HOME_X86` | auto-detected | Preferred Python 32-bit install directory |
| `BRIDGE_HOST` | `127.0.0.1` | TCP host for the local bridge |
| `BRIDGE_PORT` | `27042` | TCP port for the local bridge |
| `BRIDGE_AUTH_TOKEN` | auto-generated | Shared secret for MCP to bridge requests |
| `MCP_TRANSPORT` | `stdio` | Default startup transport: `stdio` or `streamable-http` |
| `MCP_HTTP_HOST` | `127.0.0.1` | Default HTTP bind host |
| `MCP_HTTP_PORT` | `3000` | Default HTTP listen port |
| `LOG_LEVEL` | `info` | `error`, `warn`, `info`, or `debug` |
| `MAX_SESSIONS` | `1` | Active session limit for the current bridge architecture |
| `SESSION_TIMEOUT_MS` | `3600000` | Idle session timeout in milliseconds |

If you manually start x64dbg outside the MCP flow, keep the deployed `x64dbg_mcp_bridge.token` file in the plugins directory so the bridge enforces the same token as the MCP server.

## Use With Your MCP Host

> **Note:** You do not need to pre-launch x64dbg manually. The MCP server auto-launches the correct debugger when you call `load_executable` or `attach_to_process`.

### STDIO host configuration

Use STDIO when your MCP host can spawn a local process.

#### Claude Desktop

If you installed the package globally:

```json
{
  "mcpServers": {
    "x64dbg-mcp": {
      "command": "x64dbg-mcp"
    }
  }
}
```

If you are using a source checkout instead:

```json
{
  "mcpServers": {
    "x64dbg-mcp": {
      "command": "node",
      "args": ["C:\\path\\to\\x64dbg-mcp\\dist\\server.js"]
    }
  }
}
```

#### Windsurf / Cascade

```json
{
  "mcpServers": {
    "x64dbg-mcp": {
      "command": "node",
      "args": ["C:\\path\\to\\x64dbg-mcp\\dist\\server.js"],
      "env": { "BRIDGE_PORT": "27042" }
    }
  }
}
```

### Streamable HTTP

Use Streamable HTTP when you want to start x64dbg-mcp once and let an AI tool connect to it through a fixed local URL.

Start the server first.

If you installed the package globally:

```powershell
x64dbg-mcp --transport streamable-http --host localhost --port 3000
```

If you are running from a source checkout:

```powershell
node .\dist\server.js --transport streamable-http --host localhost --port 3000
```

Then connect your AI tool to this MCP endpoint:

```text
http://localhost:3000/mcp
```

Below are direct configuration examples for common AI tools.

#### Claude Code

Create a `.mcp.json` file in the project root:

```json
{
  "mcpServers": {
    "x64dbg-mcp": {
      "type": "http",
      "url": "http://localhost:3000/mcp"
    }
  }
}
```

Or add the same server to Claude Code with its CLI:

```bash
claude mcp add --transport http x64dbg-mcp http://localhost:3000/mcp
```

#### Windsurf / Cascade

Edit `~/.codeium/windsurf/mcp_config.json`:

```json
{
  "mcpServers": {
    "x64dbg-mcp": {
      "serverUrl": "http://localhost:3000/mcp"
    }
  }
}
```

If you already have other MCP servers configured in that file, just add the `x64dbg-mcp` entry under `mcpServers`.

If your AI tool does **not** support remote HTTP MCP servers and only knows how to launch a local command, use the STDIO setup above instead.

CLI flags override `MCP_TRANSPORT`, `MCP_HTTP_HOST`, and `MCP_HTTP_PORT` from the environment. The legacy `MCP_TRANSPORT=http` alias is still accepted for compatibility.

## Typical Prompts

These are good examples of the kinds of requests the MCP server is built to support:

- "Load `C:\samples\target.exe` and analyze it for suspicious behavior"
- "Attach to PID 1234 and inspect the current thread"
- "Find the license check function"
- "Generate a first-pass malware triage report"

Typical tool flows behind those prompts look like this:

| Goal | Typical tools |
| --- | --- |
| Load and debug a binary | `load_executable`, `get_status`, `continue_execution`, `wait_for_state`, `disassemble` |
| Attach to a live process | `attach_to_process`, `get_status`, `pause_execution`, `get_call_stack`, `get_registers`, `detach_session` |
| Malware triage | `generate_security_report`, `analyze_suspicious_apis`, `detect_anti_debug`, `find_strings` |
| Reverse engineering | `find_strings`, `get_cross_references`, `analyze_function`, `collect_bp_args` |

## Capabilities

The server exposes **38 tools** across four practical groups.

| Group | Scope |
| --- | --- |
| Core debugging | load or attach, control execution, manage breakpoints, inspect session state |
| Memory and registers | read and write memory, inspect registers, switch threads, walk call stacks |
| Analysis | disassembly, function analysis, cross references, modules, imports, exports, strings, traces |
| Security triage | packing checks, suspicious APIs, anti-debug detection, section anomalies, consolidated reports |

Representative tools include `load_executable`, `attach_to_process`, `get_status`, `read_memory`, `disassemble`, `analyze_function`, and `generate_security_report`.

## Architecture

```text
┌─────────────────┐  STDIO / HTTP     ┌──────────────────┐  TCP (JSON)  ┌──────────────┐
│  AI Assistant   │ ◄───────────────► │  MCP Server      │ ◄──────────► │  x64dbg      │
│  (Claude, etc.) │                   │  (Node.js / TS)  │  port 27042  │  + Bridge    │
└─────────────────┘                   └──────────────────┘              │    Plugin    │
                                                                        └──────────────┘
```

At a high level, the MCP server in `src/` speaks STDIO or Streamable HTTP to an AI client, then forwards requests over a local TCP bridge to the plugin running inside x64dbg. The plugin side is a lightweight C loader plus Python bridge that translates those requests into x64dbg Bridge SDK calls.

## Development And Testing

Development commands:

```bash
npm run ci
npm run ci -- --no-loader
npm run dev
npm run sync-plugin
npm run setup-x64dbg
npm run setup-x64dbg -- --force
npm run build
npm run lint
npm run clean
```

Testing commands:

```bash
npm test
python plugin/tests/test_bridge.py
npm run test:e2e
npm run test:http-smoke
npm run doctor
```

`npm run dev` automatically syncs Python files into the bundled x64dbg checkout before starting the server.

`npm run inspector` launches MCP Inspector. On first run it downloads `@modelcontextprotocol/inspector` via `npx`, so restricted environments may need `HTTP_PROXY` / `HTTPS_PROXY` or a global install.

Reusable verifier scripts live under `test/e2e/`. They require an explicit target:

- `TARGET_EXE=C:\path\to\sample.exe` for load-based verification
- `TARGET_PID=1234` or `TARGET_PROCESS_NAME=notepad` for attach-based verification

Examples:

```powershell
$env:TARGET_EXE = "C:\Windows\System32\notepad.exe"
node test/e2e/verify_breakpoint_chain.mjs

$env:TARGET_PROCESS_NAME = "notepad"
node test/e2e/verify_attach_chain.mjs
```

CI in `.github/workflows/ci.yml` runs TypeScript, Python, and loader-build jobs on every push. On tagged releases (`v*`), it also publishes the npm package with the prebuilt loader binaries included.

## Project Structure

```text
x64dbg-mcp/
├── src/
│   ├── server.ts              # Entry point and transport bootstrap
│   ├── cli.ts                 # CLI parsing for transport/host/port
│   ├── httpServer.ts          # Streamable HTTP server and MCP session handling
│   ├── mcpServer.ts           # Shared MCP server factory and tool registration
│   ├── bridge.ts              # TCP client for the x64dbg bridge
│   ├── launcher.ts            # PE detection and debugger startup
│   ├── session.ts             # Session lifecycle and garbage collection
│   ├── config.ts              # Env-backed configuration loading
│   ├── errors.ts              # Shared error helpers
│   ├── logger.ts              # Winston logger
│   ├── types.ts               # Shared TypeScript types
│   └── tools/
│       ├── debug.ts
│       ├── memory.ts
│       ├── analysis.ts
│       ├── security.ts
│       └── index.ts
├── plugin/
│   ├── x64dbg_mcp_bridge.py   # Python bridge running inside x64dbg
│   ├── x64dbg_bridge_sdk.py   # ctypes wrapper for x64bridge.dll
│   ├── loader/
│   │   ├── x64dbg_mcp_loader.c
│   │   ├── CMakeLists.txt
│   │   └── prebuilt/
│   ├── tests/
│   │   └── test_bridge.py
│   └── README.md
├── scripts/
│   ├── setup.mjs
│   ├── doctor.mjs
│   ├── install-plugin.mjs
│   ├── install-plugin.ps1
│   ├── postinstall.mjs
│   ├── prepack.mjs
│   ├── setup-x64dbg.mjs
│   ├── sync-plugin.mjs
│   ├── ci.mjs
│   └── manual/
├── test/
│   ├── basic.test.ts
│   └── e2e/
├── x64dbg/                    # Bundled x64dbg snapshot used in development/tests
├── package.json
├── .env.example
└── README.md
```

## License

MIT

## Community

- Contribution guide: see [CONTRIBUTING.md](CONTRIBUTING.md)
- Security policy: see [SECURITY.md](SECURITY.md)
- Code of conduct: see [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)
- Bug reports and feature requests: use the GitHub templates under `.github/ISSUE_TEMPLATE/`

For non-sensitive questions or usage issues, open a GitHub issue. For vulnerabilities, follow the private reporting process in `SECURITY.md` instead of opening a public issue.

TDQS

A3.8/5.0

Scored across 39 tools

Disambiguation4/5

Most tools have distinct, well-defined purposes (e.g., step_into vs step_over, disassemble vs read_memory). However, tools like analyze_function and analyze_suspicious_apis could be confused if descriptions are not read carefully, and execute_command overlaps with other tools' capabilities.

Naming Consistency5/5

All tool names use a consistent verb_noun pattern in snake_case (e.g., analyze_function, load_executable, continue_execution). No mixed conventions or vague verbs.

Tool Count4/5

39 tools is on the higher end but justified by the breadth of debugger functionality. The tool set covers execution control, memory inspection, analysis, and session management without being excessive.

Completeness5/5

The tool set provides comprehensive coverage for a debugger/analysis server: loading, stepping, breakpoints, memory, registers, modules, security analysis, session management. No obvious gaps for typical reverse engineering tasks.

Maintenance

ActivityInactive
ResponsivenessNo issues