examples/integrations/claude-sdk-python/README.md
A starter template for building AI agents with the Claude Agent SDK and CopilotKit. It pairs a modern Next.js frontend with a Python agent that speaks the AG-UI protocol, and shows CopilotKit driving interactive UI beyond chat:
The agent is powered by Claude (claude-sonnet-5 by default) and exposes three backend tools —
query_data, search_flights, and generate_a2ui — while the todo board is shared state the
agent updates through the adapter's built-in ag_ui_update_state tool.
Copy the environment file:
cp .env.example .env
Add your Anthropic API key to .env:
ANTHROPIC_API_KEY=sk-ant-...
The other values are optional and already set to sensible defaults:
CLAUDE_MODEL=claude-sonnet-5 and AGENT_URL=http://localhost:8000.
Install dependencies:
npm install
This installs the Next.js frontend and, via the
postinstallscript, the Python agent's dependencies withuv sync.
Start the app:
npm run dev
This runs the Next.js UI on http://localhost:3000 and the Claude agent on http://localhost:8000 concurrently.
Open http://localhost:3000 and try the suggested prompts (add todos, draw a chart, search flights, build a dashboard, schedule a meeting).
(Optional) Enable the Threads drawer. Thread history is gated behind a CopilotKit
Intelligence license. Set COPILOTKIT_LICENSE_TOKEN (and the INTELLIGENCE_* URLs) in
.env to activate live thread history; without it the drawer shows a locked state.
channel-host.mts mounts the same agent as an Intelligence Channel
(Slack, Teams). It requires INTELLIGENCE_API_KEY and a declared Channel in
.copilotkit/channels.json — set both up with copilotkit init or
copilotkit channels add, which write that file and the credentials your
.env needs, then:
npm run channel
The host reads which Channel to hold from .copilotkit/channels.json. If a
project declares more than one, set INTELLIGENCE_CHANNEL_NAME to pick one.
The host holds no provider credentials and exposes no provider endpoint — Intelligence owns the provider edge — so the same file works for every provider.
The Channel itself is declared in channels.mts — that is where to add commands,
reactions, or an onMention handler. channel-host.mts only owns the process
lifetime, and is byte-identical in every starter.
Once startup finishes, the log reports the truth per Channel:
Channel "<name>" is online. — the session is up and can send.Channel "<name>" is declared but no provider is attached yet. —
a normal waiting state, not a failure. Run copilotkit channels status to
see what setup remains.Neither message proves the provider app is installed, reachable, or that anyone can message it — verify that separately (invite the bot, then message it) before treating the Channel as working.
npm run dev — start the UI and agent together (dev mode)npm run dev:ui — start only the Next.js UI (port 3000)npm run dev:agent — start only the Claude agent (port 8000)npm run build — build the Next.js app for productionnpm start — start the production servernpm run install:agent — (re)install the Python agent's dependenciesnpm run channel — hold an Intelligence Channel open (see "Running a Channel" above)npm run typecheck:channel — type-check the channel host on its own tsconfig.channel.json├── src/
│ ├── app/
│ │ ├── page.tsx # Main page (chat + todos canvas + threads drawer)
│ │ ├── layout.tsx # CopilotKit v2 provider + A2UI catalog
│ │ └── api/copilotkit/[[...slug]]/ # CopilotKit runtime route (HttpAgent → :8000)
│ ├── components/ # Canvas, generative UI, chat, UI primitives
│ └── hooks/ # Example suggestions + generative-UI examples
└── agent/ # Python Claude agent (AG-UI on port 8000)
├── main.py # Server: mounts the adapter's FastAPI endpoint
├── pyproject.toml # Agent dependencies (managed by uv)
└── src/
├── agent.py # The agent: backend tools → ClaudeAgentAdapter
├── model.py # Model resolution (CLAUDE_MODEL)
├── query.py # query_data tool
├── a2ui_fixed_schema.py # search_flights tool (fixed A2UI schema)
├── a2ui_dynamic_schema.py # generate_a2ui tool (LLM-designed dashboard)
├── db.csv # Sample data for query_data
└── a2ui/schemas/flight_schema.json
src/app/api/copilotkit/[[...slug]]/route.ts) connects to the agent
over HTTP with HttpAgent from @ag-ui/client.ag-ui-claude-sdk adapter. src/agent.py
defines the three backend tools and hands them to ClaudeAgentAdapter; main.py serves it
with the adapter's add_claude_fastapi_endpoint. The adapter drives Claude through the Claude
Agent SDK, bridges CopilotKit frontend tools + human-in-the-loop, and manages the shared
todos state via its built-in ag_ui_update_state tool.To customize: add or edit tools in agent/src/ and the system prompt in agent/src/agent.py,
and the UI in src/app/page.tsx and src/components/.
"I'm having trouble connecting to my tools" / agent unreachable
npm run dev:agent) and that
ANTHROPIC_API_KEY is set in .env.curl http://localhost:8000/health → {"status":"ok"}.Python import errors
cd agent && uv sync.MIT — see LICENSE.