> ## Documentation Index
> Fetch the complete documentation index at: https://docs.emergence.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Author Guide

> How to build, register, and operate A2A-compatible agents on the CRAFT platform.

# Agent Author Guide

CRAFT is a multi-agent platform built on the A2A protocol. Every capability in CRAFT — from natural-language SQL generation to semiconductor yield analysis — runs as a discrete, independently deployable agent.

**The short version:** CRAFT gives you managed LLMs, tool discovery, and an agent registry. Your agent gets all three by pointing its LLM client at the CRAFT gateway and making one API call to register. Start with the [tutorial](/guides/agent-author/your-first-agent) if you want to be running in under 20 minutes.

This overview covers what it means to be an agent on CRAFT, when to build one, how to choose a framework, and how the platform integrates with your agent at runtime.

## What is an agent on CRAFT?

A CRAFT agent is a service that:

1. Exposes an **Agent Card** at `/.well-known/agent-card.json` describing its identity, skills, and capabilities
2. Accepts work via **A2A JSON-RPC** (`message/send` or `message/stream`)
3. Streams progress and results back as **SSE events**
4. Registers with the **Assets API** so other agents and the orchestrator can discover and invoke it

Agents are microservices first. They can be authored in any language, deployed anywhere, and call any tools — as long as they speak the A2A protocol at their boundary.

## When should you build an agent?

<AccordionGroup>
  <Accordion title="Build an agent when...">
    * You have a bounded capability with a clear input/output contract (e.g., "turn natural language into SQL", "generate yield analysis charts")
    * The capability needs to be independently scalable or deployable
    * The capability will be invoked by other agents or orchestrators
    * You want the capability to appear in the platform's agent registry and be discoverable by the orchestrator
    * The capability is owned by a separate team with its own release cadence
  </Accordion>

  <Accordion title="Don't build an agent when...">
    * The capability is a simple function call used only within a single agent — add it as a tool instead
    * The capability is a data transformation pipeline with no LLM reasoning — use a standard service
    * You need real-time collaboration between multiple LLMs sharing memory — use sub-agents within the same ADK process
    * The capability is a UI-layer concern — use CRAFT's REST API directly
  </Accordion>
</AccordionGroup>

## Framework choice

CRAFT supports four agent frameworks. Choose based on your team's constraints and the nature of your agent.

| Framework            | Language           | Best For                                                               | Pros                                                                                                                  | Cons                                                      |
| -------------------- | ------------------ | ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| **Google ADK**       | Python             | Analytics, multi-agent orchestration, data pipelines                   | Native A2A (`to_a2a()`), `RemoteA2aAgent` for sub-agent delegation, model-agnostic via LiteLLM, ADK Web for debugging | A2A support still experimental; Python-only               |
| **Claude Agent SDK** | Python, TypeScript | Reasoning-heavy tasks, document analysis, complex multi-step workflows | Extended thinking, strong tool-use, multi-turn conversation handling                                                  | No native A2A server — wrap with `a2a` library manually   |
| **Pydantic AI**      | Python             | Type-safe agents, data-structured outputs, MCP toolsets                | FastMCPToolset for MCP integration, strict typing, clean dependency injection via `deps_type`                         | Less mature ecosystem than ADK                            |
| **LangGraph**        | Python             | Stateful workflows, graph-based logic, conditional branching           | Explicit state machine, fine-grained control over execution flow                                                      | More boilerplate; no native A2A — wrap with `a2a` library |

<Warning>
  **CrewAI and role-based frameworks are not supported on CRAFT.** Multi-agent coordination on CRAFT happens at the protocol layer through A2A — agents discover each other via the registry and communicate via JSON-RPC. Role-based crew frameworks duplicate this coordination mechanism and create tight coupling that breaks independent deployability. Do not use them.
</Warning>

### Framework decision flowchart

```mermaid theme={null}
%%{init: {'theme': 'base', 'themeVariables': {'lineColor': '#555555', 'fontFamily': 'sans-serif', 'edgeLabelBackground': '#ffffff'}}}%%
flowchart TD
    Start["New agent on CRAFT"] --> Q1{"Primary need?"}

    Q1 -->|"Multi-agent orchestration\nor data analytics"| Q2{"Team already uses\nGoogle ADK?"}
    Q1 -->|"Reasoning-heavy,\nlong documents"| Claude["Claude Agent SDK"]
    Q1 -->|"Strict typed outputs,\nMCP toolsets"| Pydantic["Pydantic AI"]
    Q1 -->|"Complex stateful\nworkflow / branching"| LangGraph["LangGraph"]

    Q2 -->|"Yes or no preference"| ADK["Google ADK"]
    Q2 -->|"No — already on\nPydantic AI"| Pydantic

    ADK --> A2A_native["to_a2a() + RemoteA2aAgent\n— A2A built in"]
    Claude --> A2A_wrap["Wrap with a2a library\n+ A2AStarletteApplication"]
    Pydantic --> A2A_wrap
    LangGraph --> A2A_wrap

    A2A_native --> Register["Register in Assets API"]
    A2A_wrap --> Register

    classDef entry fill:#56B4E9,stroke:#555555,color:#000
    classDef decision fill:#F0E442,stroke:#555555,color:#000
    classDef framework fill:#E69F00,stroke:#555555,color:#000
    classDef infra fill:#0072B2,stroke:#555555,color:#fff
    classDef terminal fill:#009E73,stroke:#555555,color:#000

    class Start entry
    class Q1,Q2 decision
    class ADK,Claude,Pydantic,LangGraph framework
    class A2A_native,A2A_wrap infra
    class Register terminal
```

