关于 IDA Pro MCP 插件自动启动
问题
IDA Pro 的 MCP 插件(ida-pro-mcp)默认设计是:每次打开 IDA 加载文件后,需要手动按 Ctrl+Alt+M(或 Edit → Plugins → MCP)才能启动 HTTP 服务。
对于频繁用 MCP 做分析的场景,这个设计非常烦人——因为 IDA 的命令行模式,只能打开指定的文件,但启动插件需要手动运行,每切一次文件就要重新点一次,对于 AI 自动化分析程序不友好,无法做到真正的全自动。
IDA 插件生命周期
IDA 用三个固定回调管理插件的生命周期:
1 2 3 4 5 6 7 8
| IDA 内核调用 │ ┌────────────────┼────────────────┐ ▼ ▼ ▼ init() run(arg) term() "插件被加载时" "用户触发菜单/快捷键" "IDA 关闭时" 返回 PLUGIN_KEEP 释放资源/线程 表示插件常驻内存
|
每个 IDA 插件必须实现一个 plugin_t 子类,IDA 内核在三个时机自动调用对应方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class MCP(idaapi.plugin_t): flags = idaapi.PLUGIN_KEEP wanted_hotkey = "Ctrl-Alt-M" wanted_name = "MCP"
def init(self): """IDA 启动 或 加载文件时,内核自动调用。 返回 PLUGIN_KEEP 表示加载成功并常驻。""" ...
def run(self, arg): """用户点击 Edit → Plugins → MCP 或按 Ctrl+Alt+M 时调用。""" ...
def term(self): """IDA 关闭时调用,做清理工作。""" ...
def PLUGIN_ENTRY(): return MCP()
|
调用链路:
1 2 3 4 5 6 7 8 9 10 11 12 13
| IDA 启动 / 打开文件 → 扫描 plugins/ 目录 → 调用 PLUGIN_ENTRY() 获取 MCP 实例 → 调用 plugin.init() → 插件就绪,等待用户触发
用户按 Ctrl+Alt+M → 调用 plugin.run(arg=0) → MCP HTTP 服务启动,监听 127.0.0.1:13337
IDA 关闭 → 调用 plugin.term() → HTTP 服务停止,线程回收
|
原实现的问题
原插件把 HTTP 服务的创建和启动拆开了:
1 2 3 4 5 6 7
| def init(self): self.server = Server() print("Plugin loaded, use Ctrl+Alt+M to start") return idaapi.PLUGIN_KEEP
def run(self, arg): self.server.start()
|
Server() 是一个简单的 http.server 包装,在独立线程中运行。init() 里只 new 了对象但没有调用 start(),所以端口 13337 上什么都没有。
设计者的意图是让用户按需启动——不用 MCP 的时候不开端口,减少攻击面。但在实际分析工作中,每次都要手动点一次,非常打断流程。
一行代码搞定
把 start() 从 run() 搬到 init():
1 2 3 4 5
| def init(self): self.server = Server() self.server.start() print("Plugin loaded, server auto-started on http://127.0.0.1:13337") return idaapi.PLUGIN_KEEP
|
run() 仍然保留(Ctrl+Alt+M 依然可用),不过 self.server.start() 内部做了幂等保护,重复调用不会起第二个线程。
插件安装位置
--install 命令会自动把插件拷贝到 IDA 的插件目录:
1
| C:\Users\<用户名>\AppData\Roaming\Hex-Rays\IDA Pro\plugins\mcp-plugin.py
|
IDA 启动时会自动扫描这个目录,加载所有 .py 文件并调用其 PLUGIN_ENTRY()。
安全考虑
MCP 插件监听 127.0.0.1:13337,只接受本机连接。如果担心安全问题,也可以在 Server 初始化时做额外加固:
1 2 3 4
| class Server: def __init__(self, host="127.0.0.1", port=13337): self.host = host self.port = port
|
效果如图

📄 许可证
本文采用 Creative Commons Attribution 4.0 International (CC BY 4.0) 许可证。
这意味着你可以自由地:
- 分享 — 以任何媒介或格式复制及分发本材料
- 改编 — 重混、转换和基于本材料创作,适用于任何目的,包括商业用途
在以下条件下:
- 署名 — 你必须给出适当的署名,提供指向本许可证的链接,同时标明是否作出了修改