# Connect an agent

There are two ways in. MCP is the main one: your agent calls Voxoria as a set of tools. The REST API is the alternative for your own code.

## Over MCP

Add the Voxoria server to Claude Code:

```bash
claude mcp add --transport http voxoria https://mcp.voxoria.ai
```

The server address is `https://mcp.voxoria.ai` and the transport is HTTP. Other agents that speak MCP take the same address.

## Over REST

Send your API key as a bearer token.

```bash
curl https://api.voxoria.ai/v1/ping \
  -H "Authorization: Bearer $VOXORIA_API_KEY"
```

See [Account and API key](/docs/get-started) for how to create one.

## What an agent can do today

Today a key can do three things:

- `GET /v1/ping`: confirm the key works and see which workspace it acts for.
- `GET /v1/tools`: list the tools and what each takes and returns.
- `POST /v1/tools/{tool}/calls`: call a live tool, such as `google.serp.organic`. A call draws on your balance.

Six tools are live: Google search results (web, news, maps, local and shopping) and the content of any page. The other tools in the [catalog](/catalog), scheduled checks and history are not open yet.

## Retry a call safely

A connection can drop after a call has been charged and before your agent has the answer. If the agent then sends the call again, that is a second call and a second charge. To avoid that, send an `Idempotency-Key` header with the call:

```bash
curl https://api.voxoria.ai/v1/tools/google.serp.organic/calls \
  -H "Authorization: Bearer $VOXORIA_API_KEY" \
  -H "Idempotency-Key: weekly-report-2026-10-12-step-3" \
  -H "Content-Type: application/json" \
  -d '{"input": {"query": "crm for small teams", "country": "gb"}}'
```

The key is any text you choose, up to 128 printable ASCII characters. Use one key for one call, and send the same key each time you retry it.

- **The first call succeeded.** A retry within 24 hours returns that call with the header `Idempotent-Replayed: true`. No provider is called and you are not charged again. The `cost` in the response is what the first call cost.
- **The first call failed.** Its key is free again, so a retry makes a new call.
- **The first call is still running.** A retry answers 409 with the code `IDEMPOTENCY_KEY_IN_PROGRESS`. Wait a moment and retry with the same key. If the call was cut off on our side, we close it within 15 minutes and the key is free again.
- **The key comes with a different request.** A key belongs to the tool and body it was first sent with. Anything else answers 422 with the code `IDEMPOTENCY_KEY_REUSED`.

Without the header, every request is a new call, even when two requests are identical. That is deliberate: asking twice is how you get fresh results.

## Errors

- **401**: the key is missing, wrong or revoked.
- **403**: the key's scope does not allow the endpoint.