# Embedded Agents Demo
One Claude Code skill, **`embedded-agents`**, that teaches a coding agent how to embed Claude agents in any web app using the [Claude Agent SDK](https://docs.claude.com/en/docs/agent-sdk/overview). Each embedded agent is a folder with its own instructions, knowledge files, skills and MCP servers. It runs isolated from the rest of the repo and the machine, and streams its answers to a chat UI.
The repo has no app code. Start a new app from it, or copy the skill into an app you already have. Then describe the agent you want, and Claude Code builds the rest.
## What's in the repo
```
AGENTS.md ← your project's instructions (empty; fill in your own)
CLAUDE.md ← imports AGENTS.md, so Claude Code reads the same file
.claude/skills/embedded-agents/
├── SKILL.md ← what Claude Code follows when the skill triggers
├── reference/playbook.md ← the architecture, with the measurement behind every option
├── templates/ ← the wrapper and the API route the skill copies into your app
├── scripts/ ← scaffold a new agent; list the tools an MCP server offers
└── examples/ ← two finished agents, used only when you ask for examples
```
`AGENTS.md` is empty on purpose. It is where your own rules go (stack, secrets, testing, release). `CLAUDE.md` holds only `@AGENTS.md`, so there is one instruction file to maintain.
## What the skill does
The app owns the request, the caller, storage and the UI. The agent owns reasoning and tool use. A single server-side function, `askAgent`, runs any agent. Agents are folders, so agent names never appear in code.
```
.claude/agents/<name>/
├── AGENTS.md ← the agent's instructions (its only instruction file)
├── knowledge/*.md ← optional: files it answers from
├── .mcp.json ← optional: its MCP servers, secrets as ${VAR}
└── .claude/skills/ ← optional: its own skills
```
**First use: installs the wrapper.** If there is no app yet, the skill creates a minimal Next.js (App Router, TypeScript) app. The wrapper is plain server-side Node, so an app on another framework only needs its own route. It then adds:
- `src/lib/agent.ts`: the wrapper around the SDK's `query()`
- `src/app/api/agents/route.ts`: `GET` lists the agents, `POST` streams one agent's answer as server-sent events
**Later uses: add agents.** `scripts/new-agent.mjs <name> [--knowledge] [--mcp]` scaffolds the folder. You fill in its `AGENTS.md`, and the new agent shows up in `GET /api/agents` and the chat UI's picker. You don't touch a registry, the wrapper or the UI.
**Isolation.** Every run gets the same settings, and a call site cannot turn them off:
1. Only the allowlisted built-in tools exist (`Read`, `Glob`, `Grep` by default). There is no `Bash`, `Write`, `Edit` or `WebFetch`.
2. An MCP tool runs only if the agent's `.mcp.json` lists it in `allowedTools`. Anything else is denied.
3. Only the agent's own MCP servers load. The developer's personal connectors don't leak in.
4. The model sees only the agent's own skills.
5. A hook blocks any file path outside the agent's folder, and any `.env` file.
6. Turn and budget caps limit each run.
`reference/playbook.md` explains why each setting exists (each one replaced an SDK default that failed a measurement) and what to check when you add an agent or upgrade the SDK.
## Examples
`examples/` contains two finished agents. The skill copies them only when you ask for examples:
- **knowledge-agent** answers product-management questions (OKRs, JTBD, product strategy, product vision, LLM basics) using only its `knowledge/` files. It cites the file it used and refuses topics the files don't cover.
- **research-agent** researches the live web through the Perplexity MCP server and returns a brief with sources. It needs `PERPLEXITY_API_KEY`.
## Getting started
1. Clone the repo and open it in [Claude Code](https://claude.com/claude-code). For an existing app, copy `.claude/skills/embedded-agents/` into that app's repo instead.
2. Ask for what you want, for example *"Build a chat app with the example agents"* or *"Add an agent that answers questions from our onboarding docs"*.
3. Put `ANTHROPIC_API_KEY` in `.env`, plus any secrets your agents' `.mcp.json` files reference. On a developer machine without that key, the SDK falls back to your own Claude login.
## Before you deploy
The SDK runs the Claude Code engine as a subprocess, so embedded agents need a long-lived Node host. They don't run in serverless or edge functions. Every call also costs money. Before anyone other than you can reach the route, identify the caller and set a per-user rate limit and a `maxBudgetUsd`.