Order emails in. ERP orders out. An AI reads the order emails, a person confirms, and only then is the order written to the order system.
Proof of concept by Levixflow, built to test one idea end to end with fictional companies, fictional emails and a fictional order system (the "Demo ERP"). Meant to be read, run and extended, not used in production.
Many companies that sell and ship goods still receive orders by email: a few lines in the message, or a PDF purchase order attached. Someone reads each email and types the order into the ERP. Changes arrive the same way: "make the packing tape eight cases, not six".
Inbox to Order does the reading and the typing, and leaves the decision to a person:
- Email arrives. The app reads the mailbox. It can only read: it never sends, moves or deletes anything.
- AI reads it. Claude reads the email and any PDF, finds the customer, the items and the quantities, and tells a new order from a change. Every value is linked to the words it came from. When something is unclear, it asks instead of guessing.
- You confirm. You check the proposal, correct it if needed, and confirm or reject.
- ERP updated. Only your confirmation writes the order. Nothing is written before.
The app sits in the middle. It talks to the mailbox and to the ERP through two MCP servers, an open standard for connecting tools to AI applications: the Mail server can only read, and the ERP server is called to write only after your confirmation. Claude never writes anything. Swapping Gmail for another mailbox, or the Demo ERP for a real one, means replacing one server.
Screenshots from the bundled demo emails, read without AI so anyone can reproduce them for free. With Claude the screens are the same.
The same flow on a Gmail test account with 10 emails, one of them with a PDF purchase order, read by Claude Haiku 5.5. 53 seconds, no sound.
inbox-to-order.mp4
The same video is in the repository: docs/media/inbox-to-order.mp4.
Measured in that run: all 10 emails read and sorted in 19.4 s, PDF included, about $0.001 to $0.002 of AI cost per email. The result: 3 orders ready to confirm, 1 question for a person, 3 emails set aside as not orders. Details, and what these numbers do not show: docs/TEST_RESULTS.md.
No accounts, no cost. You need uv (it installs Python if needed; 3.11 or later) and Git. Developed and tested on Windows 11; the automated tests also run on Linux. macOS has not been tried.
git clone https://github.com/levixflow-com/inbox-to-order.git
cd inbox-to-order
uv sync
uv run inbox-to-order init-db --reset
uv run inbox-to-order webOpen http://127.0.0.1:8700 (the app) and, in a second window, http://127.0.0.1:8700/erp (the Demo ERP).
Without an API key, the app reads the 8 bundled demo emails with a rule-based baseline: plain pattern matching, shown as "Read by rules, no AI". It only understands the demo emails, and exists so that anyone can try the flow. Click Read all new, open PO-48217, confirm it, and watch the Demo ERP window. Reset demo data starts again.
Every setting lives in .env (git-ignored); .env.example lists them all with comments.
cp .env.example .env| Piece | How it is connected | What you set up |
|---|---|---|
| The app | One local Python process: the web UI and the steps read, interpret, check, propose. Listens on 127.0.0.1 only. |
uv run inbox-to-order web |
| Mail MCP server | Started by the app, over stdio. Lists and reads conversations and the text of PDF attachments; no tool can send, change or delete email. | INBOX_MODE=fixture (demo emails, default) or gmail |
| Gmail (optional) | Read by the Mail server through the Gmail API, with your own OAuth client, read-only. | See below |
| Claude (optional) | Called by the app with your key. Reads through a few read-only MCP tools, limited to the selected email and its customer. | ANTHROPIC_API_KEY |
| Demo ERP MCP server | Started by the app, over stdio. Customers, catalog, orders, plus create_order and update_order, called only after your confirmation. |
Nothing: init-db fills it from fixtures/ |
| Demo ERP screen | The ERP's own window at /erp, reading its database read-only. |
Nothing |
The order of calls and the three layers of control: docs/ARCHITECTURE.md.
Claude. Create a key in the Claude Console and set
ANTHROPIC_API_KEY=sk-ant-... in .env. The default model is claude-haiku-5-5, the lowest-cost one; any Claude
model works (ANTHROPIC_MODEL), and the Settings menu switches model or reading mode without a restart. Usage
is billed to your Anthropic account; the app shows tokens and an estimated cost per run. When Claude is on, the
text of each email you process and of its PDFs is sent to Anthropic: use test emails only.
Gmail. About 15 minutes, once: a Gmail account used only for this test, a Google Cloud project with the Gmail
API and a Desktop app OAuth client saved as secrets/credentials.json, then uv run inbox-to-order gmail-auth.
Set INBOX_MODE=gmail, map your test sender to a demo customer (EXTRA_CUSTOMER_SENDERS), and choose the
conversations to read with GMAIL_QUERY (any Gmail search). Step by step: docs/GMAIL_SETUP.md.
The scope is gmail.readonly; messages the app reads stay unread in Gmail.
Demo ERP. A SQLite file with an MCP server in front of it, standing in for a real ERP: 2 customers, a 7-item
catalog, the customers' own item codes and one existing order. init-db --reset starts it again; the mailbox is
never touched.
MCP servers. The app starts and stops them; uv run inbox-to-order mcp-diagnose shows their tools and makes
a few live calls. They are ordinary stdio servers (python -m inbox_to_order.mcp_servers.mail_server or
erp_server), not tested with other MCP clients. Outside this app, mind that the ERP server's write tools do not
check for a person's confirmation: that check lives in the app.
The UI. The built UI ships in src/inbox_to_order/web/dist/, so running the app needs no Node. After
changing frontend/, rebuild it with scripts/build-ui.sh (Node in Docker) or cd frontend && npm ci && npm run build.
uv run inbox-to-order web # the app and the Demo ERP screen on http://127.0.0.1:8700
uv run inbox-to-order init-db # create or reload the demo data (--reset: start again)
uv run inbox-to-order gmail-auth # authorize the Gmail test account, read-only
uv run inbox-to-order threads # list the conversations, through the Mail MCP server
uv run inbox-to-order demo # read every demo email on a fresh database and print the results
uv run inbox-to-order drafts # the proposals and their status
uv run inbox-to-order confirm 1 # confirm proposal #1 and write it to the Demo ERP
uv run inbox-to-order erp-orders # what is in the Demo ERP
uv run inbox-to-order eval # check the demo emails against the expected outcomes
uv run inbox-to-order mcp-diagnose # the two MCP servers, their tools and some live calls
uv run pytest # offline tests: no key, no Google account
uv run ruff check . && uv run mypy src/inbox_to_order # lint and types, as in CI- No OCR: scanned PDFs and images are not read; they are flagged for a person.
- No real ERP: the Demo ERP is a SQLite database with fictional prices.
- No sending, replying, labelling or deleting email.
- No quotes, invoices, stock or delivery dates.
- New lines in a change email are not added automatically; the operator adds them.
- One operator, one machine: no login, roles or deployment.
- Only Claude is wired in as the AI (other providers are possible, not implemented).
What has been tested, and how: docs/TEST_RESULTS.md. Before pointing it at anything other than test data, read docs/SECURITY_AND_LIMITATIONS.md.
src/inbox_to_order/
mcp_servers/mail_server.py Mail MCP server (read-only; demo files or Gmail)
mcp_servers/erp_server.py Demo ERP MCP server (customers, catalog, orders; create/update order)
mcp_client.py starts both servers over stdio and keeps them running
agent.py Claude: reads through allow-listed tools, returns a structured proposal
extractors.py the rule-based baseline (no AI)
pipeline.py checks in plain code: evidence, customer, catalog, units, PO, change target
orchestrator.py one email: read -> interpret -> check -> save a proposal
review.py operator actions: the only call to create/update_order
services/ email parsing, PDF text, Gmail auth, proposals store, Demo ERP logic
web/server.py, web/dist/ local API and the built UI
frontend/ React + TypeScript source of the UI
fixtures/ demo emails, PDFs, customers, catalog, expected outcomes
docs/ architecture, Gmail setup, security, test results, extending, screenshots, video
tests/ offline tests; live tests are opt-in with -m live
.github/workflows/tests.yml lint, types and offline tests on every push
Built by Levixflow, a studio that builds custom software for companies that sell and ship goods. Order emails still typed into your system by hand? Send me your problem, even in two lines.
MIT license. See LICENSE.






