bollwerk/.github/skills/claude-api/shared/managed-agents-onboarding.md

7.9 KiB
Raw Permalink Blame History

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
Scheduled Cron Daily brief: browser + GitHub + Jira → CMA → Slack
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/<repo-name>) 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 claude-opus-4-7)

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 AC → 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.