agentbox
by sagnik11
README.md
# AgentBox
**Open-source email infrastructure for AI agents, provisioned in your AWS account.**
AgentBox is a hosted, multi-tenant control plane that gives every software agent a real email identity, inbox, safety policy, and scoped API key. People create an AgentBox account and private workspace, then connect their AWS account from the dashboard. AgentBox configures Amazon SES, S3, and SNS without replacing an existing receipt-rule set, receives raw MIME, threads conversations, sends replies, and exposes the result through REST, realtime events, SDKs, MCP, and an operator console.
Your AWS account remains the mail server. AgentBox is the control plane.
## What is included
- **AWS onboarding:** enter an AWS Access Key ID and Secret Access Key in AgentBox; credentials are encrypted at rest, checked with STS, and validated against every required permission before provisioning. Default credentials and cross-account `AssumeRole` remain available for advanced deployments.
- **Safe provisioning:** Easy DKIM or BYODKIM, custom MAIL FROM, live DNS checks, destructive-MX warnings, S3/SNS/configuration-set creation or adoption, and safe receipt-rule insertion.
- **Agent lifecycle:** readable generated addresses, bulk creation, sub-addressing, reserved system agents, optional catch-all routing, pause/resume replay, and archive tombstones.
- **Safe outbound:** SES raw MIME, SMTP/local fallback, correct reply headers, reply-all self-address removal, suppressions, allow/block lists, daily limits, approval queues, thread depth limits, and auto-reply loop prevention.
- **Inbound processing:** verified SNS notifications, S3 MIME fetch, generic signed JSON and Postmark adapters, durable idempotency, replayable failures, bounce-as-mail handling, attachment extraction, content sniffing, and content-addressed storage.
- **Events:** durable cursor log, polling, SSE, WebSocket resume, long polling, filtered waits, HMAC webhooks, exponential retry, and dead-letter replay.
- **Intelligence, optional:** hybrid lexical/semantic search, quote stripping, chunked embeddings, JSON-schema extraction, validation, confidence, spend caps, and backfill.
- **Operator surfaces:** responsive web console, OpenAPI/Swagger, TypeScript and Python SDKs, MCP tools, YAML config import/export/diff/apply, audit logs, and health views.
## Hosted account model
Human users do not log in with an organization API key. They create an account with their name, email, workspace name, and password. AgentBox creates an isolated organization and issues an expiring HTTP-only session cookie. Passwords are hashed with scrypt, and session tokens are stored only as SHA-256 hashes.
After signing in, the workspace owner adds AWS credentials and completes provisioning. Scoped AgentBox API keys are created later for agents, SDKs, MCP, and external integrations; they are not dashboard passwords.
## Architecture
```text
Customer AWS account AgentBox
┌──────────────────────────────┐ ┌────────────────────────────┐
│ SES receipt rule │ │ Operator console │
│ └─ S3 raw MIME ── SNS ─────┼── HTTPS ──▶│ Ingest + threading │
│ SES sending + config set ◀───┼── AWS SDK ─│ Provisioner + sender │
│ Bounce/complaint SNS ─────────┼── HTTPS ──▶│ Events + suppressions │
│ S3 attachment objects │◀────────────│ REST · SDKs · MCP │
└──────────────────────────────┘ │ SQLite reference store │
└────────────────────────────┘
```
The included deployment is a single-process, single-node reference deployment backed by SQLite/WAL. Organization boundaries are enforced throughout the API, but horizontal multi-replica operation requires a shared database/event notifier that is not included in this release.
## Quick start
Requirements: Node.js 20+ and npm.
```bash
git clone https://github.com/sagnik11/agentbox.git
cd agentbox
cp .env.example .env
npm install
npm run dev
```
Set at least these values in `.env` before exposing the service:
```bash
AGENTBOX_API_KEY=<a-long-random-emergency-bootstrap-key>
INBOUND_WEBHOOK_SECRET=<a-different-random-secret>
ENCRYPTION_KEY=<at-least-32-random-characters>
PUBLIC_URL=https://agentbox.example.com
```
Open `http://localhost:3000` for the AgentBox product website, then create a hosted-style account at `http://localhost:3000/signup`. Returning users sign in at `/login`; the authenticated dashboard is `/console`. The dashboard walks through AWS credentials, region, domain, DNS, and receiving setup. Interactive API documentation is at `http://localhost:3000/docs`.
`AGENTBOX_API_KEY` is an operator-controlled bootstrap/recovery credential for direct API access. It is not shown to hosted users and is not used by the browser dashboard.
For local development without AWS, create a domain and an agent. Sends are recorded as simulated and no recipient is contacted:
```bash
curl -X POST http://localhost:3000/v1/domains \
-H 'Authorization: Bearer local-secret' \
-H 'Content-Type: application/json' \
-d '{"name":"mail.agents.test"}'
curl -X POST http://localhost:3000/v1/agents \
-H 'Authorization: Bearer local-secret' \
-H 'Content-Type: application/json' \
-d '{"domain_id":"<domain-id>","username":"researcher","name":"Research agent"}'
```
## Docker
Copy `.env.example` to `.env`, replace the required secrets, then run:
```bash
docker compose up --build
```
The data volume contains the SQLite database and locally stored attachments. Back it up as one unit. See [deployment guidance](docs/DEPLOYMENT.md) before connecting a production AWS account.
## AWS onboarding
The default onboarding path asks for an AWS Access Key ID and Secret Access Key. AgentBox encrypts both values with `ENCRYPTION_KEY`; plaintext is accepted only on the create request and is never returned. Self-hosted operators can alternatively use the default AWS credential chain or a cross-account role with a unique External ID. The included [IAM policy](infra/least-privilege-policy.json) documents the required actions, and [the CloudFormation role](infra/agentbox-role.yaml) supports the advanced `AssumeRole` path.
The console then performs this sequence:
1. Accepts the AWS Access Key ID and Secret Access Key through the encrypted AgentBox console.
2. Calls STS to establish the AWS account and principal, then simulates every required IAM action and reports missing permissions.
3. Reads per-region SES production access and quota.
4. Creates or adopts an S3 bucket, SNS topic, and SES configuration set.
5. Creates the domain identity and renders DKIM, SPF, DMARC, MAIL FROM, and inbound MX records.
6. Checks DNS record-by-record and warns before a root MX change could replace human mail.
7. Appends AgentBox's rule to the active SES receipt-rule set. If no active set exists, it creates and activates one.
Provisioning is idempotent and records ownership. Teardown disables and removes AgentBox's domain rule and identity while preserving messages and adopted/shared resources.
## Core API
```bash
# Create a scoped key for an agent
curl -X POST http://localhost:3000/v1/agents/<agent-id>/api-keys \
-H 'Authorization: Bearer <root-key>' \
-H 'Content-Type: application/json' \
-d '{"name":"runtime"}'
# Send exactly once across client retries
curl -X POST http://localhost:3000/v1/agents/<agent-id>/messages \
-H 'Authorization: Bearer <agent-key>' \
-H 'Idempotency-Key: task-4021-email-1' \
-H 'Content-Type: application/json' \
-d '{"to":["person@example.com"],"subject":"Update","text":"The task is complete."}'
# Wait for matching inbound mail
curl 'http://localhost:3000/v1/agents/<agent-id>/wait?type=message.received&subject_contains=verification&timeout_ms=60000' \
-H 'Authorization: Bearer <agent-key>'
```
Important endpoint groups:
| Area | Endpoints |
| --- | --- |
| AWS | `/v1/aws/accounts`, `/v1/aws/connections`, `/preflight`, `/health`, `/production-access` |
| Domains | `/v1/domains`, `/provision-identity`, `/dns`, `/verify`, `/provision-receiving` |
| Agents | `/v1/agents`, `/bulk`, `/:id/messages`, `/:id/wait`, `/:id/api-keys` |
| Threads | `/v1/threads/:id`, `/v1/threads/:id/reply` |
| Attachments | `/v1/attachments`, `/v1/attachments/:id`, `/:id/signed-url` |
| Operations | `/v1/approvals`, `/v1/suppressions`, `/v1/audit`, `/v1/inbound/deliveries` |
| Realtime | `/v1/events`, `/v1/ws`, `/v1/webhooks`, `/v1/webhook-deliveries` |
| Intelligence | `/v1/search`, `/v1/extractors`, `/v1/intelligence/backfill` |
| Configuration | `/v1/config/export`, `/v1/config/diff`, `/v1/config/apply` |
All errors use a stable `error` code plus `message`, `docs_url`, and `request_id`. Agent-scoped keys can access only their agent. Organization keys are required for provisioning, global settings, approvals, and key management.
## Inbound and attachments
SES receiving uses S3 followed by SNS. AgentBox validates the SNS certificate origin and signature, requires an exact registered Topic ARN, fetches raw MIME from the customer bucket, and stores parsed attachments in that same S3 account when the connection has been provisioned.
Generic integrations POST normalized JSON to `/v1/inbound` with `X-AgentBox-Signature`, the hex HMAC-SHA256 of the exact request bytes using `INBOUND_WEBHOOK_SECRET`. Native Postmark payloads can use configured HTTP Basic authentication.
Attachment objects are keyed by SHA-256 and reference-counted. Downloads always use `Content-Disposition: attachment`, `application/octet-stream`, and `nosniff`. Authenticated callers can mint an anonymous signed URL valid for at most one hour.
## Realtime delivery
- Poll `/v1/events?cursor=<n>` for durable cursor pagination.
- Request `Accept: text/event-stream` on the same endpoint for SSE.
- Connect to `/v1/ws?token=<key>&cursor=<n>` for WebSocket resume. Slow consumers are closed with code `1013` and a resume cursor.
- Use `/v1/agents/:id/wait` or MCP `wait_for_message` for filtered blocking waits.
- Webhooks receive a stable event ID and `X-AgentBox-Signature: t=<unix>,v1=<hmac>`. Deliveries retry with exponential backoff and enter a replayable dead-letter state after ten attempts.
Events are at-least-once. Consumers must deduplicate by event ID and persist their cursor.
## Optional intelligence
No model call is made unless `OPENAI_API_KEY` is set. The default embedding model is `text-embedding-3-small`; extraction uses a configurable structured-output model. AgentBox stores vectors locally in the reference deployment, fuses lexical and semantic ranks using reciprocal rank fusion, and validates every extraction against its JSON schema.
```bash
OPENAI_API_KEY=...
OPENAI_EXTRACTION_MODEL=gpt-5.6
OPENAI_EMBEDDING_MODEL=text-embedding-3-small
OPENAI_ESTIMATED_CENTS_PER_1K_TOKENS=0
```
Extractors run after durable ingest, never block receipt, and record a failure with `null` data when provider output does not validate. Attachment OCR/PDF extraction is not part of this release.
## SDKs and MCP
- TypeScript: [`sdk/typescript`](sdk/typescript)
- Python: [`sdk/python`](sdk/python)
- MCP server: [`src/mcp.ts`](src/mcp.ts)
Configure an MCP client to run:
```json
{
"mcpServers": {
"agentbox": {
"command": "npx",
"args": ["tsx", "/absolute/path/to/agentbox/src/mcp.ts"],
"env": {
"AGENTBOX_URL": "http://localhost:3000",
"AGENTBOX_API_KEY": "<agent-scoped-key>"
}
}
}
}
```
Tools include `list_agents`, `create_agent`, `list_messages`, `send_message`, `read_thread`, `reply_to_thread`, `wait_for_message`, and `search`.
## Config as code
Export the live hierarchy as YAML, review a dry-run diff including projected AWS calls, then apply it:
```bash
curl http://localhost:3000/v1/config/export -H 'Authorization: Bearer <root-key>' > agentbox.yaml
curl -X POST http://localhost:3000/v1/config/diff -H 'Authorization: Bearer <root-key>' -H 'Content-Type: text/yaml' --data-binary @agentbox.yaml
curl -X POST http://localhost:3000/v1/config/apply -H 'Authorization: Bearer <root-key>' -H 'Content-Type: text/yaml' --data-binary @agentbox.yaml
```
See [configuration reference](docs/CONFIGURATION.md). Secret access keys are intentionally never exported.
## Development
```bash
npm run check
```
This type-checks the server and TypeScript SDK, compiles the Python SDK, runs the full test suite, and builds production JavaScript. The suite covers receipt-rule preservation, signed SNS rejection, idempotent ingest/send, threading, loop prevention, lifecycle replay, tenant isolation, attachments, guardrails, webhook signing/retry, config apply, and structured extraction validation.
## Security
Read [SECURITY.md](SECURITY.md) before production use. Put AgentBox behind TLS, protect signup and login with edge rate limits, use agent-scoped runtime keys, restrict autonomous recipients, rotate bootstrap secrets, and keep the data volume encrypted and backed up. Browser sessions use HTTP-only, SameSite cookies; AWS credentials are separately encrypted with `ENCRYPTION_KEY`. Email is attacker-controlled model input; AgentBox guardrails limit effects but cannot make prompt injection disappear.
## License
MIT © Sagnik Ghosh. Sponsored by Autter.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues