Execution channels
An execution channel is a composition root around the same engine. The channel
owns transport parsing, trusted identity, and process lifecycle. Invokta keeps
domain validation, authorization, execution, and error normalization inside
engine.invoke.
Direct TypeScript
Section titled “Direct TypeScript”Use direct invocation from an application, a test, or another capability-owned workflow.
const result = await engine.invoke( "onboarding.create-welcome-message", { name: "Ada" }, { source: "direct", principal: { id: "user:42" }, },);The return type is inferred from the selected capability and its output schema.
Create a thin binary entry point:
import { runCli } from "@invokta/cli";
import { engine } from "./engine.js";
process.exitCode = await runCli(engine, { principal: { id: "local:developer" },});The composition root decides which local identity is trusted. The CLI does not accept actor, role, or login flags.
my-engine listmy-engine describe onboarding.create-welcome-messagemy-engine run onboarding.create-welcome-message --input '{"name":"Ada"}'printf '%s' '{"name":"Ada"}' | \ my-engine run onboarding.create-welcome-message --stdinStandard output contains only the requested JSON result. Diagnostics are written to standard error, which makes the binary safe to compose in shell pipelines.
MCP stdio
Section titled “MCP stdio”Use stdio when an MCP host starts and supervises the engine as a local process:
import { serveMcpStdio } from "@invokta/mcp";
import { engine } from "./engine.js";
await serveMcpStdio(engine, { principal: { id: "local:mcp-host" },});Start the compiled entry point directly with Node:
node dist/mcp-stdio.jsThe adapter maps each capability to one MCP tool and propagates the request’s cancellation signal. Standard output is reserved for protocol messages; send logs to standard error.
The MCP stdio consumer recipe shows the other side of this boundary: an independent harness starts the engine, discovers its tools, invokes one capability, and shuts the child process down cleanly.
MCP Streamable HTTP
Section titled “MCP Streamable HTTP”For a loopback development server, make the unauthenticated choice explicit:
import { serveMcpHttp } from "@invokta/mcp";
import { engine } from "./engine.js";
const server = await serveMcpHttp(engine, { host: "127.0.0.1", port: 3000, auth: { mode: "dangerously-disabled-for-development", },});
const { host, port } = server.address();process.stderr.write(`MCP endpoint: http://${host}:${port}/mcp\n`);Each accepted POST /mcp request gets a fresh MCP server, transport, and
principal. Sessions, resumption, and cross-request state are disabled.
Follow the HTTP authentication guide before exposing the endpoint beyond loopback. It covers bearer verification, protected-resource metadata, Host and Origin checks, trusted proxy behavior, and authentication-hook limits.
What stays consistent
Section titled “What stays consistent”| Concern | Owner |
|---|---|
| Transport parsing and process lifecycle | Adapter or composition root |
| Authentication | Trusted composition root or HTTP boundary |
| Input and output validation | engine.invoke |
| Capability authorization | engine.invoke |
| Domain execution | Capability run |
| Normalized errors and events | engine.invoke |
Use the @invokta/cli reference or
@invokta/mcp reference for boundary-specific options.