agent-inbox 0.1.0__py3-none-any.whl
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.
- agent_inbox-0.1.0.dist-info/METADATA +208 -0
- agent_inbox-0.1.0.dist-info/RECORD +16 -0
- agent_inbox-0.1.0.dist-info/WHEEL +4 -0
- agent_inbox-0.1.0.dist-info/entry_points.txt +2 -0
- agent_inbox-0.1.0.dist-info/licenses/LICENSE +674 -0
- agent_mail/__init__.py +35 -0
- agent_mail/cli.py +425 -0
- agent_mail/config.py +296 -0
- agent_mail/config_env.py +30 -0
- agent_mail/defaults.toml +47 -0
- agent_mail/exceptions.py +20 -0
- agent_mail/identity.py +49 -0
- agent_mail/mailbox.py +308 -0
- agent_mail/mcp_server.py +258 -0
- agent_mail/models.py +68 -0
- agent_mail/py.typed +0 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agent-inbox
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A SQLite mailbox for local LLM agents — a CLI primitive plus a hostable MCP server so AI coding agents can message and notify each other. No external services.
|
|
5
|
+
Project-URL: Homepage, https://github.com/salimfadhley/agent-inbox
|
|
6
|
+
Project-URL: Repository, https://github.com/salimfadhley/agent-inbox
|
|
7
|
+
Project-URL: Issues, https://github.com/salimfadhley/agent-inbox/issues
|
|
8
|
+
Author: Sal Fadhley
|
|
9
|
+
License: GPL-3.0-or-later
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agents,claude,inter-agent,llm,mailbox,mcp,messaging,sqlite
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Communications
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Classifier: Topic :: System :: Distributed Computing
|
|
22
|
+
Requires-Python: >=3.12
|
|
23
|
+
Requires-Dist: aiosqlite>=0.20
|
|
24
|
+
Requires-Dist: click>=8.1
|
|
25
|
+
Requires-Dist: mcp[cli]>=1.12
|
|
26
|
+
Requires-Dist: pydantic-settings>=2.3
|
|
27
|
+
Requires-Dist: pydantic>=2.7
|
|
28
|
+
Requires-Dist: uvicorn>=0.30
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# agent-mail
|
|
32
|
+
|
|
33
|
+
**A local SQLite-backed mailbox for local LLM agents.** AI coding agents (Claude,
|
|
34
|
+
Codex, Gemini, …) running on the same machine or LAN get a simple, standard way to
|
|
35
|
+
**message each other** — a small **CLI** plus a **hostable MCP server** over the same
|
|
36
|
+
verbs — instead of a human hand-relaying prompts between them. Storage is a single
|
|
37
|
+
local SQLite file: **no external services, no message broker.**
|
|
38
|
+
|
|
39
|
+
[](https://github.com/salimfadhley/agent-inbox/actions/workflows/ci.yml)
|
|
40
|
+

|
|
41
|
+

|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Why
|
|
46
|
+
|
|
47
|
+
Agents on one box usually coordinate by dropping files in a shared git repo — durable
|
|
48
|
+
and auditable, but **poll-only**: one agent can't get another's attention. `agent-mail`
|
|
49
|
+
gives each agent a real, durable inbox backed by a single local **SQLite** file — no
|
|
50
|
+
server to stand up, nothing to keep running.
|
|
51
|
+
|
|
52
|
+
> **Honest limitation.** A running LLM turn can't be interrupted or poll on a timer,
|
|
53
|
+
> and SQLite can't push a cross-process wake. So "check periodically" means **check
|
|
54
|
+
> every turn** — at natural decision points. You get a durable inbox to read; there is
|
|
55
|
+
> no mid-turn preemption. (`notify` still exists but is a best-effort no-op — see below.)
|
|
56
|
+
|
|
57
|
+
## How it works
|
|
58
|
+
|
|
59
|
+
- Every message lives in one local SQLite file. Each agent's inbox is just the rows
|
|
60
|
+
addressed to it, and messages persist until that agent reads (acks) them.
|
|
61
|
+
- **Automatic expiry:** when a mailbox opens, messages older than `ttl_days`
|
|
62
|
+
(default 14) are purged, so history never grows without bound — one simple knob,
|
|
63
|
+
no compaction to manage.
|
|
64
|
+
- `notify` is a **best-effort no-op**: SQLite can't wake another process, so the verb
|
|
65
|
+
still exists (and validates the address) but doesn't push anything. The model is
|
|
66
|
+
"check your inbox every turn."
|
|
67
|
+
- The CLI and the MCP server share one core (`agent_mail.mailbox.Mailbox`) — no logic
|
|
68
|
+
duplication.
|
|
69
|
+
|
|
70
|
+
## Requirements
|
|
71
|
+
|
|
72
|
+
- **Python 3.12+**
|
|
73
|
+
- **Nothing else.** Storage is a single local SQLite file (`AGENT_MAIL_DB`, default
|
|
74
|
+
`~/.local/share/agent-mail/agent-mail.db`); there is no broker or other service to
|
|
75
|
+
run.
|
|
76
|
+
|
|
77
|
+
## Install
|
|
78
|
+
|
|
79
|
+
The PyPI package is **`agent-inbox`**; it installs the **`agent-mail`** command.
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
uv tool install agent-inbox # recommended (isolated CLI)
|
|
83
|
+
pipx install agent-inbox # or
|
|
84
|
+
pip install agent-inbox # into the current environment
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Or run the MCP server as a container — see [Hosting](docs/hosting.md):
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
docker run -p 8080:8080 -v agent-mail-data:/data \
|
|
91
|
+
salimfadhley/agent-inbox:latest
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Quickstart (CLI)
|
|
95
|
+
|
|
96
|
+
Zero infrastructure: install the package, set your two-part identity — **project +
|
|
97
|
+
agent** (`--project` / `AGENT_MAIL_PROJECT` and `--from` / `AGENT_ID`) — and run. The
|
|
98
|
+
SQLite file is created on first use.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
export AGENT_MAIL_PROJECT=agent-mail
|
|
102
|
+
export AGENT_ID=claude-opus
|
|
103
|
+
|
|
104
|
+
# direct: a specific agent on a project
|
|
105
|
+
agent-mail send --to agent-mail/codex --subject "corpus stale?" --body "reindex?"
|
|
106
|
+
# any one agent on a project (a shared work queue)
|
|
107
|
+
agent-mail send --to agent-mail --subject "task" --body "who can take this?"
|
|
108
|
+
# broadcast: every agent on a project
|
|
109
|
+
agent-mail send --to agent-mail/* --subject "heads up" --body "deploying in 5"
|
|
110
|
+
|
|
111
|
+
# read your own inbox (as agent-mail/codex)
|
|
112
|
+
AGENT_ID=codex agent-mail inbox
|
|
113
|
+
AGENT_ID=codex agent-mail read <id>
|
|
114
|
+
AGENT_ID=codex agent-mail reply <id> --body "on it" # replies directly to the sender
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Add `--json` to any command for machine-readable output.
|
|
118
|
+
|
|
119
|
+
**Addressing:** `project/agent` (direct) · `project` (any one agent) · `project/*` (broadcast).
|
|
120
|
+
|
|
121
|
+
| Verb | What it does |
|
|
122
|
+
|------|--------------|
|
|
123
|
+
| `send --to <target> --subject --body [--thread] [--intent]` | Send to `project/agent`, `project` (any), or `project/*` (all) |
|
|
124
|
+
| `inbox` | List my unread messages (peek — does **not** ack) |
|
|
125
|
+
| `read <id>` | Show a message and **ack** it (consume) |
|
|
126
|
+
| `reply <id> --body` | Reply directly to the sender and ack the original |
|
|
127
|
+
| `notify --to <target> [--thread]` | Validate the address (best-effort; a no-op — SQLite can't wake a process) |
|
|
128
|
+
| `ping` | Round-trip a message to yourself to check the system is operational |
|
|
129
|
+
| `doctor` | Validate config + storage; print the db path, `storage: ✅ ready`, and the effective (redacted) config |
|
|
130
|
+
| `hub-info` | Show this hub's public self-description (name, connect URL, admin/feedback) |
|
|
131
|
+
| `mcp-serve` | Run the MCP server (see below) |
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# verify agent-mail is working end-to-end (send + inbox + read to yourself)
|
|
135
|
+
AGENT_MAIL_PROJECT=agent-mail AGENT_ID=claude-opus agent-mail ping
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## MCP server
|
|
139
|
+
|
|
140
|
+
The same verbs are exposed as MCP tools (`send_message`, `check_inbox`,
|
|
141
|
+
`read_message`, `reply_message`, `notify_agent`, and `ping` — a self round-trip a
|
|
142
|
+
client can call on sign-on to confirm everything works). Two ways to run it:
|
|
143
|
+
|
|
144
|
+
**Local, per-agent (stdio).** The client spawns it; identity is `AGENT_MAIL_PROJECT` + `AGENT_ID`.
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
AGENT_MAIL_PROJECT=agent-mail AGENT_ID=claude-opus agent-mail mcp-serve
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Hosted, multi-agent (http).** One server serves everyone. **Each agent connects on
|
|
151
|
+
its own address — the URL *is* its identity, `/<project>/<agent>/mcp`:**
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
http://mail-host:8080/agent-mail/claude-opus/mcp → agent-mail / claude-opus
|
|
155
|
+
http://mail-host:8080/goldberg/casework/mcp → goldberg / casework
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
agent-mail mcp-serve --transport http --host 0.0.0.0
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
That personalized URL is an agent's **entire configuration** — no env, no headers.
|
|
163
|
+
(`?project=&agent=` and `X-Agent-Project` + `X-Agent-Id` headers also work for
|
|
164
|
+
programmatic clients.) See [docs/mcp-clients.md](docs/mcp-clients.md) to wire it into
|
|
165
|
+
Claude Code, Codex, and others, and [docs/hosting.md](docs/hosting.md) to deploy it.
|
|
166
|
+
|
|
167
|
+
## The "check your inbox" convention
|
|
168
|
+
|
|
169
|
+
An agent only benefits from mail if it looks. Paste the ready-made block from
|
|
170
|
+
[docs/inbox-check-snippet.md](docs/inbox-check-snippet.md) into your agents'
|
|
171
|
+
`CLAUDE.md` / `AGENTS.md`, and hand a new agent
|
|
172
|
+
[docs/agent-onboarding.md](docs/agent-onboarding.md) to get it participating.
|
|
173
|
+
|
|
174
|
+
## Configuration
|
|
175
|
+
|
|
176
|
+
Settings resolve from four layers, **later winning**: field defaults → the baked
|
|
177
|
+
`defaults.toml` → a runtime `--config file.toml` → **environment variables**. Every
|
|
178
|
+
setting has one name usable as a lowercase TOML key or its UPPERCASE env var (`db`
|
|
179
|
+
== `AGENT_MAIL_DB`). Containers set env vars; developers point at a TOML file:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
agent-mail --config ./agent-mail.toml mcp-serve # env still overrides the file
|
|
183
|
+
agent-mail doctor # show effective config + check storage
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Common settings: `AGENT_MAIL_DB` (the SQLite file path), `AGENT_MAIL_TTL_DAYS`
|
|
187
|
+
(auto-purge age, default 14; 0 disables), `AGENT_MAIL_MAX_MESSAGE_BYTES` (default
|
|
188
|
+
1048576 = 1 MiB), `AGENT_MAIL_PROJECT`, `AGENT_ID`,
|
|
189
|
+
`AGENT_MAIL_TRANSPORT/HOST/PORT/PATH`, `AGENT_MAIL_HUB`, and the hub's admin/feedback
|
|
190
|
+
fields advertised via `hub_info`. **Full reference:**
|
|
191
|
+
[docs/configuration.md](docs/configuration.md).
|
|
192
|
+
|
|
193
|
+
## Development
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
uv sync --dev
|
|
197
|
+
uv run pytest # unit tests
|
|
198
|
+
uv run ruff check . && uv run ruff format --check .
|
|
199
|
+
uv run pyright
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The test suite needs no external services — it runs against SQLite in normal CI.
|
|
203
|
+
|
|
204
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for the coding standards and quality gates.
|
|
205
|
+
|
|
206
|
+
## License
|
|
207
|
+
|
|
208
|
+
[GPL-3.0-or-later](LICENSE).
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
agent_mail/__init__.py,sha256=UeF1ePCB9Uccic05BctSwVSBfzvsv_XUV7FPtWenmPU,871
|
|
2
|
+
agent_mail/cli.py,sha256=zE5bl-Avd9mmpCcyptBsHW9dQQ6oemotkIsY3IvLxdw,12923
|
|
3
|
+
agent_mail/config.py,sha256=bcNnYypJjzK8TUot6jgJFkynrTvi2rYPehrWV4_1ruc,11021
|
|
4
|
+
agent_mail/config_env.py,sha256=sYBEhIHPpDj6u8zOOVvKjXyL9BH_3GYdRTUC9KVckrc,882
|
|
5
|
+
agent_mail/defaults.toml,sha256=8IpMFCJr4cO_Wumb8C08kfT9J8qtGfevILlTsmoVCCk,2689
|
|
6
|
+
agent_mail/exceptions.py,sha256=i80Jmii1O7hZ5dWRU4S-2IlBiJX2XVWO7FDGM5Z8HP8,662
|
|
7
|
+
agent_mail/identity.py,sha256=oPk3cBr43opHTh0CIRDppszcO7D_JZPgvy6zb79qaRk,2062
|
|
8
|
+
agent_mail/mailbox.py,sha256=aTgmW2IbkDp-GTiG3Cj_qUWef9Ll0rqgOkPCe2tltME,11827
|
|
9
|
+
agent_mail/mcp_server.py,sha256=GagFd8mPOB5eEDJyupSK1k-FycwTEnAb9LVVQtgzUd8,9005
|
|
10
|
+
agent_mail/models.py,sha256=fA4lqzVIkR6jt-d4Gt36VFRgIXLTM_7cSlIbqrQzFEw,2081
|
|
11
|
+
agent_mail/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
+
agent_inbox-0.1.0.dist-info/METADATA,sha256=uXOAqavVAFpgCq2LYmtWwbIkNgkYD6gp7Xak2Q3BsHQ,8858
|
|
13
|
+
agent_inbox-0.1.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
|
|
14
|
+
agent_inbox-0.1.0.dist-info/entry_points.txt,sha256=T8Hl95bk8AhHU8tmaMA0UIuG6cNyg9V-w-dXdSN0F0o,51
|
|
15
|
+
agent_inbox-0.1.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
16
|
+
agent_inbox-0.1.0.dist-info/RECORD,,
|