## Platform integration points

Every agent on CRAFT integrates with three platform services at runtime.

### Assets API — agent registry

The Assets API is the source of truth for agent discovery. Before your agent can be invoked by an orchestrator, you must register it:

```bash theme={null}
curl -X POST "https://<platform-host>/api/assets/agents" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Project-ID: <your-project-id>" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_card": { ... },
    "tags": ["analytics"],
    "visibility": "TENANT_ONLY"
  }'
```

The registry stores the Agent Card, assigns a `resource_uri` (`agent:<org>:<project>:<name>`), and makes the agent discoverable to orchestrators and other platform consumers.

### LiteLLM gateway — model access

All LLM calls from agents on CRAFT route through the shared LiteLLM gateway. This provides:

* **Unified model access** — use Gemini, Claude, GPT-5.5, and others with a single OpenAI-compatible endpoint
* **Cost tracking** — per-org, per-project token usage recorded automatically
* **Rate limiting** — enforced per tenant to prevent runaway costs
* **Model aliasing** — `LLM_PRO`, `LLM_LIGHT` constants resolve to the current best model for each tier

Configure your agent to point at the gateway:

```python theme={null}
# Google ADK — via the LiteLlm wrapper pointed at the gateway
from google.adk.agents import Agent
from google.adk.models.lite_llm import LiteLlm
import os

root_agent = Agent(
    name="my_agent",
    # The "openai/" prefix tells LiteLLM to use the OpenAI-compatible endpoint;
    # the actual model string is whatever the gateway routes (gemini-3.5-flash here).
    model=LiteLlm(
        model="openai/gemini-3.5-flash",
        api_base=os.environ["CRAFT_GATEWAY_URL"],
        api_key=os.environ["CRAFT_TOKEN"],
    ),
)

# Pydantic AI — point the OpenAI-compatible provider at the gateway
from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.providers.openai import OpenAIProvider

model = OpenAIChatModel(
    "gemini-3.5-flash",
    provider=OpenAIProvider(
        base_url=os.environ["CRAFT_GATEWAY_URL"],
        api_key=os.environ["CRAFT_TOKEN"],
    ),
)
agent = Agent(model, system_prompt="...")
```

See [Your First Agent › Step 1](/guides/agent-author/your-first-agent) for the
same pattern across all four supported frameworks (ADK, Claude SDK / OpenAI
client, Pydantic AI, LangGraph).

### em-runtime-mcp — tool access

CRAFT agents access data and platform capabilities through the `em-runtime-mcp` MCP server. Tools available include database schema inspection, query execution, artifact upload/download, and context graph queries.

```python theme={null}
# Pydantic AI — FastMCPToolset connects to em-runtime-mcp
from pydantic_ai.toolsets.fastmcp import FastMCPToolset
from fastmcp import Client
from fastmcp.client.transports import StreamableHttpTransport

mcp_client = Client(
    transport=StreamableHttpTransport(settings.mcp_server_url),
)
toolset = FastMCPToolset(mcp_client)
```

<Note>
  Create a fresh MCP client and toolset per agent request. Do not reuse a single long-lived client across requests — MCP sessions can expire or the MCP server pod can restart.
</Note>

## Guide contents

<CardGroup cols={2}>
  <Card title="A2A Protocol Primer" icon="network-wired" href="/guides/agent-author/a2a-protocol-primer">
    Agent Cards, JSON-RPC methods, SSE streaming, and the task lifecycle.
  </Card>

  <Card title="Your First Agent" icon="play" href="/guides/agent-author/your-first-agent">
    Framework-by-framework tutorial: Google ADK, Claude Agent SDK, Pydantic AI, LangGraph.
  </Card>

  <Card title="Tool Authoring" icon="wrench" href="/guides/agent-author/tool-authoring">
    Function tools, MCP tools via FastMCPToolset, schema discipline.
  </Card>

  <Card title="Multi-Agent Patterns" icon="diagram-project" href="/guides/agent-author/multi-agent-patterns">
    Delegation, supervision, and parallel fan-out via A2A.
  </Card>

  <Card title="Streaming Idioms" icon="wave-square" href="/guides/agent-author/streaming-idioms">
    SSE streaming, partial results, cooperative cancellation.
  </Card>

  <Card title="Eval Harness" icon="flask" href="/guides/agent-author/eval-harness">
    Langfuse evaluators, regression suites, golden traces.
  </Card>

  <Card title="Debugging Agents" icon="bug" href="/guides/agent-author/debugging-agents">
    Trace inspection, prompt iteration, common failure modes.
  </Card>
</CardGroup>
