Skip to main content
Mirrored from Meerkat Meta main at 26f5ae9da1fd on 2026-11-03; Meta version 0.9.9 at that commit. Meta modules are subprocesses declared in MetaConfig. The runtime resolves each discovered module, selects its process boundary, records startup health, and exposes module operations through UnifiedRuntime.

Route a module call

Use the host-facing UnifiedRuntime::route_module_call method. A request names the configured module, the method or MCP tool, and its JSON parameters:
The routing layer:
  1. Verifies that module_id is loaded
  2. Resolves the matching ModuleConfig and optional PreSpawnData
  3. Selects the MCP boundary when the pre-spawn environment contains META_MODULE_BOUNDARY=mcp
  4. Returns ModuleRouteResponse { module_id, method, payload }

MCP boundary

Mark a module as MCP through its pre-spawn environment:
For an MCP module, a routed call connects to the configured stdio server, lists its tools, invokes request.method with request.params, and closes the connection. The caller-provided timeout bounds connect, list, call, and close operations. The core module IDs router, delivery, and memory require MCP. Routing one of those IDs without the MCP marker fails with ModuleRouteError::ModuleRuntime(RuntimeBoundaryError::Mcp(McpBoundaryError::McpRequired { .. })). There is no event-line fallback for those core flows.

Event-line boundary

A module without the MCP marker uses the event-line boundary. For a routed call, the process must write a JSON event as its first stdout line and then terminate. For example:
The runtime normalizes that line into EventEnvelope<UnifiedEvent>. On this boundary, route_module_call launches the module and returns the first normalized module event’s payload field as ModuleRouteResponse.payload after the subprocess exits. It does not include the event envelope metadata or the normalized event’s module and event_type fields in that payload. It also does not write request.method or request.params to the module’s stdin. Use MCP when the subprocess needs a request/response tool-call contract.
Event-line route_module_call and run_module_boundary_once are one-shot execution paths. Their timeout bounds first-line arrival, not the subsequent wait for child exit. A subprocess that emits a readiness line and stays alive can leave the call waiting indefinitely. This differs from startup supervision, which can retain the final healthy child. Prefer MCP for request/response servers; each MCP routed call still connects and closes its own connection rather than reusing the startup connection.
For a discovered one-shot module that emits one event and exits, use the public configuration-aware helper:
The helper verifies that the module is both configured and discovered, applies its matching PreSpawnData, executes it once, and returns the normalized event.

Startup health

The module supervisor records startup transitions. Read them through the unified runtime:
ModuleHealthTransition has four fields: ModuleHealthState has exactly these variants:

Restart policies

For event-line modules, restart behavior is bounded by RuntimeOptions: MCP startup probes the configured tool server once. It records Starting -> Healthy on success or Starting -> Failed -> Stopped on failure; the event-line restart budgets are not applied to that probe.

Boundary errors

The public routing path preserves the boundary that failed:

See also

  • Modules - module configuration and discovery
  • Events - unified event envelopes
  • RPC API - module-level RPC methods