Skip to content
Guide Reference Download app

See it in action

This page shows the Claxedo package family as one composable app stack: run terminal coding agents, expose them to users or teams, and keep the product surface stable while swapping harness, workspace, deployment, and extension backends underneath.

PieceResponsibility
Product UIWorkspace/session/process/file/browser experience.
Product control planeAuth, org policy, credentials, workspace routing, extension policy, audit, team access.
Workspace RuntimePer-workspace execution host.
Agent ExtensionsPackage discovery, desired/lock state, policy, materialization, runtime replay.
Agent SDK RuntimeRuntime facade, harness factories, stores, turns, events, capability checks.
Agent Event RuntimeCanonical event model and projections.
Workspace RelayRemote access to cloud or user-hosted runtime hosts.
Claxedo MCPTool layer for MCP clients to orchestrate runtime/server APIs.
  1. Install the published packages

    Terminal window
    npm install @claxedo/workspace-runtime @claxedo/agent-sdk-runtime @hono/node-server

    @hono/node-server serves the runtime’s Hono app on a Node socket — the quickstart imports it directly.

  2. Start and configure a Workspace Host

    Save this as host.ts next to the project directory the agent should work on. It boots the host, then applies the harness, model, auth, MCP config, and Agent Extension desired state in code via runtime.host.apply():

    import { createWorkspaceRuntimeApp, loopbackWorkspaceRuntimeExposure } from "@claxedo/workspace-runtime"
    import { serve } from "@hono/node-server"
    const runtime = createWorkspaceRuntimeApp({
    exposure: loopbackWorkspaceRuntimeExposure(),
    })
    const server = serve({ fetch: runtime.app.fetch, port: 4096, hostname: "127.0.0.1" })
    runtime.injectWebSocket(server)
    await runtime.host.apply({
    version: 2,
    harnesses: [{ id: "codex", access: "native" }],
    model: "default",
    auth: {},
    mcp: {},
    agent_extensions: { version: 1, installs: [] },
    workspaceHarnessEnabled: true,
    })
    console.log("workspace-runtime ready on http://127.0.0.1:4096")
  3. Run it and verify

    Terminal window
    npx tsx host.ts

    Then, in a second terminal, hit the health route:

    Terminal window
    curl http://127.0.0.1:4096/api/wr/health
    {"ok":true,"status":"ready","service":"workspace-runtime","routeAuthBoundary":"loopback-only","serviceExposure":{"source":"loopback","access":"private"},"exposure":{"kind":"loopback"}}
  4. Create a session and send a prompt

    Your UI calls one session surface. The host starts a turn through the AgentRuntime facade and streams normalized events back. Run these from any HTTP client or a second script (e.g. npx tsx session.ts):

    const session = await fetch("http://127.0.0.1:4096/session", {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ title: "Fix the failing tests" }),
    }).then((res) => res.json())
    await fetch(`http://127.0.0.1:4096/session/${session.id}/message`, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({
    parts: [{ type: "text", text: "Find and fix the failing tests." }],
    }),
    })
  5. Use the same host for processes, files, and events

    await fetch("http://127.0.0.1:4096/api/wr/process/start-all", { method: "POST" })
    const files = await fetch("http://127.0.0.1:4096/file/all").then((res) => res.json())
    const events = new EventSource("http://127.0.0.1:4096/global/event")
    events.onmessage = (event) => console.log(JSON.parse(event.data))

Your UI does not need a separate streaming implementation for Claude ACP, Codex ACP, Cursor ACP, Claude SDK, Codex app-server, and OpenCode. When the harness config changes, the runtime disposes the old adapter and creates the matching one.

When the runtime runs in a cloud VM or on a user’s machine behind a tunnel, attach it to Relay with env-driven options:

import { startServer } from "@claxedo/workspace-runtime"
import { workspaceRelayRuntimeOptionsFromEnv } from "@claxedo/workspace-runtime/relay"
const port = Number(process.env.WORKSPACE_RUNTIME_PORT ?? 3002)
startServer(port, await workspaceRelayRuntimeOptionsFromEnv(process.env, port))

See @claxedo/workspace-runtime for the full relay-attachment env contract.