Claude Agent SDK project (agents-cli)
The agent is a ClaudeAgentOptions exported as root_agent from
app/agent.py. There is no google.adk dependency and no ADK runner. Other
google-agents-cli-* skills assume ADK; where they describe the agent itself,
this skill wins.
Experimental. Deploy to agent_runtime (limits: references/claude.md) or cloud_run.
The model runs on Claude on Gemini platform and must be enabled in Model Garden.
What ADK guidance maps to here
| ADK guidance | This project |
|---|---|
LlmAgent, Agent | ClaudeAgentOptions(model=..., system_prompt=..., ...) assigned to root_agent |
Agent(name=...) | AGENT_NAME in app/app_utils/settings.py (ClaudeAgentOptions has no name); keep it equal to create_params.root_agent_name in agents-cli-manifest.yaml |
google.adk.tools, FunctionTool | @tool(...) async functions, served by create_sdk_mcp_server and passed in mcp_servers |
adk web, agents-cli playground | Unavailable (no SDK dev UI). Use agents-cli run, or uv run uvicorn app.fast_api_app:app --port 8080 |
ADK runner behind agents-cli run | agents-cli run runs root_agent in process |
agents-cli eval dataset synthesize, eval optimize | Unavailable: both drive the agent through ADK. The command says so and exits |
agents-cli eval generate --url (traces from a served agent) | Unavailable: the server speaks A2A, not ADK's /run_sse. eval generate runs root_agent in process; the command refuses --url |
| ADK sessions | Claude sessions, one per A2A conversation; scaffold with --session-type cloud_sql to keep them across instances |
The contract
app/agent.pyexportsroot_agent: ClaudeAgentOptions. Only it changes when you change the agent.app/app_utils/claude.pyruns it. Leaveapp/app_utils/alone.- The served agent's own
CLAUDE.md,.claude/and.mcp.jsongo inagent_config/. app/fast_api_app.pyexposesapp. Every deployment target runsuvicorn app.fast_api_app:app.
Adding a tool
python@tool("lookup_order", "Look up an order by id.", {"order_id": str}) async def lookup_order(args: dict[str, Any]) -> dict[str, Any]: return {"content": [{"type": "text", "text": f"Order {args['order_id']}: shipped"}]} server = create_sdk_mcp_server(name="orders", tools=[lookup_order]) root_agent = ClaudeAgentOptions( ..., mcp_servers={"orders": server}, tools=[], # no built-in Claude Code tools allowed_tools=["mcp__orders__lookup_order"], # mcp__<server>__<tool> )
A tool missing from allowed_tools is not available to the agent. Subagents (agents=
or agent_config/.claude/agents/) run through the built-in Agent tool: add "Agent" to both
tools and allowed_tools. Built-in tools
(WebFetch, WebSearch, Read, Bash, ...) go in both tools and allowed_tools;
keep Bash and file-editing tools out of a served agent unless the user asks.
Commands
bashagents-cli install # uv sync agents-cli run "hello" # run root_agent in process; prints a session id agents-cli run "and?" --session-id <id> # continue that conversation agents-cli eval generate --dataset tests/eval/datasets/basic-dataset.json -o tests/eval/output/ agents-cli eval grade --traces tests/eval/output/<dataset>.json --config tests/eval/eval_config.yaml agents-cli deploy agents-cli scaffold enhance -d cloud_run --cicd-runner github_actions # add infra later
run, eval generate, publish gemini, playground, eval dataset and
eval optimize are overridden by agents-cli-extension.yaml at the project root.
Prefix any command with AGENTS_CLI_DISABLE_OVERRIDES=1 to reach the built-in instead.
Serving
A2A: JSON-RPC at POST /a2a/app, card at /a2a/app/.well-known/agent-card.json,
health at /health; over A2A, text streams as it is generated. On Agent Runtime, also
:query and :streamQuery (new sessions and turns), which agents-cli run --mode adk
and an ingress Agent Gateway use. See references/claude.md for sessions, telemetry
and deployment.
Common mistakes
- Renaming
root_agentorapp, which breaksrun, eval and deploy. - Leaving
toolsunset: the agent then gets every built-in Claude Code tool. - Using a model id that is not enabled on Gemini platform for the project.
- Reaching for
eval dataset synthesizeoreval optimize: they need ADK. Write cases intotests/eval/datasets/and useeval generate+eval grade. - Expecting
/run_sseor ADK's REST session routes; this server serves A2A and Agent Runtime's:query/:streamQuery.
References
references/claude.md— how a turn runs, model access, project settings, sessions, calling other agents, telemetry and logs.references/migrate-claude-agent.md— moving an existing Claude Agent SDK agent into this project and onto GCP.references/migrate-from-aws.md— extra migration steps for an agent running on AWS.


