Install
$ agentstack add mcp-openma-ai-open-managed-agents ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ● Shell / process execution Used
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Open Managed Agents
Open-source alternative to Claude Managed Agents — and a foundation for open-source, self-hosted Claude Tag-style agents.
🌐 openma.dev · 📖 docs.openma.dev · 💬 github.com/openma-ai/open-managed-agents
Write a harness. Deploy. The platform runs it — with sessions, sandboxes, tools, memory, vaults, Slack/GitHub/Linear integrations, and crash recovery out of the box. Drop-in compatible with the Claude Managed Agents API; runs on Cloudflare Workers + Durable Objects, or docker compose up on your own box.
Use Open Managed Agents when you want:
- A self-hosted Claude Managed Agents API implementation.
- An open-source, self-hosted Claude Tag-style workflow with BYOK model credentials.
- MCP, private tools, encrypted vaults, and durable sessions under your own deployment boundary.
Compare: Claude Tag alternative · Open-source Claude Tag · Self-hosted Claude Tag
Two ways to run OMA
The same harness, business logic, and event-log model run on both. Pick the one that matches your hosting story:
| | Self-host (Node) | Cloudflare | |---|---|---| | Where it lives | Your VPS / Mac / Docker host / fly.io / your k8s | Cloudflare Workers + DO + Containers | | Storage | SQLite or Postgres + local FS | D1 + KV + R2 | | Sandbox | LocalSubprocess / LiteBox / Daytona / E2B / BoxRun | Cloudflare Sandbox (Containers) | | Time to running | docker compose up (~2 min) | wrangler deploy (~10 min once configured) | | Best for | OSS users, on-prem, no CF account, data-resident deploys | Edge scale, no host management, already on CF |
Same SDK. Same /v1/agents / /v1/sessions API. Same Console UI. Same crash-recovery semantics. Switch between them by changing env vars, not code.
Quick start: self-host (Docker)
git clone https://github.com/openma-ai/open-managed-agents.git
cd open-managed-agents
cp .env.example .env
# Two secrets are required before first boot — both generated locally:
# BETTER_AUTH_SECRET — signs Console sessions
# PLATFORM_ROOT_SECRET — encrypts credentials, model-card API keys, integration tokens at rest
# (lose it and every encrypted row is unreadable — back it up)
$EDITOR .env
# BETTER_AUTH_SECRET=$(openssl rand -hex 32)
# PLATFORM_ROOT_SECRET=$(openssl rand -base64 32)
#
# Optional: ANTHROPIC_API_KEY lets the first agent run without a Model Card.
# In production, add a Model Card per tenant from the Console instead.
# SQLite + LocalSubprocess sandbox (default — fastest path)
docker compose up -d
# Or Postgres backend
# docker compose -f docker-compose.postgres.yml up -d
curl localhost:8787/health
# → {"status":"ok","backends":{"db":"sqlite ..."}, ...}
open http://localhost:8787 # Console UI on the same port
Smoke test the harness end-to-end:
AID=$(curl -s -X POST localhost:8787/v1/agents -H 'content-type: application/json' \
-d '{"name":"hello","model":"claude-sonnet-4-6","tools":[{"type":"agent_toolset_20260401"}]}' | jq -r .id)
SID=$(curl -s -X POST localhost:8787/v1/sessions -H 'content-type: application/json' \
-d "{\"agent\":\"$AID\"}" | jq -r .id)
curl -s -X POST localhost:8787/v1/sessions/$SID/events -H 'content-type: application/json' \
-d '{"events":[{"type":"user.message","content":[{"type":"text","text":"Run: uname -a"}]}]}'
Full self-host guide (sandbox modes, Postgres, BoxRun, vault sidecar, Console UI, operator gotchas): docs.openma.dev/self-host/overview
Quick start: Cloudflare deploy
Requires Workers Paid plan (for Durable Objects + Containers).
git clone https://github.com/openma-ai/open-managed-agents.git
cd open-managed-agents
pnpm install
# Local dev (no CF account needed) — wrangler dev with simulators
cp .dev.vars.example .dev.vars && $EDITOR .dev.vars
# Same two-secret setup as Docker — PLATFORM_ROOT_SECRET is required to start
pnpm dev
# API → http://localhost:8787
# Console → http://localhost:5173
# Deploy
npx wrangler login
npx wrangler kv namespace create CONFIG_KV # paste id into wrangler.jsonc
# Required secrets (paste each when prompted)
npx wrangler secret put BETTER_AUTH_SECRET # openssl rand -hex 32
npx wrangler secret put PLATFORM_ROOT_SECRET # openssl rand -base64 32 — back this up
npx wrangler secret put API_KEY # initial bootstrap key for the REST API
# Optional — only if you want a tenant-less default LLM (otherwise add a Model Card in the Console)
# npx wrangler secret put ANTHROPIC_API_KEY
npm run deploy
# → https://openma.dev (or https://managed-agents..workers.dev for a personal deploy)
What gets deployed:
| Component | What it does | |---|---| | Main Worker | API routes — agents, sessions, environments, vaults, memory, files | | Agent Worker | SessionDO + harness + sandbox per environment | | KV Namespace | Config storage for agents, environments, credentials | | R2 Bucket | Workspace file persistence across container restarts |
Create your first agent
The smoke test above works against any deployment. For the Console-driven flow (Model Cards, vaults, integrations) see docs.openma.dev/quickstart. The minimal API equivalent:
BASE=http://localhost:8787 # or your deployed URL
KEY=dev-test-key # whatever you set as API_KEY
AGENT=$(curl -s $BASE/v1/agents \
-H "x-api-key: $KEY" -H "content-type: application/json" \
-d '{
"name": "Coder",
"model": "claude-sonnet-4-6",
"system": "You are a helpful coding assistant.",
"tools": [{ "type": "agent_toolset_20260401" }]
}' | jq -r .id)
SESSION=$(curl -s $BASE/v1/sessions \
-H "x-api-key: $KEY" -H "content-type: application/json" \
-d "{\"agent\":\"$AGENT\"}" | jq -r .id)
# Send a turn AND stream the reply token-by-token in one shot
curl -N -X POST $BASE/v1/sessions/$SESSION/messages \
-H "x-api-key: $KEY" -H "content-type: application/json" \
-d '{"content":"Write a Python script that fetches HN top stories"}'
For long-lived sessions use GET /v1/sessions/$SESSION/events/stream — replays history on connect, never closes.
Architecture
A meta-harness is not an agent — it's the platform that runs agents. It defines stable interfaces for everything an agent needs, and stays out of the way of the agent loop:
┌─────────────────────────────────────────────────────────┐
│ Harness (the brain — your code) │
│ - Reads events, builds context, calls the model │
│ - Decides HOW: caching, compaction, tool delivery │
│ - Stateless: crash → rebuild from event log → resume │
├─────────────────────────────────────────────────────────┤
│ Meta-Harness (the platform — SessionDO) │
│ - Prepares WHAT is available: tools, skills, history │
│ - Manages lifecycle: sandbox, events, WebSocket │
│ - Crash recovery, credential isolation, usage tracking │
├─────────────────────────────────────────────────────────┤
│ Infrastructure (Cloudflare or Node self-host) │
│ - Event log: Durable-Object SQLite (CF) or SQLite/Pg │
│ - Sandbox: CF Containers / subprocess / LiteBox / E2B │
│ - Storage: KV + R2 (CF) or local FS (self-host) │
└─────────────────────────────────────────────────────────┘
The platform prepares what is available. The harness decides how to deliver it to the model.
| Platform manages | Harness decides | |---|---| | Event log persistence (SQLite) | Context engineering (filtering, ordering) | | Sandbox lifecycle (containers) | Caching strategy (cache breakpoints) | | Tool registration (built-in + MCP) | Compaction strategy (when to compress) | | WebSocket broadcast | Retry strategy (backoff, transient detection) | | Crash recovery | Stop conditions (max steps, completion signals) | | Credential isolation (vaults) | System prompt construction | | Memory (vector search) | Tool delivery (all at once vs. progressive) |
Write a Harness
The default harness works out of the box. When you need custom behavior — different caching, compaction, context engineering — write your own:
// my-harness.ts
import { defineHarness, generateText, stepCountIs } from "@open-managed-agents/sdk";
export default defineHarness({
name: "research",
async run(ctx) {
let messages = ctx.runtime.history.getMessages();
// Your context engineering
messages = keepOnly(messages, ["web_search", "web_fetch"]);
// Your caching strategy
markLastN(messages, 3, { cacheControl: "ephemeral" });
// Your loop — tools, sandbox, broadcast are platform-provided
const result = await generateText({
model: ctx.model,
system: ctx.systemPrompt,
messages,
tools: ctx.tools,
stopWhen: stepCountIs(50),
onStepFinish: async ({ text }) => {
if (text) ctx.runtime.broadcast({
type: "agent.message",
content: [{ type: "text", text }],
});
},
});
await ctx.runtime.reportUsage?.(result.usage.inputTokens, result.usage.outputTokens);
},
});
Deploy it:
oma deploy --harness my-harness.ts --agent agent_abc123
The harness is bundled into the agent worker at build time. Your code runs in the same isolate as SessionDO — direct access to the event log, sandbox, and WebSocket broadcast. No RPC, no serialization boundary.
API
Compatible with the Claude Managed Agents API. Same endpoints, same event types, works with existing SDKs.
Agents — Create and manage agent configurations
POST /v1/agents # Create agent
GET /v1/agents # List agents
GET /v1/agents/:id # Get agent
PUT /v1/agents/:id # Update agent
DELETE /v1/agents/:id # Delete agent
POST /v1/agents/:id/archive # Archive agent
GET /v1/agents/:id/versions # Version history
GET /v1/agents/:id/versions/:version # Get specific version
Environments — Sandbox execution environments
POST /v1/environments # Create environment
GET /v1/environments # List environments
GET /v1/environments/:id # Get environment
PUT /v1/environments/:id # Update environment
DELETE /v1/environments/:id # Delete environment
Sessions — Run agent conversations
POST /v1/sessions # Create session
GET /v1/sessions # List sessions
GET /v1/sessions/:id # Get session
POST /v1/sessions/:id # Update session
DELETE /v1/sessions/:id # Delete session
POST /v1/sessions/:id/archive # Archive session
POST /v1/sessions/:id/events # Send events (user messages)
GET /v1/sessions/:id/events # Get events (JSON or SSE)
GET /v1/sessions/:id/events/stream # SSE stream
POST /v1/sessions/:id/resources # Attach resource
GET /v1/sessions/:id/resources # List resources
DELETE /v1/sessions/:id/resources/:resId # Remove resource
Vaults — Secure credential storage
POST /v1/vaults # Create vault
POST /v1/vaults/:id/credentials # Add credential
GET /v1/vaults/:id/credentials # List (secrets stripped)
Memory Stores — persistent storage; Claude Managed Agents Memory contract
When attached to a session, each store is mounted into the sandbox at /mnt/memory//. The agent reads and writes it with the standard file tools (bash/read/write/edit/glob/grep) — there are no bespoke memory_* tools.
R2 holds the bytes-of-truth (key /); D1 holds the index + audit, kept eventually consistent via R2 Event Notifications → Cloudflare Queue → Consumer.
POST /v1/memory_stores # Create store
GET /v1/memory_stores # List stores
GET /v1/memory_stores/:id # Retrieve store
POST /v1/memory_stores/:id/archive # Archive (one-way)
DELETE /v1/memory_stores/:id # Delete store + memories + versions
POST /v1/memory_stores/:id/memories # Create/upsert memory {path, content, precondition?}
GET /v1/memory_stores/:id/memories?path_prefix=&depth=N # List memories (metadata)
GET /v1/memory_stores/:id/memories/:mid # Retrieve memory (with content)
POST /v1/memory_stores/:id/memories/:mid # Update memory {path?, content?, precondition?}
DELETE /v1/memory_stores/:id/memories/:mid # Delete memory
GET /v1/memory_stores/:id/memory_versions?memory_id= # Audit history (newest first)
GET /v1/memory_stores/:id/memory_versions/:ver_id # Single version (with snapshot content)
POST /v1/memory_stores/:id/memory_versions/:ver_id/redact # Redact prior version (refuses live head)
CAS via precondition: { type: "content_sha256", content_sha256 }. 100KB cap per memory. 30-day version retention with the most-recent version per memory always preserved. Rollback = retrieve a version and write its content as a new memory revision (no special endpoint).
CLI:
oma memory stores create "User Preferences"
oma memory write /preferences/formatting.md --content "Always use tabs."
oma memory ls --prefix /preferences/
oma memory versions --memory-id
Files & Skills
POST /v1/files # Upload file
GET /v1/files/:id/content # Download file
POST /v1/skills # Create skill
GET /v1/skills # List skills
Built-in Tools
The agent_toolset_20260401 provides:
| Tool | Description | |---|---| | bash | Execute commands in the sandbox | | read | Read files from sandbox filesystem | | write | Write/create files (auto-creates directories) | | edit | Surgical string replacement in files | | glob | Find files matching a pattern | | grep | Search file contents with regex | | web_fetch | URL → markdown via Workers AI; auto-summarized when agent.aux_model is set, raw saved to /workspace/.web/ | | web_search | Web search via Tavily API (requires TAVILY_API_KEY) | | schedule / cancel_schedule / list_schedules | Cron-style self-wakeup for long-running agents | | browser (opt-in) | Headless browser session — navigate, click, screenshot. Opt-in via tools: [{ name: "browser", enabled: true }] so the default-tool list nudges agents toward cheaper web_fetch |
Derived tools are auto-generated based on session config:
| Tool | Source | |---|---| | call_agent_* | Callable Agents (multi-agent delegation) | | mcp____ | MCP Servers (double underscore is the actual separator) |
(Memory Stores do not add bespoke tools — agents access them as filesystem mounts at /mnt/memory// via the standard file tools above.)
MCP servers
OMA registers any Model Context Protocol server attached to an agent. Each upstream tool surfaces to the model as mcp____ (double underscore — copy the name exactly). Up to 20 servers per agent.
| Transport | When to use | How | |---|---|---| | HTTP / SSE | Hosted MCP servers (Linear, GitHub Copilot, Notion, …) | {"type":"url","url":"https://mcp.linear.app/mcp"} | | stdio | npm / PyP
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: openma-ai
- Source: openma-ai/open-managed-agents
- License: Apache-2.0
- Homepage: https://openma.dev
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.