Metasploit Deep Dive Part 11: RPC and msgrpc Automation
Everything in this series so far has assumed a human at msfconsole. That assumption stops being true the moment any external code, a script, a CI pipeline, or an LLM agent, needs to drive the framework. msfrpcd is the layer that makes that possible, and it’s worth understanding directly, since both AI Part 7’s community MetasploitMCP integration and this series’ own Part 12 sit on top of it rather than replacing it.
msfrpcd itself
msfrpcd is a real, thin script in the framework root, read directly for this post. Its job is straightforward: parse a handful of flags (-a bind address, -p port, default 55553, -U/-P credentials, -S to disable SSL, -f to run in the foreground, -j to switch to JSON-RPC instead of the legacy MessagePack protocol), spin up a real Msf::Simple::Framework instance, and load either the msgrpc plugin (legacy MessagePack RPC) or start a JSON-RPC web service via a Thin-backed Rack app, depending on which mode was requested.
A detail worth calling out directly from the source: msfrpcd reads MSF_RPC_USER and MSF_RPC_PASS environment variables as a fallback for credentials, explicitly commented in the source as existing “to avoid passing secrets on the command line,” and explicitly attributed to msfmcpd’s auto-start behavior. That’s Part 12’s MCP server talking to this script before Part 12 has even been written; the framework’s own RPC daemon was updated specifically to support being spawned automatically by the new MCP layer without leaking a password into ps aux output.
Two protocols, two eras
MessagePack RPC (the default, port 55553, SSL on by default) is the older interface, a binary-efficient serialization format with client libraries in most languages. JSON-RPC (-j flag) is the newer, human-readable alternative, served over an actual HTTP web service (msf-json-rpc.ru, a real Rackup config in the repo root) rather than a raw socket. The real source shows both a v1_0 and a v2_0 directory under lib/msf/core/rpc/json/, with v1 holding the original command dispatch logic and v2 apparently still under active development in this framework version. Anyone automating against Metasploit today has a real choice to make between the compact, longer-established MessagePack interface and the more debuggable, HTTP-native JSON-RPC one, and that choice shows up again directly in Part 12: msfmcpd supports both as backing transports for its own MCP tools.
What the RPC surface actually exposes
lib/msf/core/rpc/v10/ holds the real modules behind the MessagePack RPC surface: rpc_module (search, run, and inspect modules, the same module system covered in Part 2), rpc_job (background job management for long-running scans and handlers), rpc_session (list, read, and write to active sessions, the same session concept Part 2’s post-mixin discussion introduced), rpc_console (drive a virtual msfconsole instance remotely), rpc_db (workspaces, hosts, services, vulnerabilities, creds, loot, covered in full in Part 13), and rpc_auth (token issuance and permission scoping for RPC clients). Nothing here is a separate reimplementation of framework functionality for remote use; every one of these RPC methods is a thin wrapper calling straight into the same Msf::Simple::Framework instance and the same module classes this entire series has been reading source for.
Virtual consoles: RPC without giving up msfconsole’s UX
rpc_console.rb deserves a specific mention, because it solves a real problem cleanly: a lot of Metasploit usage, interactive, exploratory, one command informing the next, doesn’t map naturally onto discrete RPC calls the way msf_module_execute does. A virtual console, created via the RPC surface, gives a remote client something that behaves like an actual msfconsole session, commands typed in, output streamed back, state preserved between calls, but reachable over the network rather than requiring a local terminal. This is the same interaction model a human would get sitting at the console directly, just proxied.
Ruby and Python clients
lib/msf/core/rpc/v10/client.rb is the framework’s own Ruby client for its RPC surface, useful for anything already living inside the Ruby ecosystem. Outside of Ruby, the practical path is a MessagePack client library (available for Python, and most other mainstream languages) talking directly to port 55553, which is exactly the approach AI Part 7’s MetasploitMCP integration took: a Python process connecting to msfrpcd via the msgpack RPC API and re-exposing the results as MCP tools, no Ruby involved at all on the client side.
Why this layer matters more now than it used to
msfrpcd isn’t new; RPC access to the framework predates this series by years. What’s changed is what’s built on top of it. Part 12 covers msfmcpd, released with Metasploit 6.5 in the same month this series is being written, and it is not a new competing interface to the framework, it’s an MCP-shaped wrapper around this exact RPC layer, with an auto-start relationship to msfrpcd visible directly in the environment variable handling this post just read from source. Understanding msfrpcd first is what makes Part 12 legible: the MCP server doesn’t reimplement module execution, session handling, or the datastore. It calls this.