Home › Agent Skills › Managed Agents — skills live on the Agent, with a session-scoped override
Agent Skills · Build

Managed Agents — skills live on the Agent, with a session-scoped override

Skills reach a Managed Agent two ways: attach them to the persisted, versioned Agent object via its skills array, or mount a GitHub repository whose root `.claude/skills//SKILL.md` d

In one line

skills is a field on the Agent object, and the only session-scoped path to a different skill set is the agent_with_overrides form at session-create time — sessions.update cannot touch it.

Why you'd careThe problem it solves

You are writing the call and you need to know where the array is legal before you type it, because getting it wrong fails in three different ways. Put skills on sessions.create() as a top-level field and it is rejected. Put it on the Agent and every session inherits it, including the one run where you wanted it off. Try to fix that mid-flight with sessions.update() and it silently is not one of the fields that call accepts. The catalogue previously carried a flat claim that model, system, tools, MCP servers, and skills are "never session fields" — that is now wrong, and the correction has a shape worth learning rather than memorising as a new flat rule. There is a session-scoped path. It is narrow, it is create-time only, and it replaces rather than merges.

ConceptWhat it is

Managed Agents splits configuration from execution. An Agent is a persisted, versioned object holding model, system, tools, mcp_servers, and skills. A Session is a run against a pre-created Agent plus an Environment; every update to the Agent cuts a new version, and a session can pin to one for reproducibility. That is why skills live on the Agent: they are configuration, and configuration is what gets versioned.

The agent field on sessions.create() takes three forms. A bare string ID uses the latest version. An object of type agent with an explicit version pins it. An object of type agent_with_overrides takes the same ID plus replacements for model, system, tools, mcp_servers, or skills — applied to that session only, creating no new Agent version.

So both halves of the correction matter. Skills are not a top-level session field; there is no sessions.create(skills=[...]). But they are overridable at session-create through that third form. Once the session exists, the door closes: sessions.update() can change tools, mcp_servers, and vault_ids on a live session, and skills are not on that list. A skill set is therefore fixed for a session's lifetime, decided at the moment of creation, from either the Agent's value or a create-time override. The cap is 500 skills per session, counted as the deduplicated set across every agent in the session.

How it worksThe mechanics

Skills go on the Agent, alongside model and system:

code
agent = client.beta.agents.create(
    name="Financial Agent",
    model="claude-opus-5",
    system="You are a financial analysis agent.",
    skills=[
        {"type": "anthropic", "skill_id": "xlsx"},
        {"type": "custom", "skill_id": "skill_abc123", "version": "latest"},
    ],
)

session = client.beta.sessions.create(
    agent=agent.id,                    # string shorthand, latest version
    environment_id=environment.id,
)

version is optional on both kinds and defaults to latest. It is not a custom-skill-only field, which is a common misreading of examples that happen to show it only on the custom entry.

To give one session a different set, use the third agent form:

code
session = client.beta.sessions.create(
    agent={
        "type": "agent_with_overrides",
        "id": agent.id,
        "skills": [{"type": "anthropic", "skill_id": "xlsx"}],
    },
    environment_id=environment.id,
)

Three rules govern that override. Omit the field and the session inherits the Agent's skills. Pass null or [] and the session runs with no skills — clearing works in full for skills, unlike model, which can never be cleared. Pass a value and it replaces the Agent's list entirely; overrides never merge, so an override must name every skill the session should have.

One coupling to know about: skills need the read tool to reach their bundled files. Clearing tools in an override returns a 400 when the session's effective skills is non-empty. If you genuinely want neither, clear both in the same request.

Two more edges. In a multiagent session, overrides apply to the coordinator and its self-copies only — roster agents referenced by ID always run their own as-created configuration, skills included. And on a self-hosted sandbox the skills attached to the agent are downloaded into {workdir}/skills/<name>/ before tool calls begin, which is where to look when a skill appears attached but its files are not on disk.

At a glanceSee it

Managed Agents — skills live on the Agent, with a session-scoped override diagram

Where the skills array is legal: on the Agent, or in a create-time session override — never after.

Where it runsSurfaces and availability

