# Connect LlamaIndex agents to a NZ phone number, SMS and email

**Short answer:** Install llama-index-tools-mcp, create a BasicMCPClient for https://agentline.nz/mcp with your Agentline NZ API key in an Authorization: Bearer header, and pass McpToolSpec(client=client).to_tool_list_async() to a FunctionAgent. The agent can then text from a New Zealand 028 number, use an @agentline.nz inbox and wait for one-time codes.

## Before you start

- An Agentline NZ API key from Dashboard → API keys, exported as AGENTLINE_KEY. No credit card needed to sign up. Start free with an email inbox, or take a 7-day trial of Starter or Pro to get a number.
- Your 028 number is set up within a few days of signup. Your email inbox works straight away.
- An LLM for the agent. The example uses OpenAI, with OPENAI_API_KEY set; any LlamaIndex LLM that supports tool calling works.

## Steps

1. **Install the MCP tools package.** llama-index-tools-mcp brings in llama-index-core. Install the LLM package you want as well.

   ```bash
   pip install llama-index-tools-mcp llama-index-llms-openai
   ```

2. **Connect and build the agent.** A URL that doesn't end in /sse selects Streamable HTTP. headers is sent with every request, and timeout is in seconds.

   ```python
   import asyncio, os
   from llama_index.core.agent.workflow import FunctionAgent
   from llama_index.llms.openai import OpenAI
   from llama_index.tools.mcp import BasicMCPClient, McpToolSpec

   async def main():
       client = BasicMCPClient(
           "https://agentline.nz/mcp",
           headers={"Authorization": f"Bearer {os.environ['AGENTLINE_KEY']}"},
           timeout=60,
       )
       tools = await McpToolSpec(client=client).to_tool_list_async()
       agent = FunctionAgent(
           name="Assistant",
           description="Texts, emails and reads one-time codes with Agentline NZ.",
           tools=tools,
           llm=OpenAI(model="gpt-4o"),
           system_prompt="Use Agentline NZ to text, email and wait for one-time codes.",
       )
       print(await agent.run("What's my Agentline NZ number?"))

   asyncio.run(main())
   ```

3. **Run it.** Run the script. The agent should call get_my_number and print your number and inbox.

## Limit the agent to some tools

Pass `allowed_tools` to keep an agent read-only, for example:

```python
spec = McpToolSpec(
    client=client,
    allowed_tools=["get_my_number", "list_messages", "list_emails", "read_email", "wait_for_code"],
)
```

The sending tools are `send_sms` and `send_email`. `wait_for_code` doesn't send anything, but it isn't strictly read-only: it consumes each code it returns, so the code isn't returned again.

## Using the REST API instead

If you'd rather not use MCP, wrap a few REST calls as `FunctionTool`s. The API is at `https://agentline.nz/api/v1` with the same `Authorization: Bearer` header:

```python
import os, httpx
from llama_index.core.tools import FunctionTool

API = "https://agentline.nz/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['AGENTLINE_KEY']}"}

def send_sms(to: str, body: str) -> dict:
    """Text a New Zealand mobile number, such as 021 123 4567, from the Agentline NZ 028 number."""
    return httpx.post(f"{API}/sms", headers=HEADERS, json={"to": to, "body": body}).json()

def list_inbound_sms(limit: int = 20) -> dict:
    """List received texts, newest first."""
    return httpx.get(f"{API}/sms", headers=HEADERS, params={"direction": "in", "limit": limit}).json()

def wait_for_code(channel: str = "any", timeout_seconds: int = 45) -> dict:
    """Wait for a one-time code to arrive by SMS or email. channel is sms, email or any."""
    return httpx.post(
        f"{API}/wait-for-code",
        headers=HEADERS,
        json={"channel": channel, "timeout_seconds": timeout_seconds},
        timeout=60,
    ).json()

tools = [FunctionTool.from_defaults(fn) for fn in (send_sms, list_inbound_sms, wait_for_code)]
```

`POST /sms` returns `{"message": {…}}`, `GET /sms` returns `{"messages": [...]}`, and `POST /wait-for-code` returns `{"found": true, "code": "…", …}` or `{"found": false}`. Errors come back as `{"error": {"code": "…", "message": "…"}}`, which the agent can read. The [docs](/docs) list every endpoint.

## Good to know

- Keep timeout at 60 seconds or more. wait_for_code can wait up to 55 seconds, and BasicMCPClient's default is 30.
- Until you're on a paid plan, your agent can only email or text your own verified email address and mobile number. Anything else returns recipient_not_allowed.
- Standard NZ mobile numbers only (020/021/022/027/028/029). No landlines, short codes, premium or international numbers.
- BasicMCPClient opens a new session for each call, so you don't need to close it.

## FAQ

### Can I use aget_tools_from_mcp_url instead?

Yes. Pass the same BasicMCPClient as client, for example await aget_tools_from_mcp_url('https://agentline.nz/mcp', client=client). It returns the same tool list as McpToolSpec and also takes allowed_tools.

### What does Agentline NZ cost?

Starter is NZ$29/month and Pro is NZ$79/month, billed in NZ dollars. No credit card needed to sign up. Start free with an email inbox, or take a 7-day trial of Starter or Pro to get a number. Agentline NZ is not GST-registered, so no GST is charged.

### How long does it take to get the 028 number?

Your 028 number is set up within a few days of signup. Your email inbox works straight away. Full refund if your number hasn't arrived within 30 days of your first payment.

### Can my assistant send marketing or bulk texts?

No. Transactional and assistant messages only: replies, bookings, confirmations, reminders people asked for, and codes. Marketing, promotions, cold texts and bulk texts are blocked. See [What we don't allow](/what-we-dont-allow).

## Related

- [Connect LangChain and LangGraph agents to a NZ phone number, SMS and email](/integrations/langchain)
- [Connect the OpenAI Agents SDK to a NZ phone number, SMS and email](/integrations/openai-agents-sdk)
- [How does wait_for_code get one-time codes for my agent?](/help/how-wait-for-code-works)
- [How do I create an Agentline NZ API key?](/help/how-to-create-an-api-key)

[Start free](https://agentline.nz/signup) · No credit card needed to sign up. Start free with an email inbox, or take a 7-day trial of Starter or Pro to get a number.
