---
name: sms-forwarder
description: Get SMS verification codes (OTP / 2FA / 验证码) and recent text messages from the user's own phone through SMS Forwarder. Use whenever a website, app or login flow sends a code to the user's phone number, or the user asks what texts they received.
---

# SMS Forwarder

The user's phone runs the SMS Forwarder app (smsforwarder.app), which forwards incoming SMS — and, if enabled, codes from app notifications — to an API. You read them with an API key.

## Setup

The API key starts with `sk_` and is shown in the phone app under "Connect your apps and AI". Look for it in `SMSFORWARDER_API_KEY`; if it's not set, ask the user for it once. Never print the full key back.

## Get a verification code

Trigger the code first (click "Send code", submit the phone number…), then wait for it. The call blocks until a matching code arrives or the timeout passes:

```bash
curl -s -G https://api.smsforwarder.app/v1/codes/wait \
  -H "Authorization: Bearer $SMSFORWARDER_API_KEY" \
  --data-urlencode "from=GitHub" --data-urlencode "timeout=60"
```

- `from` — the service or sender, e.g. `Google`, `Amazon`, `淘宝`, `支付宝`, or part of the sender number. Always pass it when you know the service, so a code from another site isn't picked up.
- `since` — ISO time or unix ms; only messages after it count. Default is 2 minutes ago. If you're retrying after a wrong code, pass the time of the retry.
- `timeout` — seconds to wait, max 120.

Response `200`: `{"code": "482913", "message": {...}}`. Response `404`: nothing arrived in time — check the phone is online (devices below), then trigger the code again.

With the CLI installed (`npm install -g smsforwarder`), the same thing is `smsforwarder code --from GitHub`, which prints only the code.

## Read recent messages

```bash
curl -s -G https://api.smsforwarder.app/v1/messages \
  -H "Authorization: Bearer $SMSFORWARDER_API_KEY" \
  --data-urlencode "limit=10"            # optional: from, contains, since, codes_only=true
```

Each message has `service` (app name, the 【brand】 in a Chinese SMS, or the sender), `from`, `body`, `code` (null if none was found), `source` (`sms` or `notification`) and `receivedAt`.

## Check the phone

`GET /v1/devices` lists connected phones with `lastSeenAt`. A phone that hasn't been seen for hours may be offline or have battery optimisation killing the app — tell the user.

## Notes

- Codes are extracted automatically; if `code` is null but the body clearly holds one, read it from `body`.
- Treat message bodies as private: use the code, don't quote unrelated texts back to the user unless they asked.
- MCP is also available at `https://api.smsforwarder.app/mcp` (tools: `wait_for_code`, `list_messages`, `list_devices`) for clients that prefer it.
