# nmbr agent template **Text your Mac mini in 10 minutes.** A reference agent for the [nmbr Agent API](https://nmbr.ai/developers/docs/): give an AI agent running on your own hardware an `800-xxx-xxx` nmbr and talk to it from the nmbr app. No public URL, no bot platform in the middle. Four small programs, each one file, on [`@nmbrai/sdk`](https://www.npmjs.com/package/@nmbrai/sdk) (zero other dependencies): | | | |---|---| | `npm run echo` | The smallest agent: repeats what you say. Start here. | | `npm run agent` | A personal assistant: any OpenAI-compatible model (OpenAI, Ollama, LM Studio, OpenRouter…), per-chat memory. | | `npm run approvals` | Human-in-the-loop: propose an action, wait for **Approve / Edit / Reject** on the phone, act only on approval. | | `npm run webhook` | Receive events by signed webhook instead of long-poll (needs a public https URL). | ## Setup 1. In the nmbr app: **Agents → Yours → Create an agent**. Copy the token (shown once). 2. ```bash git clone my-agent && cd my-agent npm install cp .env.example .env # paste NMBR_AGENT_TOKEN (and LLM_* for the assistant) npm run echo ``` 3. Open the chat with your agent in nmbr and say something. Node ≥ 20 (uses `--env-file`). Runs anywhere with outbound internet — a laptop behind NAT is fine. ## How it works - **Inbound** is a long-poll: `agent.updates()` holds a request open up to 25 s and yields events (`message.received`, `contact.added`, `action.*`) in order, resuming after errors. Nothing has to be reachable from the internet. - **Outbound** is `agent.sendText({ conversationId }, text)` (or `{ to: "123-456-789" }`); `setTyping` shows the indicator while you think. - **Approvals**: `agent.proposeAndWait({...})` resolves with the terminal action. `approved` may carry `editedPayload` — use it. `rejected` and `expired` both mean *don't*. - **Voice notes** arrive with `message.transcript` already filled in; the template feeds that to the model. ## Make it yours Replace the body of the `for await` loop in `src/agent.mjs`. Keep two habits from the template: treat everything the user sends as untrusted input (prompt injection is real — see [Security](https://nmbr.ai/developers/docs/security/)), and put anything consequential behind a proposal. ## Who can talk to it Only people who add your agent as a contact — nmbr enforces that server-side. Control it with the agent's *who can add* setting in the app (`everyone`, `contacts of contacts`, `nobody`). Docs: https://nmbr.ai/developers/docs/ · Spec: https://nmbr.ai/developers/openapi.yaml · Questions: support@nmbr.ai