# Agent quickstart

Generate an agent, register it, connect it over the relay, and message it from the terminal.

Source: https://anywe.dev/docs/guides/quickstart

Put a working agent in your own contact list, from a terminal, in about ten minutes. You will generate an agent, register it, connect it over the relay, and message it.

**The path:** Generate (anywe init) -> Register (anywe agent create) -> Credential (anywe agent secret) -> Connect (anywe listen --relay) -> Message (anywe agent test)

**Before you start**

- Go 1.24 or later. `anywe init` writes a Go agent, the only language it generates today, and the agent builds with no dependencies. There is no Python or Node generator and no published package for either yet. If you are not using Go, the platform only needs an endpoint that verifies the signature and replies asynchronously: see [Integrate an existing service](/docs/guides/existing-service-integration), and the [SDK helpers](/docs/tooling/sdks), which sign and verify in TypeScript and Python from a checkout.
- An Anywe account, the same one you use in the app.

## Prepare the CLI

**Install the CLI**

```sh
curl -fsSL https://cli.anywe.dev/install.sh | sh
```

The installer covers macOS and Linux on `amd64` and `arm64` and verifies the download against the published checksums. To build from source instead, see the [CLI reference](/docs/tooling/cli#build-from-source).

**Sign in**

```sh
anywe login --browser
```

A browser window opens; the terminal waits for it. On a server, in a container or in CI there is no browser, so sign in by emailed code in two steps:

```sh
anywe login --email you@example.test
anywe login --email you@example.test --code 123456
```

The first command sends a six-digit code. On a terminal it then waits for you to type it; with no terminal on stdin it prints the second command and exits. The second command checks the code and never sends one. Confirm the session:

```sh
anywe whoami
```

**Create a publisher**

```sh
anywe publisher create --name "Your Name"
```

Agents belong to a publisher, not to a user. One publisher is enough; if you skip this step, `anywe agent create` stops and tells you to run it.

## Register the agent

**Generate the agent**

```sh
anywe init hello-agent
cd hello-agent && go build ./...
```

`anywe init` writes a complete agent: an HTTP server that verifies every delivery's signature, acknowledges inside the platform's ten-second budget, and answers on its own goroutine. The only file you will edit later is `agent.go`.

**Register it**

```sh
anywe agent create --handle hello-agent
```

No `--webhook` is needed: this agent will be reached over the relay, and the CLI fills in a placeholder address that is never dialed while the relay is connected. The output ends with a reminder that the agent has no credential yet. That is the next step.

An account can own three agents. At three, `anywe agent create` stops with `account_agent_limit_reached`. To free a slot, delete an agent you own by naming its handle back, or add `--yes` to skip that:

```sh
anywe agent delete agt_01ARZ3NDEKTSV4RRFFQ69G5FAV hello-agent
```

Deleting withdraws the agent for good: its handle stays reserved, and conversations keep its past messages. Only the agent's owner can delete it.

**Issue its credential**

```sh
anywe agent secret agt_01ARZ3NDEKTSV4RRFFQ69G5FAV
```

Use the `agt_` id the previous step printed. The secret is shown exactly once and no command returns it again. The command prints `export` lines; paste them into your shell, or into a file you `source`. CLI v0.2.0 prints them as `AICONNECT_AGENT_ID`, `AICONNECT_CREDENTIAL_ID` and `AICONNECT_AGENT_SECRETS`, the names an agent it generated reads; later releases print both sets:

```sh
export ANYWE_AGENT_ID=agt_01ARZ3NDEKTSV4RRFFQ69G5FAV
export ANYWE_CREDENTIAL_ID=cred_01ARZ3NDEKTSV4RRFFQ69G5FAV
export ANYWE_AGENT_SECRETS=the-secret-printed-once
```

> **Registering does not issue a credential** They are separate calls. Until `anywe agent secret` runs, every delivery fails with `agent has no currently-valid credential`. It looks like a connection problem and is not one.

## Prove the loop

Three terminals: the agent, the relay, and you.

**One delivery, end to end:** You (anywe agent test) -> Platform (delivery queued) -> Relay (anywe listen) -> Your agent (ack, then Answer()) -> Platform (reply stored) -> You (reply printed)

**Start the agent**

In the `hello-agent` directory, with the three variables exported:

```sh
go run .
```

It listens on port 9092 and serves `POST /webhook`, which is why the relay below forwards to that path. If something else already holds 9092, pick another port with `AGENT_LISTEN` and use the same port in the relay's `--forward-to`:

```sh
AGENT_LISTEN=:19092 go run .
```

**Connect it over the relay**

In a second terminal, with the same three variables exported:

```sh
anywe listen --relay --forward-to http://localhost:9092/webhook
```

The relay holds an outbound connection to the platform and forwards deliveries to your local process. No public DNS, no inbound port, no tunnel. Close this terminal and the agent is offline; the platform sees that directly rather than inferring it from failed deliveries.

**Message it**

In a third terminal:

```sh
anywe agent test "$ANYWE_AGENT_ID" "Hello from the terminal"
```

This creates a real conversation, sends the message, and waits for the reply. It is the same path a user takes from the app. The reply is asynchronous: the platform acknowledges the delivery within ten seconds, and the agent answers afterwards. If nothing arrives before the timeout, the command reads the delivery log and prints the status and last error, so the reason is on screen rather than in a log file.

Open the app and the conversation you just started is in your inbox. The agent is private by default, so only you can message it for now.

## When something does not work

```sh
anywe check --agent-id "$ANYWE_AGENT_ID"
anywe logs "$ANYWE_AGENT_ID" --follow
```

`anywe check` confirms the platform is reachable and the credential is valid, and needs no account for its local checks. A relay-connected agent publishes no endpoint, so `check` does not probe one; for that, `anywe logs --follow` is the command with the answer. It shows each delivery's status and last error as it happens, including `relay_not_connected` when the `anywe listen` terminal is closed.

Do not register a `localhost` address as a webhook to work around the relay: deliveries carry conversation content, and the platform refuses non-HTTPS endpoints for that reason.

## Circuit breaker

After five consecutive failed deliveries to one agent, the platform stops dispatching to it for about a minute, and `anywe logs` shows `breaker open: ... retrying automatically until <time>` on the waiting deliveries. That is a pause, not a fault to fix: repair whatever was failing (a wrong `--forward-to` path is the usual one, and the relay prints each delivery's status, so a `404` there names it), wait for the time in that line, and the queued deliveries go out on their own. A `429` from your agent does not count toward the five.

## Next steps

**Make it yours.** `agent.go` is one function. It runs after the platform has been acked, so it may take as long as a language model needs:

```go
func Answer(ctx context.Context, question string, locale string) (string, error) {
	if strings.TrimSpace(question) == "" {
		return "", errors.New("empty message")
	}
	return "You said: " + question, nil
}
```

`locale` is the user's language tag (`vi`, `en`), passed on every delivery, so answering in their language costs one comparison. Return an error to send nothing; the failure is logged.

- **Reply with blocks.** You receive `text` and send `blocks`; the [reply workflows guide](/docs/guides/reply-workflows) covers cards, tables and forms, and the [block reference](/docs/interactions/reference) lists every type.
- **Ship it on a server.** For an agent with its own HTTPS endpoint, register a real `--webhook` and verify each delivery as the [request-signing reference](/docs/api/security-signing) describes.
- **Let others message it.** Change the access policy with `anywe agent policy`; see the [CLI reference](/docs/tooling/cli).
