aitextaroo 0.1.2__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aitextaroo-0.2.0/PKG-INFO +227 -0
- aitextaroo-0.2.0/README.md +194 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/aitextaroo/__init__.py +1 -1
- aitextaroo-0.2.0/aitextaroo/agent_cli.py +268 -0
- aitextaroo-0.2.0/aitextaroo/agents.py +381 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/aitextaroo/bridge.py +3 -1
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/aitextaroo/cli.py +28 -6
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/aitextaroo/client.py +238 -18
- aitextaroo-0.2.0/aitextaroo/credentials.py +76 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/aitextaroo/setup.py +65 -14
- aitextaroo-0.2.0/aitextaroo.egg-info/PKG-INFO +227 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/aitextaroo.egg-info/SOURCES.txt +6 -1
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/aitextaroo.egg-info/entry_points.txt +1 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/pyproject.toml +3 -2
- aitextaroo-0.2.0/tests/test_agent_cli.py +276 -0
- aitextaroo-0.2.0/tests/test_agents.py +288 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/tests/test_bridge.py +40 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/tests/test_client.py +55 -1
- aitextaroo-0.2.0/tests/test_client_replies.py +199 -0
- aitextaroo-0.2.0/tests/test_setup.py +66 -0
- aitextaroo-0.1.2/PKG-INFO +0 -230
- aitextaroo-0.1.2/README.md +0 -197
- aitextaroo-0.1.2/aitextaroo/agents.py +0 -235
- aitextaroo-0.1.2/aitextaroo.egg-info/PKG-INFO +0 -230
- aitextaroo-0.1.2/tests/test_agents.py +0 -107
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/LICENSE +0 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/aitextaroo/commands.py +0 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/aitextaroo/conversation.py +0 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/aitextaroo/formatting.py +0 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/aitextaroo/models.py +0 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/aitextaroo.egg-info/dependency_links.txt +0 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/aitextaroo.egg-info/requires.txt +0 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/aitextaroo.egg-info/top_level.txt +0 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/setup.cfg +0 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/tests/test_commands.py +0 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/tests/test_conversation.py +0 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/tests/test_formatting.py +0 -0
- {aitextaroo-0.1.2 → aitextaroo-0.2.0}/tests/test_models.py +0 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aitextaroo
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Client library for AI Text-a-roo — give any AI agent a phone number
|
|
5
|
+
Author-email: AI Text-a-roo <hello@aitextaroo.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://aitextaroo.com
|
|
8
|
+
Project-URL: Documentation, https://github.com/rwfresh/aitextaroo-clients
|
|
9
|
+
Project-URL: Repository, https://github.com/rwfresh/aitextaroo-clients
|
|
10
|
+
Project-URL: Issues, https://github.com/rwfresh/aitextaroo-clients/issues
|
|
11
|
+
Keywords: sms,ai,agent,chatbot,text-messaging,mcp,agent-skills,claude,chatgpt,codex,openclaw,hermes
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Communications :: Chat
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: httpx>=0.27.0
|
|
26
|
+
Provides-Extra: bridge
|
|
27
|
+
Requires-Dist: pyyaml>=6.0; extra == "bridge"
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
31
|
+
Requires-Dist: ruff>=0.4.0; extra == "dev"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# AI Text-a-roo
|
|
35
|
+
|
|
36
|
+
Give any AI agent a phone number, in about two minutes.
|
|
37
|
+
|
|
38
|
+
[AI Text-a-roo](https://aitextaroo.com) is an SMS gateway for AI agents. You verify your
|
|
39
|
+
phone once; then you can text your agent from any phone (no app), and it can text you back,
|
|
40
|
+
or first, when something needs you. This repo has everything an agent needs to use it: an
|
|
41
|
+
[Agent Skill](skills/aitextaroo/SKILL.md), plugin manifests for Claude, Codex, Cursor and
|
|
42
|
+
Gemini CLI, the `aitextaroo` command, a Python SDK, and an SMS bridge for CLI agents.
|
|
43
|
+
|
|
44
|
+
## Install in your agent
|
|
45
|
+
|
|
46
|
+
| Agent | One step |
|
|
47
|
+
|---|---|
|
|
48
|
+
| Claude Code | `claude plugin install aitextaroo --marketplace rwfresh/aitextaroo-clients`, or in a session `/plugin marketplace add rwfresh/aitextaroo-clients` then `/plugin install aitextaroo@aitextaroo` |
|
|
49
|
+
| Claude, Claude Desktop, Claude Duet | Customize → Plugins → Add marketplace → `rwfresh/aitextaroo-clients`, or Customize → Connectors → Add custom connector → `https://api.aitextaroo.com/mcp` |
|
|
50
|
+
| ChatGPT and Dots | Plugins → + → Add custom MCP server → `https://api.aitextaroo.com/mcp` → OAuth |
|
|
51
|
+
| Codex | `codex plugin marketplace add rwfresh/aitextaroo-clients`, then `codex plugin add aitextaroo@aitextaroo` |
|
|
52
|
+
| Gemini CLI | `gemini extensions install https://github.com/rwfresh/aitextaroo-clients` |
|
|
53
|
+
| Grok Bot | Say: "Add a custom MCP server called AI Text-a-roo at https://api.aitextaroo.com/mcp" |
|
|
54
|
+
| Cursor | Add the MCP server to `~/.cursor/mcp.json` (run `aitextaroo connect cursor`) |
|
|
55
|
+
| Any skills-aware agent | `npx skills add rwfresh/aitextaroo-clients` |
|
|
56
|
+
| Claude Code, Codex, Hermes, OpenClaw, Grok, Gemini, Antigravity, Goose, Cursor (answer texts from your phone) | `pipx install aitextaroo`, then `aitextaroo-bridge` |
|
|
57
|
+
|
|
58
|
+
The plugins bundle the skill and the remote MCP server. They sign in with OAuth: you enter
|
|
59
|
+
your phone number and the 6-digit code we text you, so there's no API key to copy. Setup
|
|
60
|
+
guides for each agent: <https://aitextaroo.com/agents>.
|
|
61
|
+
|
|
62
|
+
Or just tell your agent:
|
|
63
|
+
|
|
64
|
+
> Set me up with AI Text-a-roo so I can text you. Instructions: aitextaroo.com/llms.txt
|
|
65
|
+
|
|
66
|
+
## Quick start from a terminal
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pipx install aitextaroo # or: pip install --user aitextaroo
|
|
70
|
+
aitextaroo-setup --phone +12125551234 # texts you a 6-digit code
|
|
71
|
+
aitextaroo-setup --phone +12125551234 --code 123456 --save # saves the key (owner-only)
|
|
72
|
+
aitextaroo send "Hello from my agent!"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`--save` stores the API key in `~/.aitextaroo/credentials.json` with owner-only permissions.
|
|
76
|
+
`aitextaroo` and `aitextaroo-bridge` find it there, or in `AITEXTAROO_API_KEY`, or in `--api-key`.
|
|
77
|
+
|
|
78
|
+
## The `aitextaroo` command
|
|
79
|
+
|
|
80
|
+
Made for agents with a shell. Output is JSON; errors go to stderr with exit code 1.
|
|
81
|
+
`aitextaroo verify-pin` exits 2 when the PIN is wrong, so `aitextaroo verify-pin <<< 4821 && …`
|
|
82
|
+
only continues on a match. `verify-pin` and `set-pin` read the PIN from stdin when it isn't
|
|
83
|
+
an argument, which keeps it out of shell history and the process list.
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
aitextaroo send "Build finished: 318 tests passing."
|
|
87
|
+
aitextaroo ask "Deploy to production? Reply YES or NO" --timeout 120 # text, then wait for the answer
|
|
88
|
+
aitextaroo wait --timeout 60 # wait for the next text
|
|
89
|
+
aitextaroo recent # texts from the last 5 minutes
|
|
90
|
+
aitextaroo relay --to +12125550100 --name Mom "Happy birthday!" # Pro: text a contact
|
|
91
|
+
aitextaroo verify-pin <<< 4821 # check a PIN the user texted
|
|
92
|
+
aitextaroo set-pin <<< 4821 # set the user's PIN (4-8 digits)
|
|
93
|
+
aitextaroo account
|
|
94
|
+
aitextaroo upgrade # Stripe link for Pro
|
|
95
|
+
aitextaroo webhook set https://example.com/hook --auth-header "Bearer <token>"
|
|
96
|
+
aitextaroo connect [claude-code|codex|gemini|cursor|muse-code|claude|chatgpt|grok]
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## SMS bridge
|
|
100
|
+
|
|
101
|
+
The bridge holds one outbound connection to AI Text-a-roo. Each text you send becomes a
|
|
102
|
+
prompt for a CLI agent on your machine, and its answer is texted back. No webhook, no public
|
|
103
|
+
IP: it works behind NAT, firewalls and VPNs.
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
aitextaroo-bridge # auto-detects an installed agent
|
|
107
|
+
aitextaroo-bridge --agent codex
|
|
108
|
+
aitextaroo-bridge --agent-command "pnpm --silent --dir ~/nanoclaw run chat" # any other CLI
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
| `--agent` | Runs |
|
|
112
|
+
|---|---|
|
|
113
|
+
| `claude` | `claude -p "<prompt>"` |
|
|
114
|
+
| `codex` | `codex exec --skip-git-repo-check --color never -o <file> "<prompt>"` |
|
|
115
|
+
| `hermes` | `hermes -z "<prompt>"` |
|
|
116
|
+
| `openclaw` | `openclaw agent exec "<prompt>"` |
|
|
117
|
+
| `grok` | `grok --no-auto-update -p "<prompt>"` |
|
|
118
|
+
| `gemini` | `gemini -p "<prompt>"` |
|
|
119
|
+
| `antigravity` | `agy -p "<prompt>"` |
|
|
120
|
+
| `goose` | `goose run -q --no-session -t "<prompt>"` |
|
|
121
|
+
| `cursor` | `cursor-agent -p --trust "<prompt>"`, or `agent` if that's all there is (explicit only: Grok Build also installs an `agent` binary, and the bridge refuses it) |
|
|
122
|
+
|
|
123
|
+
Auto-detect tries them in this order. `--agent-command` runs any CLI that takes the prompt
|
|
124
|
+
as its last argument and prints the reply.
|
|
125
|
+
|
|
126
|
+
Conversation history is saved locally in `~/.aitextaroo/sessions/` and survives restarts.
|
|
127
|
+
Text `/help`, `/new` (fresh conversation) or `/status`. Use `--no-persist` for memory-only
|
|
128
|
+
history. Responses are stripped of markdown for SMS.
|
|
129
|
+
|
|
130
|
+
```text
|
|
131
|
+
aitextaroo-bridge [OPTIONS]
|
|
132
|
+
--api-key KEY API key (default: AITEXTAROO_API_KEY or the saved credentials)
|
|
133
|
+
--agent NAME auto, claude, codex, hermes, openclaw, grok, gemini, antigravity, goose, cursor
|
|
134
|
+
--agent-command CMD Any other CLI agent (overrides --agent)
|
|
135
|
+
--sessions-dir PATH Session files (default ~/.aitextaroo/sessions/)
|
|
136
|
+
--no-persist Keep history in memory only
|
|
137
|
+
--base-url URL Custom API URL
|
|
138
|
+
-v, --verbose Debug logging
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Python SDK
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
import asyncio
|
|
145
|
+
from aitextaroo import TextarooClient
|
|
146
|
+
|
|
147
|
+
async def main():
|
|
148
|
+
client = TextarooClient(api_key="YOUR_KEY")
|
|
149
|
+
await client.send("All tests pass. Open a PR? Reply YES or NO.")
|
|
150
|
+
reply = await client.wait_for_reply(timeout_seconds=90)
|
|
151
|
+
print(reply.text if reply else "No answer yet")
|
|
152
|
+
await client.close()
|
|
153
|
+
|
|
154
|
+
asyncio.run(main())
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
| Method | What it does |
|
|
158
|
+
|---|---|
|
|
159
|
+
| `send(text)` | Text the user. Returns the message ID. |
|
|
160
|
+
| `wait_for_reply(timeout_seconds=60)` | Wait up to 120 s for the user's next text (or one that arrived since your last send). Returns an `InboundMessage` or `None`. |
|
|
161
|
+
| `recent_messages(after_id=None)` | Texts from the last five minutes. |
|
|
162
|
+
| `listen()` | Async iterator over inbound texts via SSE, with automatic reconnect and replay. |
|
|
163
|
+
| `text_contact(to, text, recipient_name=None)` | Pro: text someone else; their replies go to the user's phone. |
|
|
164
|
+
| `verify_pin(pin)` | Check a PIN the user texted: `{"verified": bool, "attempts_remaining": int \| None}`. |
|
|
165
|
+
| `set_pin(pin)` / `remove_pin()` | Set, change or remove the user's security PIN (4–8 digits). |
|
|
166
|
+
| `set_webhook(url, auth_header=None)` / `remove_webhook()` | Forward inbound texts to a URL (signed with `X-Signature`). |
|
|
167
|
+
| `account()` | Plan, assigned number, usage and daily limit. |
|
|
168
|
+
| `upgrade_link()` | Stripe checkout link for Pro. |
|
|
169
|
+
| `TextarooClient.request_verification(phone)` / `confirm_verification(phone, code)` | Sign-up, no key needed. |
|
|
170
|
+
|
|
171
|
+
`InboundMessage` has `id`, `text`, `received_at`, `channel` (`"sms"`), `trust_level` and
|
|
172
|
+
`has_pin`. See [`examples/`](examples/) for an echo bot, a listener and an ask-and-wait flow.
|
|
173
|
+
|
|
174
|
+
## MCP server
|
|
175
|
+
|
|
176
|
+
`https://api.aitextaroo.com/mcp` (streamable HTTP). Tools: `send_text`, `wait_for_reply`,
|
|
177
|
+
`get_recent_messages`, `text_contact`, `verify_pin`, `get_account`, `get_upgrade_link`.
|
|
178
|
+
Clients sign in with OAuth, or send `Authorization: Bearer <API key>`:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
claude mcp add --transport http --scope user aitextaroo https://api.aitextaroo.com/mcp \
|
|
182
|
+
--header "Authorization: Bearer $AITEXTAROO_API_KEY"
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Run `aitextaroo connect` for every client's exact setup. Reference: <https://aitextaroo.com/docs/mcp>.
|
|
186
|
+
|
|
187
|
+
## Plans
|
|
188
|
+
|
|
189
|
+
| | Free ($0) | Pro ($5/mo, 14-day free trial) |
|
|
190
|
+
|---|---|---|
|
|
191
|
+
| Messages per day | 10 | 200 |
|
|
192
|
+
| Two-way texting, MCP, skill, SDK, bridge | ✓ | ✓ |
|
|
193
|
+
| Security PIN | ✓ | ✓ |
|
|
194
|
+
| Text your contacts, with replies forwarded | | ✓ |
|
|
195
|
+
|
|
196
|
+
Up to 5 texts per minute. Limits reset at midnight UTC.
|
|
197
|
+
|
|
198
|
+
## Privacy and security
|
|
199
|
+
|
|
200
|
+
- Message content is never written to AI Text-a-roo's database. Texts are held in memory
|
|
201
|
+
for at most five minutes so an agent can catch up after a dropped connection.
|
|
202
|
+
- Phone numbers are encrypted at rest; PINs are stored as bcrypt hashes.
|
|
203
|
+
- The bridge's history and the saved credentials live only on your machine.
|
|
204
|
+
- SMS isn't end-to-end encrypted, and sender IDs can be spoofed. The bridge tells every agent
|
|
205
|
+
to ask for your PIN before anything sensitive, because some CLIs (for example `hermes -z`)
|
|
206
|
+
auto-approve their own tool calls in one-shot mode. Run the bridge with an agent whose
|
|
207
|
+
permissions you're comfortable exposing to your phone number.
|
|
208
|
+
|
|
209
|
+
Details: <https://aitextaroo.com/security>.
|
|
210
|
+
|
|
211
|
+
## Environment variables
|
|
212
|
+
|
|
213
|
+
| Variable | Description |
|
|
214
|
+
|---|---|
|
|
215
|
+
| `AITEXTAROO_API_KEY` | API key (alternative to `--api-key` and the saved credentials) |
|
|
216
|
+
| `AITEXTAROO_BASE_URL` | Custom API URL |
|
|
217
|
+
|
|
218
|
+
## Releasing
|
|
219
|
+
|
|
220
|
+
Bump `version` in `pyproject.toml` and `__version__` in `aitextaroo/__init__.py`, merge to
|
|
221
|
+
`main`, then push a matching tag: `git tag v0.2.1 && git push origin v0.2.1`. The
|
|
222
|
+
[Release workflow](.github/workflows/release.yml) tests, builds and publishes to PyPI with
|
|
223
|
+
Trusted Publishing.
|
|
224
|
+
|
|
225
|
+
## License
|
|
226
|
+
|
|
227
|
+
MIT
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# AI Text-a-roo
|
|
2
|
+
|
|
3
|
+
Give any AI agent a phone number, in about two minutes.
|
|
4
|
+
|
|
5
|
+
[AI Text-a-roo](https://aitextaroo.com) is an SMS gateway for AI agents. You verify your
|
|
6
|
+
phone once; then you can text your agent from any phone (no app), and it can text you back,
|
|
7
|
+
or first, when something needs you. This repo has everything an agent needs to use it: an
|
|
8
|
+
[Agent Skill](skills/aitextaroo/SKILL.md), plugin manifests for Claude, Codex, Cursor and
|
|
9
|
+
Gemini CLI, the `aitextaroo` command, a Python SDK, and an SMS bridge for CLI agents.
|
|
10
|
+
|
|
11
|
+
## Install in your agent
|
|
12
|
+
|
|
13
|
+
| Agent | One step |
|
|
14
|
+
|---|---|
|
|
15
|
+
| Claude Code | `claude plugin install aitextaroo --marketplace rwfresh/aitextaroo-clients`, or in a session `/plugin marketplace add rwfresh/aitextaroo-clients` then `/plugin install aitextaroo@aitextaroo` |
|
|
16
|
+
| Claude, Claude Desktop, Claude Duet | Customize → Plugins → Add marketplace → `rwfresh/aitextaroo-clients`, or Customize → Connectors → Add custom connector → `https://api.aitextaroo.com/mcp` |
|
|
17
|
+
| ChatGPT and Dots | Plugins → + → Add custom MCP server → `https://api.aitextaroo.com/mcp` → OAuth |
|
|
18
|
+
| Codex | `codex plugin marketplace add rwfresh/aitextaroo-clients`, then `codex plugin add aitextaroo@aitextaroo` |
|
|
19
|
+
| Gemini CLI | `gemini extensions install https://github.com/rwfresh/aitextaroo-clients` |
|
|
20
|
+
| Grok Bot | Say: "Add a custom MCP server called AI Text-a-roo at https://api.aitextaroo.com/mcp" |
|
|
21
|
+
| Cursor | Add the MCP server to `~/.cursor/mcp.json` (run `aitextaroo connect cursor`) |
|
|
22
|
+
| Any skills-aware agent | `npx skills add rwfresh/aitextaroo-clients` |
|
|
23
|
+
| Claude Code, Codex, Hermes, OpenClaw, Grok, Gemini, Antigravity, Goose, Cursor (answer texts from your phone) | `pipx install aitextaroo`, then `aitextaroo-bridge` |
|
|
24
|
+
|
|
25
|
+
The plugins bundle the skill and the remote MCP server. They sign in with OAuth: you enter
|
|
26
|
+
your phone number and the 6-digit code we text you, so there's no API key to copy. Setup
|
|
27
|
+
guides for each agent: <https://aitextaroo.com/agents>.
|
|
28
|
+
|
|
29
|
+
Or just tell your agent:
|
|
30
|
+
|
|
31
|
+
> Set me up with AI Text-a-roo so I can text you. Instructions: aitextaroo.com/llms.txt
|
|
32
|
+
|
|
33
|
+
## Quick start from a terminal
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pipx install aitextaroo # or: pip install --user aitextaroo
|
|
37
|
+
aitextaroo-setup --phone +12125551234 # texts you a 6-digit code
|
|
38
|
+
aitextaroo-setup --phone +12125551234 --code 123456 --save # saves the key (owner-only)
|
|
39
|
+
aitextaroo send "Hello from my agent!"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`--save` stores the API key in `~/.aitextaroo/credentials.json` with owner-only permissions.
|
|
43
|
+
`aitextaroo` and `aitextaroo-bridge` find it there, or in `AITEXTAROO_API_KEY`, or in `--api-key`.
|
|
44
|
+
|
|
45
|
+
## The `aitextaroo` command
|
|
46
|
+
|
|
47
|
+
Made for agents with a shell. Output is JSON; errors go to stderr with exit code 1.
|
|
48
|
+
`aitextaroo verify-pin` exits 2 when the PIN is wrong, so `aitextaroo verify-pin <<< 4821 && …`
|
|
49
|
+
only continues on a match. `verify-pin` and `set-pin` read the PIN from stdin when it isn't
|
|
50
|
+
an argument, which keeps it out of shell history and the process list.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
aitextaroo send "Build finished: 318 tests passing."
|
|
54
|
+
aitextaroo ask "Deploy to production? Reply YES or NO" --timeout 120 # text, then wait for the answer
|
|
55
|
+
aitextaroo wait --timeout 60 # wait for the next text
|
|
56
|
+
aitextaroo recent # texts from the last 5 minutes
|
|
57
|
+
aitextaroo relay --to +12125550100 --name Mom "Happy birthday!" # Pro: text a contact
|
|
58
|
+
aitextaroo verify-pin <<< 4821 # check a PIN the user texted
|
|
59
|
+
aitextaroo set-pin <<< 4821 # set the user's PIN (4-8 digits)
|
|
60
|
+
aitextaroo account
|
|
61
|
+
aitextaroo upgrade # Stripe link for Pro
|
|
62
|
+
aitextaroo webhook set https://example.com/hook --auth-header "Bearer <token>"
|
|
63
|
+
aitextaroo connect [claude-code|codex|gemini|cursor|muse-code|claude|chatgpt|grok]
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## SMS bridge
|
|
67
|
+
|
|
68
|
+
The bridge holds one outbound connection to AI Text-a-roo. Each text you send becomes a
|
|
69
|
+
prompt for a CLI agent on your machine, and its answer is texted back. No webhook, no public
|
|
70
|
+
IP: it works behind NAT, firewalls and VPNs.
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
aitextaroo-bridge # auto-detects an installed agent
|
|
74
|
+
aitextaroo-bridge --agent codex
|
|
75
|
+
aitextaroo-bridge --agent-command "pnpm --silent --dir ~/nanoclaw run chat" # any other CLI
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
| `--agent` | Runs |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `claude` | `claude -p "<prompt>"` |
|
|
81
|
+
| `codex` | `codex exec --skip-git-repo-check --color never -o <file> "<prompt>"` |
|
|
82
|
+
| `hermes` | `hermes -z "<prompt>"` |
|
|
83
|
+
| `openclaw` | `openclaw agent exec "<prompt>"` |
|
|
84
|
+
| `grok` | `grok --no-auto-update -p "<prompt>"` |
|
|
85
|
+
| `gemini` | `gemini -p "<prompt>"` |
|
|
86
|
+
| `antigravity` | `agy -p "<prompt>"` |
|
|
87
|
+
| `goose` | `goose run -q --no-session -t "<prompt>"` |
|
|
88
|
+
| `cursor` | `cursor-agent -p --trust "<prompt>"`, or `agent` if that's all there is (explicit only: Grok Build also installs an `agent` binary, and the bridge refuses it) |
|
|
89
|
+
|
|
90
|
+
Auto-detect tries them in this order. `--agent-command` runs any CLI that takes the prompt
|
|
91
|
+
as its last argument and prints the reply.
|
|
92
|
+
|
|
93
|
+
Conversation history is saved locally in `~/.aitextaroo/sessions/` and survives restarts.
|
|
94
|
+
Text `/help`, `/new` (fresh conversation) or `/status`. Use `--no-persist` for memory-only
|
|
95
|
+
history. Responses are stripped of markdown for SMS.
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
aitextaroo-bridge [OPTIONS]
|
|
99
|
+
--api-key KEY API key (default: AITEXTAROO_API_KEY or the saved credentials)
|
|
100
|
+
--agent NAME auto, claude, codex, hermes, openclaw, grok, gemini, antigravity, goose, cursor
|
|
101
|
+
--agent-command CMD Any other CLI agent (overrides --agent)
|
|
102
|
+
--sessions-dir PATH Session files (default ~/.aitextaroo/sessions/)
|
|
103
|
+
--no-persist Keep history in memory only
|
|
104
|
+
--base-url URL Custom API URL
|
|
105
|
+
-v, --verbose Debug logging
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Python SDK
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
import asyncio
|
|
112
|
+
from aitextaroo import TextarooClient
|
|
113
|
+
|
|
114
|
+
async def main():
|
|
115
|
+
client = TextarooClient(api_key="YOUR_KEY")
|
|
116
|
+
await client.send("All tests pass. Open a PR? Reply YES or NO.")
|
|
117
|
+
reply = await client.wait_for_reply(timeout_seconds=90)
|
|
118
|
+
print(reply.text if reply else "No answer yet")
|
|
119
|
+
await client.close()
|
|
120
|
+
|
|
121
|
+
asyncio.run(main())
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
| Method | What it does |
|
|
125
|
+
|---|---|
|
|
126
|
+
| `send(text)` | Text the user. Returns the message ID. |
|
|
127
|
+
| `wait_for_reply(timeout_seconds=60)` | Wait up to 120 s for the user's next text (or one that arrived since your last send). Returns an `InboundMessage` or `None`. |
|
|
128
|
+
| `recent_messages(after_id=None)` | Texts from the last five minutes. |
|
|
129
|
+
| `listen()` | Async iterator over inbound texts via SSE, with automatic reconnect and replay. |
|
|
130
|
+
| `text_contact(to, text, recipient_name=None)` | Pro: text someone else; their replies go to the user's phone. |
|
|
131
|
+
| `verify_pin(pin)` | Check a PIN the user texted: `{"verified": bool, "attempts_remaining": int \| None}`. |
|
|
132
|
+
| `set_pin(pin)` / `remove_pin()` | Set, change or remove the user's security PIN (4–8 digits). |
|
|
133
|
+
| `set_webhook(url, auth_header=None)` / `remove_webhook()` | Forward inbound texts to a URL (signed with `X-Signature`). |
|
|
134
|
+
| `account()` | Plan, assigned number, usage and daily limit. |
|
|
135
|
+
| `upgrade_link()` | Stripe checkout link for Pro. |
|
|
136
|
+
| `TextarooClient.request_verification(phone)` / `confirm_verification(phone, code)` | Sign-up, no key needed. |
|
|
137
|
+
|
|
138
|
+
`InboundMessage` has `id`, `text`, `received_at`, `channel` (`"sms"`), `trust_level` and
|
|
139
|
+
`has_pin`. See [`examples/`](examples/) for an echo bot, a listener and an ask-and-wait flow.
|
|
140
|
+
|
|
141
|
+
## MCP server
|
|
142
|
+
|
|
143
|
+
`https://api.aitextaroo.com/mcp` (streamable HTTP). Tools: `send_text`, `wait_for_reply`,
|
|
144
|
+
`get_recent_messages`, `text_contact`, `verify_pin`, `get_account`, `get_upgrade_link`.
|
|
145
|
+
Clients sign in with OAuth, or send `Authorization: Bearer <API key>`:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
claude mcp add --transport http --scope user aitextaroo https://api.aitextaroo.com/mcp \
|
|
149
|
+
--header "Authorization: Bearer $AITEXTAROO_API_KEY"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Run `aitextaroo connect` for every client's exact setup. Reference: <https://aitextaroo.com/docs/mcp>.
|
|
153
|
+
|
|
154
|
+
## Plans
|
|
155
|
+
|
|
156
|
+
| | Free ($0) | Pro ($5/mo, 14-day free trial) |
|
|
157
|
+
|---|---|---|
|
|
158
|
+
| Messages per day | 10 | 200 |
|
|
159
|
+
| Two-way texting, MCP, skill, SDK, bridge | ✓ | ✓ |
|
|
160
|
+
| Security PIN | ✓ | ✓ |
|
|
161
|
+
| Text your contacts, with replies forwarded | | ✓ |
|
|
162
|
+
|
|
163
|
+
Up to 5 texts per minute. Limits reset at midnight UTC.
|
|
164
|
+
|
|
165
|
+
## Privacy and security
|
|
166
|
+
|
|
167
|
+
- Message content is never written to AI Text-a-roo's database. Texts are held in memory
|
|
168
|
+
for at most five minutes so an agent can catch up after a dropped connection.
|
|
169
|
+
- Phone numbers are encrypted at rest; PINs are stored as bcrypt hashes.
|
|
170
|
+
- The bridge's history and the saved credentials live only on your machine.
|
|
171
|
+
- SMS isn't end-to-end encrypted, and sender IDs can be spoofed. The bridge tells every agent
|
|
172
|
+
to ask for your PIN before anything sensitive, because some CLIs (for example `hermes -z`)
|
|
173
|
+
auto-approve their own tool calls in one-shot mode. Run the bridge with an agent whose
|
|
174
|
+
permissions you're comfortable exposing to your phone number.
|
|
175
|
+
|
|
176
|
+
Details: <https://aitextaroo.com/security>.
|
|
177
|
+
|
|
178
|
+
## Environment variables
|
|
179
|
+
|
|
180
|
+
| Variable | Description |
|
|
181
|
+
|---|---|
|
|
182
|
+
| `AITEXTAROO_API_KEY` | API key (alternative to `--api-key` and the saved credentials) |
|
|
183
|
+
| `AITEXTAROO_BASE_URL` | Custom API URL |
|
|
184
|
+
|
|
185
|
+
## Releasing
|
|
186
|
+
|
|
187
|
+
Bump `version` in `pyproject.toml` and `__version__` in `aitextaroo/__init__.py`, merge to
|
|
188
|
+
`main`, then push a matching tag: `git tag v0.2.1 && git push origin v0.2.1`. The
|
|
189
|
+
[Release workflow](.github/workflows/release.yml) tests, builds and publishes to PyPI with
|
|
190
|
+
Trusted Publishing.
|
|
191
|
+
|
|
192
|
+
## License
|
|
193
|
+
|
|
194
|
+
MIT
|