Usage Guide
August 1, 2026 ยท View on GitHub
managed-agents provides a local control plane for building, running, and
debugging managed agents. The usual workflow is:
- Create or import an agent.
- Attach skills, tools, MCP servers, files, memory stores, or credentials.
- Start a session in an environment.
- Inspect the transcript and debug event stream.
- Iterate on the agent definition and save new versions.
Workspace Layout
A workspace is a folder that contains runtime configuration, runtime state, and optional seed agent definitions and skill packages. Live metadata is stored in SQLite under the workspace state directory.
my-agents/
+-- agents/ # Optional seed agent definitions
| +-- assistant.yaml
+-- skills/ # Optional seed skill packages
| +-- code-review/
| +-- SKILL.md
+-- .managed-agents/
+-- config.yaml
+-- data.db # SQLite metadata store
+-- logs/
| +-- runtime.log
+-- files/ # Uploaded file bytes
+-- skills/ # Uploaded custom skill package assets
+-- snapshots/ # Session workspace snapshots
+-- sandbox/ # Local session workspaces
The workspace is portable. Commit examples, templates, config, and any seed
definitions you intentionally maintain. Keep .managed-agents/data.db,
.managed-agents/logs/, .managed-agents/files/, and sandbox state out of
source control unless you intentionally want to snapshot local runtime data.
Agent Definitions
Agents can be imported from YAML files in agents/ or created through the
Console/API. Once loaded, the runtime source of truth is SQLite.
name: assistant
description: Helps with development tasks.
model: gpt-4o
system: |
You are a helpful assistant. Answer clearly and use tools when needed.
mcp_servers: []
tools:
- type: agent_toolset_20260401
default_config:
enabled: true
permission_policy:
type: always_allow
skills:
- type: custom
skill_id: skill_code-review
metadata:
owner: platform
Agent ids are stable object identifiers. YAML seed agents use deterministic ids
when they are first imported, while agents created through the API or Console
receive server-generated agent_... ids. Use the returned id in API calls,
sessions, and SDK requests; treat name as a human-readable display field.
Dashboard Workflow
Start the runtime:
managed-agents start
Open:
http://127.0.0.1:3000/dashboard
The Dashboard includes:
- Workspace and local runtime status
- Agent templates and agent versions
- Session creation and session debug timelines
- Runtime Settings for the single workspace model vendor, loop engine, storage backends, context-memory backend, and default sandbox
- Environments
- Credential vaults and credentials
- Memory stores and memory entries
- File upload and file resources
- Skill upload and skill details
Runtime Settings
Open Settings > Models, Loop engine, Storage, Memory, or Sandbox to
edit the workspace runtime configuration. Settings V2 stores one versioned JSON
document in SQLite under the runtime data directory. Each Console page edits its
own section of that document: Models edits model, Loop engine edits
loop_engine, Storage edits storage, Memory edits memory, and
Sandbox edits sandbox. The Form and JSON tabs are two views of that current
section, and saving merges the section back into the versioned document.
The usual sequence is:
- Change the relevant field.
- Click
Save settings; the Dashboard validates the change before saving. - Optionally run
Check configurationfor a local capability check when you need diagnostics before or after saving. - Restart the runtime when the page shows
Restart required.
All first-release Settings V2 fields require a runtime restart before they
become effective. Until restart, API responses expose both saved_config and
effective_config; sessions continue using the effective revision.
The workspace has one active model vendor, one built-in loop engine, SQLite
metadata storage, local artifact storage, one context-memory backend, and one
default sandbox provider. Named Environments can still override the default
sandbox per session. Planned adapters such as S3, mem0, MemU, Harness, Codex,
and Claude remain unavailable until their runtime implementations exist; Docker,
Kubernetes, and remote sandbox providers appear as available only when the
current runtime can reach their transport. Remote sandbox maps to the
self-hosted worker queue: configure the worker API URL and key so external
workers can claim and complete queued work items; the Settings check calls the
remote /v1/x/health endpoint.
Sandbox Backends
A sandbox is where an agent's tool commands actually run. One sandbox is bound to one session for that session's lifetime.
Each backend declares what it can do, and the runtime reads those capabilities instead of assuming them. Requesting something a backend cannot provide is reported in the runtime log rather than silently dropped.
| Backend | Selected as | Isolated from runtime host | Host workspace | Resource limits | Transport |
|---|---|---|---|---|---|
| Local process | local | No | Yes | No | Child process |
| Docker | docker | Yes | No | Yes | docker CLI |
| Kubernetes | kubernetes | Yes | No | Yes | kubectl CLI |
| Self-hosted worker | remote in Settings, self_hosted in an Environment | Runs off-host | No | No | Work-item queue |
Consequences worth knowing before choosing one:
- Local is not a security boundary. File tools are confined to the session workspace and the child process environment is reduced to an allowlist, but a shell command still runs as the same OS user on the same machine as the runtime: it can read outside the workspace and reach the network. Use it for trusted local development, not for running untrusted agent output.
- Workspace snapshots need a host workspace. Only
localexposes one, so snapshots are unavailable on the other three. Enabling them anyway logs a warning naming the missing capability. - Resource limits are honored only by
dockerandkubernetes. Settingresourcesonlocalorremotelogs a warning instead of appearing to apply.
A backend is offered only when the runtime can reach its transport: no Docker
daemon means docker is not registered, and no reachable cluster means
kubernetes is not registered. An Environment naming a backend that is not
registered fails when the session provisions its sandbox, with an error listing
the backends that are registered. It does not fall back to local execution โ
quietly running unsandboxed after an isolated backend was requested would be a
worse outcome than a failed session.
Startup logs the registered backends:
Sandbox: local, docker, self_hosted
Kubernetes Sandboxes
Requires kubectl on PATH and a reachable cluster. Each session becomes one
Pod running sleep infinity; commands run through kubectl exec and files move
through kubectl cp.
Configure it under Settings > Sandbox, or per Environment:
{
"sandbox_provider": "kubernetes",
"image": "node:22-slim",
"kubernetes": {
"namespace": "agent-sandboxes",
"context": "staging",
"service_account": ""
}
}
- The image needs
/bin/sh,find, andtar(taris whatkubectl cpuses). The defaultnode:22-slimhas all three. namespacemust be a lowercase RFC 1123 label and defaults todefault.- Leaving
service_accountempty creates the Pod withautomountServiceAccountToken: false, so sandboxed commands cannot call the Kubernetes API. Only set it when an agent genuinely needs cluster access, and scope that account's RBAC accordingly. - Pods are labeled
app.kubernetes.io/managed-by=managed-agentsandmanaged-agents/session-id=<session id>, and are deleted when the session reaches a terminal state.
See Deployment Examples for the RBAC the runtime itself needs to create these Pods.
YAML model entries and legacy provider rows are bootstrap/import data for a new workspace. After Settings V2 is seeded, normal Dashboard edits do not rewrite source-controlled YAML files and legacy provider mutation endpoints are read-only compatibility failures.
Create An Agent
Use the Dashboard Create agent action, or add a seed YAML file in agents/ and
reload to import it into SQLite:
managed-agents reload
Create an agent through the API:
curl -X POST http://127.0.0.1:3000/v1/agents \
-H "Content-Type: application/json" \
-d '{
"name": "assistant",
"description": "Helps with development tasks.",
"model": "default",
"system": "You are a helpful assistant.",
"tools": [{ "type": "agent_toolset_20260401" }],
"skills": [],
"metadata": {}
}'
Start A Session
A session is a run of an agent inside an environment.
curl -X POST http://127.0.0.1:3000/v1/sessions \
-H "Content-Type: application/json" \
-d '{
"agent": "agent_assistant",
"environment_id": "env_default",
"title": "Local smoke test"
}'
The response contains a sesn_... id.
Send a user message:
curl -N -X POST http://127.0.0.1:3000/v1/sessions/SESSION_ID/messages \
-H "Content-Type: application/json" \
-d '{"content": "Hello", "stream": true}'
List events:
curl http://127.0.0.1:3000/v1/sessions/SESSION_ID/events
Resume a live event stream:
curl -N http://127.0.0.1:3000/v1/sessions/SESSION_ID/events/stream \
-H "Last-Event-ID: EVENT_ID"
Stop a session:
curl -X POST http://127.0.0.1:3000/v1/sessions/SESSION_ID/stop
Attach Files To A Session
Upload a file:
curl -X POST http://127.0.0.1:3000/v1/files \
-F "file=@notes.txt"
Create a session with the file mounted under /uploads/:
curl -X POST http://127.0.0.1:3000/v1/sessions \
-H "Content-Type: application/json" \
-d '{
"agent": "agent_assistant",
"environment_id": "env_default",
"resources": [
{
"type": "file",
"file_id": "file_abc123",
"mount_path": "/uploads/notes.txt"
}
]
}'
Attach A Memory Store
Create a memory store:
curl -X POST http://127.0.0.1:3000/v1/memory_stores \
-H "Content-Type: application/json" \
-d '{"name": "project-memory", "description": "Long-term project notes"}'
Add a memory:
curl -X POST http://127.0.0.1:3000/v1/memory_stores/MEMORY_STORE_ID/memories \
-H "Content-Type: application/json" \
-d '{"path": "/notes/overview", "content": "Use concise release notes."}'
Mount the store into a session:
{
"type": "memory_store",
"memory_store_id": "memstore_abc123",
"access": "read_write",
"instructions": "Use this store for durable project notes."
}
Use Credential Vaults
Credential vaults hold credentials that sessions can use without writing secrets into agent YAML files.
Create a vault:
curl -X POST http://127.0.0.1:3000/v1/credential-vaults \
-H "Content-Type: application/json" \
-d '{"name": "production-tools"}'
Add an environment variable credential:
curl -X POST http://127.0.0.1:3000/v1/credential-vaults/VAULT_ID/credentials \
-H "Content-Type: application/json" \
-d '{
"name": "github-token",
"auth_type": "environment_variable",
"variable_name": "GITHUB_TOKEN",
"value": "ghp_example",
"network": {
"type": "limited",
"allowed_hosts": ["api.github.com"]
},
"injection_locations": ["request_headers"]
}'
Attach one or more vaults when creating a session:
{
"vault_ids": ["vlt_abc123"]
}
TypeScript SDK
import { ManagedAgentsClient } from 'managed-agents/sdk';
const client = new ManagedAgentsClient({
baseUrl: 'http://127.0.0.1:3000',
});
const session = await client.sessions.create({
agent: 'agent_assistant',
environment_id: 'env_default',
});
for await (const event of client.sessions.chat(session.id, 'Hello')) {
if (event.type === 'agent.message_chunk') {
process.stdout.write(event.delta ?? '');
}
}
CLI Commands
managed-agents init
managed-agents start --host 127.0.0.1 --port 3000
managed-agents list
managed-agents reload
managed-agents chat agent_assistant --message "hello"
managed-agents template list
managed-agents template install <template-name-or-path>
managed-agents template create <name>
Operational Notes
- Keep credentials in vaults or environment variables, not in agent YAML files.
- Keep uploaded file resources below 10 MB per file.
- Keep skill uploads below 8 MB per package.
- Use
MANAGED_AGENTS_SECRET_KEYto provide a stable credential encryption key across runtime moves. - Create a managed API key in the Dashboard or set
MANAGED_AGENTS_API_KEYbefore exposing the runtime beyond a trusted local network.