Skip to main content
MobKit’s module system manages the lifecycle, routing, and communication for operational subsystems. This guide covers how module calls are routed, how MCP boundaries work, and how the supervisor manages process health.

Module call routing

When the runtime needs to invoke a module — for a delivery send, schedule evaluation, or gating decision — it routes the call through route_module_call:
The routing layer:
  1. Looks up the module by ID in the loaded modules table
  2. Checks if the module uses MCP (core modules) or the subprocess JSON-line protocol
  3. 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:
Non-MCP modules receive calls through the subprocess JSON-line protocol instead.

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 as ModuleHealthTransition 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, use run_module_boundary_once:
This spawns the module, sends a single request, collects the response, and terminates the process.

See also

  • Modules — module configuration and discovery
  • Events — health transition events
  • RPC API — module-level RPC methods