Build Your First Claude Agent in 15 Minutes (Step-by-Step)

A hands-on tutorial for building your first Claude Managed Agent. Create an agent, configure tools, launch a session, and stream results — with real code.

Anthropic launched Claude Managed Agents on April 8, and the official docs are solid — but they throw you into API calls without much context about why each step matters or what to do when things don’t work.

This is the friendlier version. We’ll build a working agent from scratch, explain what’s actually happening at each step, and flag the gotchas the docs don’t mention. Total time: about 15 minutes if you already have an API key.


What You’re Building

By the end of this tutorial, you’ll have a Claude agent that can:

  • Write and execute code inside a secure cloud container
  • Read and create files
  • Run bash commands
  • Browse the web
  • Stream its progress back to you in real time

The agent runs on Anthropic’s infrastructure. You don’t need Docker, Kubernetes, or any cloud provider setup. Just an API key and a terminal.


What You’ll Need

Before starting:

  1. An Anthropic account — Sign up at the Anthropic Console if you don’t have one
  2. An API key — Create one in your Console settings
  3. Python 3.8+ or Node.js 18+ — For running the code examples (we’ll show both)
  4. A terminal — Any terminal works: macOS Terminal, VS Code terminal, Windows Terminal with WSL

Set your API key as an environment variable:

export ANTHROPIC_API_KEY="your-api-key-here"

Then install the SDK:

# Python
pip install anthropic

# Or TypeScript
npm install @anthropic-ai/sdk

Step 1: Create an Agent

An agent is a reusable configuration. Think of it as a job description — you define what model it uses, what instructions it follows, and what tools it has access to.

Python:

from anthropic import Anthropic

client = Anthropic()

agent = client.beta.agents.create(
    name="Coding Assistant",
    model="claude-sonnet-4-6",
    system="You are a helpful coding assistant. Write clean, well-documented code.",
    tools=[
        {"type": "agent_toolset_20260401"},
    ],
)

print(f"Agent ID: {agent.id}")

TypeScript:

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const agent = await client.beta.agents.create({
  name: "Coding Assistant",
  model: "claude-sonnet-4-6",
  system: "You are a helpful coding assistant. Write clean, well-documented code.",
  tools: [
    { type: "agent_toolset_20260401" },
  ],
});

console.log(`Agent ID: ${agent.id}`);

What’s happening: You’re registering an agent definition with Anthropic’s API. The agent_toolset_20260401 gives it access to all built-in tools — bash, file operations, web search, code execution. You get back an agent.id that you’ll reuse for every session.

The system prompt matters more than you’d think. This isn’t just a greeting. It shapes how the agent approaches every task. “Write clean, well-documented code” means it’ll add comments and structure. Change this to “Write minimal, production-ready code with error handling” and you’ll get different output.

Save that agent.id — you’ll reference it in every session.


Step 2: Create an Environment

An environment is the container where your agent does its work. It’s a sandboxed Linux machine with whatever packages and network access you configure.

Python:

environment = client.beta.environments.create(
    name="quickstart-env",
    config={
        "type": "cloud",
        "networking": {"type": "unrestricted"},
    },
)

print(f"Environment ID: {environment.id}")

TypeScript:

const environment = await client.beta.environments.create({
  name: "quickstart-env",
  config: {
    type: "cloud",
    networking: { type: "unrestricted" },
  },
});

console.log(`Environment ID: ${environment.id}`);

What’s happening: Anthropic spins up a container template for you. The "unrestricted" networking means the agent can reach the internet (useful for web searches, API calls, package installs). In production, you’d lock this down to specific domains.

The container comes with Python, Node.js, and common tools pre-installed. If your agent needs to pip install pandas or npm install axios, it can do that inside the container during a session.

Save the environment.id too.


Step 3: Start a Session

A session connects your agent to an environment and kicks things off. This is where actual work happens.

Python:

session = client.beta.sessions.create(
    agent=agent.id,
    environment_id=environment.id,
    title="My first agent session",
)

print(f"Session ID: {session.id}")

TypeScript:

const session = await client.beta.sessions.create({
  agent: agent.id,
  environment_id: environment.id,
  title: "My first agent session",
});

console.log(`Session ID: ${session.id}`);

What’s happening: Anthropic provisions a fresh container from your environment template, loads your agent configuration into it, and waits for instructions. The session is now live — but the agent won’t do anything until you send it a message.


Step 4: Send a Message and Stream the Response

Now the fun part. You send the agent a task, and it streams back what it’s doing in real time — including every tool call, file write, and bash command.

Python:

with client.beta.sessions.events.stream(session.id) as stream:
    # Send the task
    client.beta.sessions.events.send(
        session.id,
        events=[
            {
                "type": "user.message",
                "content": [
                    {
                        "type": "text",
                        "text": "Create a Python script that generates the first 20 Fibonacci numbers and saves them to fibonacci.txt",
                    },
                ],
            },
        ],
    )

    # Watch the agent work
    for event in stream:
        match event.type:
            case "agent.message":
                for block in event.content:
                    print(block.text, end="")
            case "agent.tool_use":
                print(f"\n[Using tool: {event.name}]")
            case "session.status_idle":
                print("\n\nAgent finished.")
                break

TypeScript:

const stream = await client.beta.sessions.events.stream(session.id);

