Use Warden
Integration seams
Integrate Warden with MCP Runtime, Node isolated launchers, Orchestrator and Sandbox Policy.Maelys Executor is the mechanical layer shared by MCP Runtime and Maelys Orchestrator. Neither adapter puts authorization logic in this library.
trusted manifest/profile approved agent request
| |
v v
MCP Runtime adapter Orchestrator adapter
request + sealed plan request + sealed plan
| |
+------------------+ +-------------------------+
v v
Maelys Executor
POSIX | Bubblewrap | SeatbeltMCP Runtime
Both external providers and mcp-proxy upstreams must cross the same launcher
adapter. The adapter converts the runtime's complete process specification into
an opaque maelys_execution_request_t; it never lets a proxy's full argv bypass
execution. The adapter is the only component that includes both public APIs.
For an isolated provider protocol:
- use
MAELYS_EXEC_IO_ISOLATED_DUPLEX; - copy the runtime's closed environment exactly for the
"local"platform; - use inherited stderr so a pipe the runtime never drains cannot block a noisy provider;
- transfer only the protocol descriptor with
maelys_execution_take_fd(); - map the runtime's launcher
wait,stopandreleaseoperations to the corresponding Executor operations, with release remaining local-only; - build and seal the plan from trusted manifest/profile data before spawn.
Native, TypeScript and Python providers differ only in executable and argv. The fd layout and sandbox enforcement are applied by the host before the target program image starts.
Node isolated protocol launcher
The Node SDK exposes the same core contract through spawnIsolated(). Node
talks to maelys-warden over ordinary stdin/stdout pipes; the CLI copies those
opaque bytes to and from Executor's isolated fd 3 socket. No descriptor passing
or MAELYS_PRESERVE_FDS convention is involved.
The SDK creates separate private control, workspace and writable temp
locations. Workspace access remains governed by the selected policy. It passes
the temp location as the launcher's TMPDIR, requests an empty child
environment and keeps receipts outside the sandbox-writable root.
Callers own continuous drainage of both the returned protocol duplex stream and
stderr. wait() and stop() are idempotent; stop() relies on the CLI's
bounded graceful/forced Executor shutdown.
Maelys Orchestrator
The orchestrator adapter uses the same execution specification for Codex, Claude Code or another agent process. Captured stdio or duplex stdio exposes the agent endpoint, while the approved workspace, writable paths, environment and network mode become a sealed plan. A policy decision point may produce that plan, but policy evaluation remains outside this repository.
Executions and the MCP launcher retain their executor. Adapters transfer only
the descriptors they own. A host performs bounded shutdown when it owns the
lifecycle; maelys_execution_release() itself never signals or waits.
Published MCP contract
E3 is compiled against the published mcp-runtime v0.23.0 contract at the
exact tag commit recorded in adapter/MCP_RUNTIME_PIN. ABI 6 keeps the ABI 5
launcher function signatures and requires out-of-tree launchers to recompile
with .abi_version = 6. It also authorizes a confining profile to augment the
runtime's closed environment without replacing any base entry, and reserves
child descriptors from 4 upward for explicit profile-installed channels.
max_message_bytes is deliberately not consumed: the adapter transports bytes
and does not parse or buffer MCP frames.
The hook itself belongs to the distribution that builds maelys-mcp, because
that distribution owns the trusted profile registry. Its strong definition
creates an Executor, registers the permitted backends, then calls
maelys_mcp_executor_launcher_create() with its profile resolver. Linking that
object through mcp-runtime's MCP_HOST_LAUNCHER_OBJECTS replaces the weak POSIX
default for every process provider and proxied upstream. A failed hook or an
unknown profile must return an error; neither may fall back to an unconfined
launch.
The current adapter supports only the MCP environment platform token "local".
Non-local targets are refused explicitly until the OCI target contract defines
how their profile produces PATH; no value is guessed, dropped or translated.
The pure adapter can request an unconfined POSIX plan or a host-selected
confined plan without depending on a concrete backend. It deliberately rejects
EXTERNAL_CHANNEL plans: after removal of Executor's internal connector, only
a Egress-aware host owns enough state to create the authenticated connector,
retain its broker for the whole execution and stop it after the workload.
Environment injection is not a channel and is never used as a fallback. An MCP
distribution that needs mediated networking must compose the MCP launcher and
Executor-Egress adapter in its host integration; the pure adapter remains useful
for INHERIT and NONE plans.
Portable SandboxPlan compiler
maelys-sandbox-policy and Executor are joined by a separate optional adapter, not by
sharing an opaque type. See sandbox-policy-integration.md.
The former owns maelys_sandbox_policy_plan_t; Executor ABI 10 owns
maelys_executor_plan_t. This keeps MIR compilation independent of launch
mechanics and allows both libraries to be linked into the same registry host.