# Managed Agents — Onboarding Flow > **Invoked via `/claude-api managed-agents-onboard`?** You're in the right place. Run the interview below — don't summarize it back to the user, ask the questions. Use this when a user wants to set up a Managed Agent from scratch. Three steps: **branch on know-vs-explore → configure the template → set up the session**. End by emitting working code. > Read `shared/managed-agents-core.md` alongside this — it has full detail for each knob. This doc is the interview script, not the reference. --- Claude Managed Agents is a hosted agent: Anthropic runs the agent loop on its orchestration layer and provisions a sandboxed container per session where the agent's tools execute. You supply the agent config and the environment config; the harness — event stream, sandbox orchestration, prompt caching, context compaction, and extended thinking — is handled for you. **What you supply:** - **An agent config** — tools, skills, model, system prompt. Reusable and versioned. - **An environment config** — the sandbox your agent's tools execute in (networking, packages). Reusable across agents. Each run of the agent is a **session**. --- ## 1. Know or explore? Ask the user: > Do you already know the agent you want to build, or would you like to explore some common patterns first? ### Explore path — show the patterns Four shapes, same runtime code path (`sessions.create()` → `sessions.events.send()` → stream). Only the trigger and sink differ. | Pattern | Trigger | Example | |---|---|---| | Event-triggered | Webhook | GitHub PR push → CMA (GitHub tool) → Slack | # <------ MC maybe delete? | Scheduled | Cron | Daily brief: browser + GitHub + Jira → CMA → Slack | # <------ MC maybe delete? | Fire-and-forget PR | Human | Slack slash-command → CMA (GitHub tool) → PR passing CI | | Research + dashboard | Human | Topic → CMA (web search + `frontend-design` skill) → HTML dashboard | Ask which shape fits, then continue with the Know path using it as the reference. ### Know path — configure template Three rounds. Batch the questions in each round; don't ask them one at a time. **Round A — Tools.** Start here; it's the most concrete part. Three types; ask which the user wants (any combination): | Type | What it is | How to guide | |---|---|---| | **Prebuilt Claude Agent tools** (`agent_toolset_20260401`) | Ready-to-use: `bash`, `read`, `write`, `edit`, `glob`, `grep`, `web_fetch`, `web_search`. Enable all at once, or individually via `enabled: true/false`. | Recommend enabling the full toolset. List the 8 tools so the user knows what they're getting. Full detail: `shared/managed-agents-tools.md` → Agent Toolset. | | **MCP tools** | Third-party integrations (GitHub, Linear, Asana, etc.) via `mcp_toolset`. Credentials live in a vault, not inline. | Ask which services. For each, walk through MCP server URL + vault credentials. Full detail: `shared/managed-agents-tools.md` → MCP Servers + Vaults. | | **Custom tools** | The user's own app handles these tool calls — agent fires `agent.custom_tool_use`, the app sends a result message back. | Ask for each tool: name, description, input schema. The app code that handles the event is *their* code — don't generate it. Full detail: `shared/managed-agents-tools.md` → Custom Tools. | **Round B — Skills, files, and repos.** What the agent has on hand when it starts. *Skills* — two types; both work the same way — Claude auto-uses them when relevant. Max 64 per agent. - [ ] **Pre-built Agent Skills**: `xlsx`, `docx`, `pptx`, `pdf`. Reference by name. - [ ] **Custom Skills**: skills uploaded to the user's org via the Skills API. Reference by `skill_id` + optional `version`. If the skill doesn't exist yet, walk the user through `POST /v1/skills` + `POST /v1/skills/{id}/versions` (beta header `skills-2025-10-02`). Full detail: `shared/managed-agents-tools.md` → Skills + Skills API. *GitHub repositories* — any repos the agent needs on-disk? For each: - [ ] Repo URL (`https://github.com/org/repo`) - [ ] `authorization_token` (PAT or GitHub App token scoped to the repo) - [ ] Optional `mount_path` (defaults to `/workspace/`) and `checkout` (branch or SHA) Emit as `resources: [{type: "github_repository", url, authorization_token, ...}]`. Full detail: `shared/managed-agents-environments.md` → GitHub Repositories. > ‼️ **PR creation needs the GitHub MCP server too.** `github_repository` gives filesystem access only — to open PRs, also attach the GitHub MCP server in Round A and credential it via a vault. The workflow is: edit files in the mounted repo → push branch via `bash` → create PR via the MCP `create_pull_request` tool. *Files* — any local files to seed the session with? For each: - [ ] Upload via the Files API → persist `file_id` - [ ] Choose a `mount_path` — absolute, e.g. `/workspace/data.csv` (parents auto-created; files mount read-only) Emit as `resources: [{type: "file", file_id, mount_path}]`. Max 999 file resources. Agent working directory defaults to `/workspace`. Full detail: `shared/managed-agents-environments.md` → Files API. **Round C — Environment + identity:** - [ ] Networking: unrestricted internet from the container, or lock egress to specific hosts? (If locked, MCP server domains must be in `allowed_hosts` or tools silently fail.) - [ ] Name? - [ ] Job (one or two sentences — becomes the system prompt)? - [ ] Model? (default `{{OPUS_ID}}`) --- ## 2. Set up the session Per-run. Points at the agent + environment, attaches credentials, kicks off. **Vault credentials** (if the agent declared MCP servers): - [ ] Existing vault, or create one? (`client.beta.vaults.create()` + `vaults.credentials.create()`) Credentials are write-only, matched to MCP servers by URL, auto-refreshed. See `shared/managed-agents-tools.md` → Vaults. **Kickoff:** - [ ] First message to the agent? Session creation blocks until all resources mount. Open the event stream before sending the kickoff. Stream is SSE; break on `session.status_terminated`, or on `session.status_idle` with a terminal `stop_reason` — i.e. anything except `requires_action`, which fires transiently while the session waits on a tool confirmation or custom-tool result (see `shared/managed-agents-client-patterns.md` Pattern 5). Usage lands on `span.model_request_end`. Agent-written artifacts end up in `/mnt/session/outputs/` — download via `files.list({scope_id: session.id, betas: ["managed-agents-2026-04-01"]})`. --- ## 3. Emit the code Go straight from the last interview answer to the code — no preamble about the setup-vs-runtime split, no "the critical thing to internalize…", no lecture about `agents.create()` being one-time. The two-block structure below already shows that; don't narrate it. Generate **two clearly-separated blocks** per language detected (Python/TS/cURL — see SKILL.md → Language Detection): **Block 1 — Setup (run once, store the IDs):** 1. `environments.create()` → persist `env_id` 2. `agents.create()` with everything from §Round A–C → persist `agent_id` and `agent_version` Label: `# ONE-TIME SETUP — run once, save the IDs to config/.env` **Block 2 — Runtime (run on every invocation):** 1. Load `env_id` + `agent_id` from config/env 2. `sessions.create(agent=AGENT_ID, environment_id=ENV_ID, resources=[...], vault_ids=[...])` 3. Open stream, `events.send()` the kickoff, loop until `session.status_terminated` or `session.status_idle && stop_reason.type !== 'requires_action'` (see `shared/managed-agents-client-patterns.md` Pattern 5 for the full gate — do not break on bare `session.status_idle`) > ⚠️ **Never emit `agents.create()` and `sessions.create()` in the same unguarded block.** That teaches the user to create a new agent on every run — the #1 anti-pattern. If they need a single script, wrap agent creation in `if not os.getenv("AGENT_ID"):`. Pull exact syntax from `python/managed-agents/README.md`, `typescript/managed-agents/README.md`, or `curl/managed-agents.md`. Don't invent field names.