> For the complete documentation index, see [llms.txt](https://docs.interactive.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.interactive.ai/agents/guides/quickstart.md).

# Quickstart

> **Context** — This guide builds a minimal but real agent — **Mercedes**, a car-rental assistant for "DriveAway" — on the InteractiveAI platform. The platform hosts and runs the agent; you author its content, deploy it with the `iai` CLI, and talk to it over the chat UI or the SDK. You don't run any agent container yourself. Time: \~30 minutes.
>
> **Prerequisites:**
>
> * A **project created in the InteractiveAI platform** (an organization + project you can deploy into).
> * The **`iai` CLI** installed and authenticated — run `iai login`, then `iai organizations` / `iai projects` to select your org and project (or pass `-o`/`-p` on each command).
> * An **LLM router API key** and a **project API key pair** (Platform UI → Project Settings → API Keys).
> * Python 3.12+ for the tool server and the SDK client.
>
> Every `iai` subcommand has `--help` (e.g. `iai routines create --help`); use it for the full flag set.
>
> YAML examples follow **manifest schema 6.1.1**. Manifest and content shapes are schema-versioned and differ across runtime versions — see [Versioning & compatibility](/agents/operations/versioning.md).

## What you'll build

```
  you author          platform hosts             you run / consume
  ──────────          ──────────────             ─────────────────
  system prompt  ┐
  policy         ├──► InteractiveAI ──► Mercedes ──chat UI / SDK──► you
  routine        ┘    (content +        (agent)   ◄──
  agent config        runtime)             │
                                           └──MCP──► your car-catalog tool server
```

Everything below is authored **in the platform** with `iai` — the platform catalog is the source of truth for your content; there's nothing to keep in sync locally. The steps: author the **content** (system prompt, policy, routine), stand up a **tool server**, then **deploy** the agent and chat with it.

## 1. Author the content in the platform

Content — the system prompt, routines, policies, glossaries, and macros — lives in the platform's versioned catalog. Each `iai … create` stores one item (and assigns it version 1); the agent config you write in step 3 references each by name and pins a version.

### System prompt

The agent's persona and ground rules — an unstructured **prompt**. Create it inline:

```bash
iai prompts create system-prompt --content "You are Mercedes, a friendly \
booking specialist at DriveAway, a car-rental agency. Help customers find \
the right car; keep answers short and concrete. Fleet: economy, compact, \
SUV, van, luxury. Daily rates ~35 EUR (economy) to ~140 EUR (luxury). \
Minimum driver age is 21. Warm, professional, no emoji; quote prices in \
EUR per day."
```

For anything longer, put the text in a file and use `--file system-prompt.txt` instead of `--content`.

### Policy

A condition → action rule applied on every turn. Put it in `stay-on-topic.yaml`:

```yaml
id: stay-on-topic
name: Stay On Topic
condition: >
  The user asks about something unrelated to car rental, the DriveAway
  fleet, bookings, or related logistics — e.g. life advice, news,
  unrelated products.
action: >
  Politely acknowledge the question, explain that you can only help with
  car rental at DriveAway, and offer one concrete next step — browsing
  the fleet or making a booking.
criticality: HIGH
```

```bash
iai policies create stay-on-topic --file stay-on-topic.yaml
```

(Concepts: [Policies](/agents/concepts/policies.md). More patterns: [Authoring policies](/agents/guides/authoring-policies.md). `iai policies schema` prints the full field set.)

### Routine

A multi-node flow. Put it in `car-search.yaml`:

```yaml
id: car-search
title: Car Search
conditions:
  - >
    The user wants to browse the fleet, find a car, or asks for car
    suggestions — phrases like "what cars do you have", "show me an SUV",
    "I need a 7-seater".
description: >
  Help the user narrow down the fleet by collecting their criteria,
  searching the catalog, and presenting results with prices.

entry: gather-criteria
nodes:
  - id: gather-criteria
    chat_state: >
      Ask the user for their preferences in one short message: category
      (economy / compact / SUV / van / luxury), minimum number of seats,
      transmission preference (manual or automatic), and any daily-budget
      cap in EUR. Tell them any field is optional.
    transitions:
      - to: run-search
        condition: >
          The user has provided at least one preference, or has said
          "anything" / "no preference".

  - id: run-search
    tools: cars:search_cars
    tool_instruction: >
      Call search_cars with the filters the user provided. Pass null /
      omit fields the user did not mention. Do not invent constraints.
    transitions:
      - to: present-results

  - id: present-results
    chat_state: >
      Summarise the matching cars in a compact list — one line per car
      with make, model, category, transmission, and daily price in EUR.
      If there are zero matches, suggest relaxing one specific filter.
      End by asking if the user wants to book one.
```

```bash
iai routines create car-search --file car-search.yaml
```

Note the structure: a **chat** node (ask), a **tool** node (search), a **chat** node (present), connected by transitions — never tools and speech on the same node. This is the single most important authoring rule; see [Routines](/agents/concepts/routines.md#node-types-read-this-first).

## 2. Stand up the tool server

The `run-search` node calls `cars:search_cars` — a tool your agent reaches over the Model Context Protocol. You host this server; the platform-run agent connects to it at the address you'll put in the agent config, so it must be reachable from the platform (a public URL or one your platform networking allows). `cars_mcp.py`:

```python
"""Minimal car-catalog MCP server for the DriveAway quickstart."""

from fastmcp import FastMCP

mcp = FastMCP("car-rental")

CATALOG = [
    {"car_id": "eco-1", "make": "Toyota", "model": "Yaris",
     "category": "economy", "seats": 5, "transmission": "manual",
     "daily_price_eur": 35},
    {"car_id": "suv-1", "make": "Volvo", "model": "XC60",
     "category": "suv", "seats": 5, "transmission": "automatic",
     "daily_price_eur": 95},
    {"car_id": "van-1", "make": "VW", "model": "Multivan",
     "category": "van", "seats": 7, "transmission": "automatic",
     "daily_price_eur": 110},
]


@mcp.tool
def search_cars(
    category: str | None = None,
    min_seats: int | None = None,
    transmission: str | None = None,
    max_daily_price_eur: int | None = None,
) -> dict:
    """Search the catalog for cars matching optional filters.

    Args:
        category: economy, compact, suv, van, or luxury.
        min_seats: minimum number of seats (e.g. 5, 7).
        transmission: manual or automatic.
        max_daily_price_eur: cap on daily rental price in EUR.

    Returns:
        {"results": [{car_id, make, model, category, seats,
        transmission, daily_price_eur}, ...]}
    """
    results = [
        car for car in CATALOG
        if (category is None or car["category"] == category.lower())
        and (min_seats is None or car["seats"] >= min_seats)
        and (transmission is None or car["transmission"] == transmission.lower())
        and (max_daily_price_eur is None
             or car["daily_price_eur"] <= max_daily_price_eur)
    ]
    return {"results": results}


if __name__ == "__main__":
    mcp.run(transport="streamable-http", host="0.0.0.0", port=8765)
```

```bash
pip install fastmcp
python cars_mcp.py
```

The docstring is not decoration — the agent's model reads it to decide how to call the tool. See [Connecting tools](/agents/guides/connecting-tools.md).

## 3. Write the agent config

The agent config is what the agent *does*: which model it uses, which content it loads, and which tool servers it connects to. It references the content you created by name and pins exact versions. `agent-config.yaml`:

```yaml
runtime:
  api_key: ${AGENT_API_KEY}
interactive_platform:
  public_key: ${INTERACTIVEAI_PUBLIC_KEY}
  secret_key: ${INTERACTIVEAI_SECRET_KEY}
llms:
  default: anthropic/claude-haiku-4.5
  api_key: ${ROUTER_API_KEY}

context:
  system_prompt:
    id: system-prompt
    version: 1

  language: match_user

  greeting: "Hi! I'm Mercedes from DriveAway — how can I help you with your car rental today?"

  preamble:
    examples:
      - "Let me check."
      - "One moment."

  routines:
    - id: car-search
      version: 1

  policies:
    - id: stay-on-topic
      version: 1

mcps:
  - id: cars
    hostname: https://cars-mcp.example.com
    port: 443
    transport: streamable-http
```

Things to notice:

* This file is the **`agent_config`** block — the agent's identity (name, agent type, runtime version, secrets, endpoint) is passed as CLI flags in step 4, not written here. (The [manifest reference](/agents/reference/manifest.md) documents the full object; the CLI splits it into config-file + flags.)
* Every secret is a `${VAR}` env-ref — the platform supplies the value at deploy time from the secret bundle; literal secrets are rejected.
* `context.*` entries reference the content you authored in step 1 by name and pin an exact version.
* `mcps[].hostname` is where the running agent reaches your tool server.
* `iai agents schema --schema-version 5.0.0` prints the full config schema.

## 4. Deploy the agent

Create the secret bundle carrying the four `${VAR}` values the config references:

```bash
iai secrets create driveaway-secrets \
  --data AGENT_API_KEY=devsecret \
  --data ROUTER_API_KEY=your-interactiveai-router-key \
  --data INTERACTIVEAI_PUBLIC_KEY=your-public-key \
  --data INTERACTIVEAI_SECRET_KEY=your-secret-key
```

Then create the agent. `--id` is the agent **type** from the marketplace (`interactive-agent`); `--version` is the runtime image version (run `iai agents catalog` to list available versions); `--endpoint` exposes a URL you can reach:

```bash
iai agents create driveaway-demo \
  --id interactive-agent \
  --version <runtime-version> \
  --file agent-config.yaml \
  --secret driveaway-secrets \
  --endpoint
```

The platform validates the config, fetches the pinned content, connects your tool server, and starts the agent. On first deploy it also runs [startup evaluation](/agents/concepts/startup-evaluation.md) (model calls — a minute or two for this one routine); the agent becomes reachable once that settles, and subsequent deploys reuse the evaluation cache.

To change anything later — new content versions, a different model, a runtime upgrade — edit and re-run with `iai agents update driveaway-demo --file agent-config.yaml` (or `--version <new>` for a runtime upgrade). Check progress and the assigned URL with `iai agents describe driveaway-demo`.

## 5. Talk to it

### Through the chat UI

With `--endpoint`, the agent is exposed at a URL like `https://driveaway-demo-<project-hash>.interactive.ai` (read the exact one from `iai agents describe driveaway-demo`). The built-in **chat UI** is that URL with `/chat` appended:

```
https://driveaway-demo-<project-hash>.interactive.ai/chat
```

Open it in a browser, sign in with the agent API key when prompted (the UI sets a cookie so its own requests authenticate), and chat with Mercedes directly — the fastest way to try the agent without writing code.

### Through the SDK

For a real integration, reach the agent over the SDK at the same endpoint URL, authenticating with the `AGENT_API_KEY`:

```bash
pip install "interactiveai[agent]"
```

`chat.py`:

```python
import asyncio
import os

from interactiveai.agent import (
    AssistantMessage,
    InteractiveAgentClient,
    Preamble,
    StatusEvent,
)


async def main() -> None:
    async with InteractiveAgentClient(
        base_url=os.environ["AGENT_URL"],
        api_key=os.environ["AGENT_API_KEY"],
    ) as client:
        sess = await client.sessions.open(id="quickstart-user")
        await sess.post_user_message("I need an automatic SUV for 5 people")

        async for ev in sess.events():
            if isinstance(ev, Preamble):
                print(f"mercedes (working): {ev.text}")
            elif isinstance(ev, AssistantMessage):
                print(f"mercedes: {ev.text}")
            elif isinstance(ev, StatusEvent) and ev.status == "ready":
                break


asyncio.run(main())
```

```bash
AGENT_URL=https://driveaway-demo-<project-hash>.interactive.ai \
  AGENT_API_KEY=devsecret python chat.py
```

Either way you should see the greeting, possibly a short preamble while the search tool runs, and a reply quoting the Volvo XC60 at 95 EUR/day. Try `"what's the meaning of life?"` to watch the stay-on-topic policy fire.

## 6. What just happened

1. `iai agents create` submitted your config; the platform resolved the `${VAR}` secrets from `driveaway-secrets` and loaded the prompt, routine, and policy from the catalog at their pinned versions.
2. The agent connected to your MCP server and catalogued `cars:search_cars`.
3. Your message activated the `car-search` routine (its condition matched); the engine walked chat → tool → chat across the turns, matching the policy set on every turn. The full mechanics: [Conversation lifecycle](/agents/concepts/conversation-lifecycle.md).

## Where to go next

| Goal                                                   | Guide                                                                            |
| ------------------------------------------------------ | -------------------------------------------------------------------------------- |
| Richer flows: branching, multi-tool                    | [Authoring routines](/agents/guides/authoring-routines.md)                       |
| More behaviour rules                                   | [Authoring policies](/agents/guides/authoring-policies.md)                       |
| Integrate your tools / other providers' tools over MCP | [Connecting tools](/agents/guides/connecting-tools.md)                           |
| A real channel (web, Zendesk, Slack)                   | [Integrating the SDK](/agents/guides/integrating-the-sdk.md)                     |
| Typed backend automations                              | [Authoring autonomous routines](/agents/guides/authoring-autonomous-routines.md) |
| Ground answers in documents                            | [Setting up the knowledge base](/agents/guides/knowledge-base-setup.md)          |
| The full platform deploy lifecycle                     | [Deploying](/agents/guides/deploying.md)                                         |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.interactive.ai/agents/guides/quickstart.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
