CLI & SDK
openma ships two developer-facing packages:
open-managed-agents— a Node CLI for scripting against the API.@open-managed-agents/api-types— pure-TypeScript DTOs of the wire format. Zero workspace dependencies; safe to import from a CLI, a Worker, the Console, or your own integrations.
Both live in this repo (packages/cli, packages/api-types).
Install
Section titled “Install”npm i -g open-managed-agentspnpm add -g open-managed-agentsbun add -g open-managed-agentsConfigure
Section titled “Configure”The CLI reads two env vars:
export OMA_BASE_URL="https://app.openma.dev"export OMA_API_KEY="oma_..."For self-hosters, point OMA_BASE_URL at your own deployment.
Common commands
Section titled “Common commands”# List agentsoma agents list
# Create an agent from a JSON fileoma agents create -f ./my-agent.json
# Start a sessionoma sessions create --agent agent_abc123 \ --input "Summarize the openma docs."
# Tail a session's event stream (SSE under the hood)oma sessions tail sess_xyz
# Replay a session's full event logoma sessions logs sess_xyz
# Show your usageoma usageRun oma --help or oma <command> --help for the full surface.
SDK (api-types)
Section titled “SDK (api-types)”@open-managed-agents/api-types is a tiny package: just the TypeScript types for every request and response shape. No HTTP client, no runtime — bring your own fetch.
Install
Section titled “Install”npm i @open-managed-agents/api-typespnpm add @open-managed-agents/api-typesbun add @open-managed-agents/api-typesimport type { AgentConfig, CreateAgentRequest, CreateAgentResponse, SessionEvent, SessionMeta, ContentBlock,} from '@open-managed-agents/api-types';
const baseUrl = process.env.OMA_BASE_URL!;const apiKey = process.env.OMA_API_KEY!;
async function createAgent(req: CreateAgentRequest): Promise<CreateAgentResponse> { const res = await fetch(`${baseUrl}/v1/agents`, { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json', }, body: JSON.stringify(req), }); if (!res.ok) throw new Error(`HTTP ${res.status}`); return res.json();}Why no client library?
Section titled “Why no client library?”Because everything is HTTP and SSE — well-supported in every runtime (Node, Bun, Deno, browsers, Workers). Wrapping it would just hide what’s actually happening. The DTOs give you autocomplete and compile-time safety; the wire format is documented in REST API and Reference → API Endpoints.
If you want a typed wrapper, the CLI source (packages/cli/src/) is a small reference implementation you can lift.
Talking to the SSE stream
Section titled “Talking to the SSE stream”import type { SessionEvent } from '@open-managed-agents/api-types';
const res = await fetch(`${baseUrl}/v1/sessions/${sessionId}/events`, { headers: { 'Authorization': `Bearer ${apiKey}` },});
const reader = res.body!.getReader();const decoder = new TextDecoder();let buffer = '';
while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true });
let i; while ((i = buffer.indexOf('\n\n')) !== -1) { const chunk = buffer.slice(0, i); buffer = buffer.slice(i + 2);
const dataLine = chunk.split('\n').find(l => l.startsWith('data: ')); if (!dataLine) continue;
const event = JSON.parse(dataLine.slice(6)) as SessionEvent; handleEvent(event); }}For most use cases the CLI’s oma sessions tail does this for you.