SurfaceStatusNotes
Managed AgentsYesBeta (managed-agents-2026-04-01; memory-store endpoints use agent-memory-2026-07-22). skills on agents.create() and agents.update(), each entry taking type (anthropic or custom), skill_id, and an optional version defaulting to latest; session-scoped replacement through agent_with_overrides at create time. The ceiling is 500 skills per session, counted across every agent in the session — not a per-agent cap of twenty. Mounting more skills slows sandbox start-up, so attach only what each agent needs. Source: Managed Agents → Skills (platform.claude.com/docs/en/managed-agents/skills).
Claude API / Messages APIYesGenerally available with no beta header, and a different mechanism: container.skills with the code-execution tool, capped at 20 skills per request. The Agent request shape does not transfer.
Claude Platform on AWSYesBeta. Managed Agents is documented as available there “including agents, environments, sessions, credential vaults, memory stores, webhooks, multiagent orchestration, and self-hosted sandboxes”. The one documented divergence is autonomous-session reauthentication: a session may run without user events for up to 6 hours, after which it needs any user-role event before continuing; first-party Managed Agents has no such limit. Self-hosted sandboxes are supported here — the worker authenticates with AWS IAM (SigV4) or an API key generated in the AWS Console rather than a Console environment key, with the AnthropicSelfHostedEnvironmentAccess managed policy attached. Source: platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws.
Claude CodeNoDifferent object model — local directories, no Agent object, no skill_id.
Claude Desktop or claude.aiNoThese are end-user products, not the Managed Agents API surface. Their own skills feature is a separate question — and a separate store: claude.ai Skills are per-user zip uploads that do not sync to the API or to Managed Agents.
Agent SDKNoEasily confused with Managed Agents, and different: the Agent SDK is a harness you host yourself. Its skills are filesystem artefacts, and the docs state it “doesn't provide a programmatic API for registering them” — it does not create Agent objects or attach skills to them.
Amazon BedrockNoManaged Agents is documented as available on the first-party API and Claude Platform on AWS; Bedrock is not among them. Agent Skills are separately recorded as “Not available (requires code execution)” on Bedrock, and the anthropic-beta header is unsupported there, so neither route exists.
Google Vertex AINoDocumented, not inferred: “Claude Managed Agents” appears verbatim in the “Features not supported” list on the Claude on Google Cloud page, alongside Agent Skills (platform.claude.com/docs/en/build-with-claude/claude-on-vertex-ai).
Microsoft FoundryNoCorrecting an earlier reading: this is a documented denial, not an inference from absence. Anthropic's Foundry page lists “Claude Managed Agents” explicitly under “Claude features not supported for Claude in Microsoft Foundry” (platform.claude.com/docs/en/build-with-claude/claude-in-microsoft-foundry). Foundry does carry Agent Skills on the Messages API path at beta — but only on a Hosted on Anthropic deployment. Treat the Agent path on Foundry as ruled out, not as untested.
Self-hosted sandboxesYesBeta. The agent loop stays on Anthropic's side; your worker claims the session from a queue and downloads the agent's skills to <workdir>/skills/<name>/ (workdir defaults to /workspace; if you change it, update the agent's system prompt so Claude can still find the files). Two operational differences worth planning for: deliverables are written under the working directory rather than /mnt/session/outputs, so bind-mount that directory to retrieve them; and skills may bundle executables — the CLI and SDK workers preserve the executable bits from the skill bundle, but a hand-rolled download must set them itself. Source: platform.claude.com/docs/en/managed-agents/self-hosted-sandboxes.

The split that matters for a build decision is Foundry, and it is now settled rather than open: the stateless Messages API skills path works there, the Agent path is documented as unsupported. That is an argument for keeping document generation on container.skills where a Foundry deployment is on the roadmap — or for accepting that the Agent path is first-party and AWS only. Two corrections worth carrying forward if you have quoted this table before. The per-agent skill ceiling is not twenty; it is 500 per session across all agents, which changes what a large multiagent roster can carry. And Claude Platform on AWS is closer to parity than previously recorded — self-hosted sandboxes run there too, with IAM-based worker auth; the real constraint is the 6-hour autonomous-session reauthentication window, which is the thing to design around for long unattended runs.

ExampleIn the real world

A team ships an internal analyst agent. Its Agent object carries the pre-built xlsx skill plus a custom house-model-conventions skill that encodes the firm's tab layout, sign conventions, and the assumptions block every model must open with. Every session inherits both, and the agent ID lives in config — created once, referenced forever.

Then a client asks for a workbook in their template. Running the house conventions would actively fight the requirement.

The wrong instinct is to update the Agent, which cuts a new version everyone else inherits, or to start the session and strip the skill afterwards, which sessions.update() will not do. The right move is one session created with agent_with_overrides, listing only {"type": "anthropic", "skill_id": "xlsx"}. That replaces the list wholesale — the custom skill is gone for this run, the Excel skill survives because it was named explicitly, and the Agent object is untouched at version 7.

The response's agent object reflects the post-override configuration while its id and version still identify the base agent, so the run is traceable back to version 7 even though it did not behave like it. Every other session that day keeps both skills.

Not thisWhat it is often confused with

  • Not a top-level session fieldthere is no sessions.create(skills=[...]). The only session-side entry point is inside the agent field's agent_with_overrides form. The nesting is the whole distinction.
  • Not mutable mid-sessionsessions.update() accepts agent.tools, agent.mcp_servers, and vault_ids. Skills are not on that list. A skill set is decided at create time and fixed for the session's lifetime.
  • Not a mergean override replaces the Agent's list in full. "Add one skill for this session" does not exist; you re-list everything you want. The same is true of agents.update(), where array fields are replaced wholesale.
  • Not the Messages API container.skillssame concept, different field, different call, different lifecycle. Copying the container block onto an Agent create will not work, and neither will the reverse.
  • Not a toolskills sit in their own array and are never called with arguments. They do, however, depend on the read tool, which is why clearing tools with non-empty skills is rejected.

LimitsWhen not to reach for it

  • The behaviour varies per request, not per deployment.If every run needs a different skill set, you are versioning an Agent for something that is really request-scoped. Use the stateless Messages API path instead.
  • You wanted to change skills on a running session.You cannot. If that requirement is real, restructure so the decision happens before sessions.create() — or end the session and start another.
  • You are attaching dozens of skills to one agent.The ceiling is 500 per session, but every mounted skill adds sandbox start-up time and context cost. Split into several agents with focused skill sets and delegate, rather than assembling one agent that knows everything.
  • You need to override effort too.An effort value inside a per-session model override is not applied, and because that override replaces the Agent's whole model object, the Agent's own effort is dropped too — the session runs at the model's default effort. If effort must change, that is a different agent or an agent update, not an override.
  • The target is Bedrock, Vertex, or Foundry.Managed Agents is not available on any of them. Build on the Messages API surface, or on Claude Platform on AWS.
Checked

Verified 2026-09-12. Moves in weeks. Treat anything specific here as a starting point, not a fact. Provider: Anthropic.

A living map of modern AI — kept current every morning