await client.beta.sessions.events.send(session.id, {
  events: [
    {
      type: "user.message",
      content: [
        {
          type: "text",
          text: "Create a Python script that generates the first 20 Fibonacci numbers and saves them to fibonacci.txt",
        },
      ],
    },
  ],
});

for await (const event of stream) {
  if (event.type === "agent.message") {
    for (const block of event.content) {
      process.stdout.write(block.text);
    }
  } else if (event.type === "agent.tool_use") {
    console.log(`\n[Using tool: ${event.name}]`);
  } else if (event.type === "session.status_idle") {
    console.log("\n\nAgent finished.");
    break;
  }
}

What you’ll see:

I'll create a Python script that generates the first 20 Fibonacci numbers
and saves them to a file.
[Using tool: write]
[Using tool: bash]
The script ran successfully. Let me verify the output file.
[Using tool: bash]
fibonacci.txt contains the first 20 Fibonacci numbers (0 through 4181).

Agent finished.

What’s happening under the hood: The agent read your message, decided it needed to write a file (used the write tool), executed it with bash, then verified the output by reading the file back. Three tool calls, all autonomous — you didn’t tell it how to do the task, just what you wanted.

The session.status_idle event means the agent has nothing left to do. That’s your signal to either send another message or close the session.


The Three Key Events

When streaming, you’ll encounter these event types constantly:

EventWhat It MeansWhen You’ll See It
agent.messageThe agent is talking to youExplaining its plan, reporting results
agent.tool_useThe agent is using a toolWriting files, running code, searching the web
session.status_idleThe agent is doneTask complete, waiting for next instruction

There are more event types (tool results, errors, status changes), but these three cover 90% of what you need for a basic integration.


What It Can’t Do (Yet)

Before you go building your entire infrastructure around this:

It’s in beta. The API requires a managed-agents-2026-04-01 beta header (the SDK handles this automatically). Endpoints and event formats could change.

Session containers are ephemeral. Files written during a session live in that session’s container. When the session ends, they’re gone unless you extract them first via the API.

Rate limits apply. Standard Claude API rate limits govern how many tokens your agent can consume. If your agent is doing complex, multi-step work, you’ll burn through tokens faster than a regular chat.

Cost can surprise you. The $0.08/hr runtime fee is small, but token costs for multi-tool-call sessions add up. A session that runs for 10 minutes with 15 tool calls might cost $0.50-2.00 in total depending on the model and output length.


What to Build Next

Now that you’ve got a working agent, here are three practical directions:

Make it useful for your work. Change the system prompt and task to something you actually do. “Analyze this CSV and generate a summary report.” “Read these log files and find the error pattern.” “Write unit tests for this module.” The tools are the same — the prompt is what makes it yours.

Add MCP servers. Managed Agents supports MCP (Model Context Protocol) servers, which means your agent can connect to Slack, GitHub, databases, or any tool with an MCP integration. This is how the Notion and Asana integrations work.

Build a multi-agent workflow. Agents can spawn sub-agents. A “project manager” agent can create specialist agents for different parts of a task — one for research, one for coding, one for testing. This is where things get genuinely powerful.


What This Means for You

If you’re a developer: This is the fastest path to a working AI agent in production. The four-step flow (agent → environment → session → stream) takes the infrastructure question off the table entirely. You can prototype a real agent in an afternoon and have it running for clients by the end of the week.

If you’re a technical PM or founder: The barrier to AI agent products just dropped. You don’t need an infrastructure team. You don’t need to understand container orchestration. You need an API key, a clear idea of what you want the agent to do, and someone who can write a Python or TypeScript script.

If you’re learning about AI agents: This tutorial is a complete, working example you can run right now. Modify the task, change the system prompt, watch how the agent’s behavior changes. That hands-on loop is how you actually learn what agents can and can’t do.


The Complete Script

Here’s the full Python script — copy, paste, run:

from anthropic import Anthropic

client = Anthropic()

# 1. Create agent
agent = client.beta.agents.create(
    name="Coding Assistant",
    model="claude-sonnet-4-6",
    system="You are a helpful coding assistant. Write clean, well-documented code.",
    tools=[{"type": "agent_toolset_20260401"}],
)
print(f"Agent: {agent.id}")

# 2. Create environment
environment = client.beta.environments.create(
    name="quickstart-env",
    config={"type": "cloud", "networking": {"type": "unrestricted"}},
)
print(f"Environment: {environment.id}")

# 3. Start session
session = client.beta.sessions.create(
    agent=agent.id,
    environment_id=environment.id,
    title="Quickstart",
)
print(f"Session: {session.id}\n")

# 4. Send task and stream response
with client.beta.sessions.events.stream(session.id) as stream:
    client.beta.sessions.events.send(
        session.id,
        events=[{
            "type": "user.message",
            "content": [{"type": "text", "text": "Create a Python script that generates the first 20 Fibonacci numbers and saves them to fibonacci.txt"}],
        }],
    )

    for event in stream:
        match event.type:
            case "agent.message":
                for block in event.content:
                    print(block.text, end="")
            case "agent.tool_use":
                print(f"\n[Tool: {event.name}]")
            case "session.status_idle":
                print("\n\nDone.")
                break

Run it with python your_script.py and watch your first agent work.


Sources:

Build Real AI Skills

Step-by-step courses with quizzes and certificates for your resume