Module call routing
When the runtime needs to invoke a module — for a delivery send, schedule evaluation, or gating decision — it routes the call throughroute_module_call:
- Looks up the module by ID in the loaded modules table
- Checks if the module uses MCP (core modules) or the subprocess JSON-line protocol
- Dispatches the call through the appropriate boundary
MCP boundary
Core modules (router, delivery, scheduling, gating, memory) communicate over MCP tool calls. The MCP boundary:- Serializes the tool name and arguments to JSON
- Sends the request to the module’s MCP server
- Parses the response and extracts the result payload
- Applies a timeout (
CORE_MODULE_MCP_TIMEOUT) to prevent hung modules
MCP requirement checking
Before dispatching, the boundary verifies the module supports MCP:Subprocess protocol
Non-MCP modules communicate over a JSON-line protocol on stdout/stderr:1
Spawn
The supervisor spawns the module process with the configured command and arguments.
2
Capabilities handshake
The first line of stdout must be a JSON capabilities declaration:The runtime validates the contract version matches
MOBKIT_CONTRACT_VERSION ("0.4.0").3
Request/Response
Subsequent communication uses JSON-RPC over the JSON-line protocol. Each line is a complete JSON object.
RPC routing
Subprocess modules receive JSON-RPC requests routed by method name:Supervisor
The supervisor manages module process lifecycle:Health tracking
Each module transitions through health states:Health transitions
Health transitions are recorded asModuleHealthTransition events and emitted into the unified event stream:
Restart behavior
Module boundary errors
The boundary layer produces typed errors:Running a module once
For testing or one-off execution, userun_module_boundary_once:
