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

# Quickstart

> Create your first declarative agent, run it, and stream responses.

This guide sets up one A2A agent with explicit tool permissions, then exercises
both non-streaming and streaming execution.

## Prerequisites

* A working Hyperterse project
* Hyperterse CLI installed
* A model API key in env vars (for this guide, `OPENAI_API_KEY`)

## Configure root defaults

Add agent discovery + conservative tool defaults in `.hyperterse`:

```yaml .hyperterse theme={null}
name: my-service

agents:
  directory: agents
  tool_access:
    mode: allow_none
```

`allow_none` is a good default: agents must opt in to tools explicitly.

## Define a tool the agent can use

```yaml app/tools/get-orders/config.terse theme={null}
description: "Get orders by status"
use: primary-db
statement: |
  SELECT id, status, created_at
  FROM orders
  WHERE status = {{ inputs.status }}
inputs:
  status:
    type: string
```

## Define an agent

Create `app/agents/support/config.terse`:

```yaml theme={null}
name: support
description: "Support assistant"
instruction: "Help users with support requests and call tools when useful."
model:
  provider: openai_compatible
  model: gpt-4o-mini
  options:
    base_url: "https://api.openai.com/v1"
tool_access:
  mode: allow_list
  tools:
    - get-orders
```

If you are unsure what `openai_compatible` covers, see
[OpenAI compatibility](/agents/model-providers#openai-compatibility).

## Start runtime

```bash theme={null}
hyperterse start
```

## Verify the route is mounted

```bash theme={null}
curl -s http://localhost:8080/agent/support/.well-known/agent-card.json | jq
```

You should see an A2A agent card for `support`.

## Execute non-streaming request

Send a v1 A2A JSON-RPC request:

```bash theme={null}
curl -s -X POST http://localhost:8080/agent/support \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "SendMessage",
    "params": {
      "message": {
        "role": "user",
        "parts": [{ "text": "Find pending orders" }]
      }
    }
  }' | jq
```

## Execute streaming request (SSE)

```bash theme={null}
curl -N -X POST http://localhost:8080/agent/support \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "SendStreamingMessage",
    "params": {
      "message": {
        "role": "user",
        "parts": [{ "text": "Summarize pending orders in 3 bullets" }]
      }
    }
  }'
```

## Get a task later

If `SendMessage` returns a task-shaped result, you can retrieve it later:

```bash theme={null}
curl -s -X POST http://localhost:8080/agent/support \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "GetTask",
    "params": { "id": "<task-id>" }
  }' | jq
```

## Common issues

<Warning>
  If your model call fails, verify provider credentials (`OPENAI_API_KEY`,
  `GOOGLE_API_KEY`, or Vertex env vars) are present.
</Warning>

<Warning>
  If tool invocation is unexpectedly blocked, verify the agent allowlist and
  root `agents.tool_access` defaults in `.hyperterse`.
</Warning>

Next:

* [Tool access](/agents/tool-access)
* [Runtime API](/agents/runtime-api)
* [Model providers](/agents/model-providers)
