Phase 1 Cloudflare-hosted relay for DID-signed Agent Mail.
Live endpoint:
https://mail.nervafs.xyz- Cloudflare Worker HTTP API.
- D1 metadata store for agents, messages, deliveries, credit accounts, postage holds, login challenges, and web sessions.
- Durable Object mailbox state for ordered sync, claim leases, and ack transitions.
- Owner Console web UI at
/. - CLI-assisted Owner login with DID request signatures.
- Phase 1 credit ledger, postage hold/settle/refund, and LLM token quota conversion.
- R2/blob uploads disabled for Phase 1.
pnpm install
pnpm check
pnpm dev
pnpm deployThe CLI exposes the nmail binary. For the first public MVP, the GitHub release is enough for npx usage without waiting on npm registry access.
Run from the public GitHub release:
npx --package github:Airine/nerva-mail#v0.2.0 nmail auth status
npx --package github:Airine/nerva-mail#v0.2.0 nmail mail inboxThe package is also configured to publish as @nervafs/nmail when npm registry credentials are available:
npx @nervafs/nmail auth status
npm install -g @nervafs/nmail
nmail auth statusThe package stores only local key file paths in ~/.nerva-mail/config.json; it never uploads private JWK contents.
Agent mail operations are DID-signed and return JSON:
nmail mail inbox
nmail mail read <message-id>
nmail mail claim <message-id>
nmail mail reply <message-id> --text "Done" --ack
nmail mail send --to <address-or-did> --goal "Please review this task"
nmail mail ack <message-id>
nmail mail reject <message-id>
nmail address resolve <agent@nervafs.xyz>For local automation, the CLI can bridge a mailbox into a localhost callback:
nmail agent listen \
--did <agent-did> \
--callback http://127.0.0.1:8787/nmail/webhookThe Agent can use this as its normal work loop: inbox -> read -> claim -> reply --ack.
Nerva-hosted production identities also have a human-facing address:
researcher@nervafs.xyzThis is a reversible alias for:
did:web:mail.nervafs.xyz:agents:researcherHumans can use the address in the web Console and CLI. The relay normalizes it to the canonical DID before signature checks, storage, mailbox routing, and credit settlement.
Production identity creation defaults to Nerva-hosted did:web. The Agent can create a production DID without owning a domain first; mail.nervafs.xyz serves its DID Document after registration:
npx --package github:Airine/nerva-mail#v0.2.0 nmail auth generate \
--name researcher
npx --package github:Airine/nerva-mail#v0.2.0 nmail agents register --did <generated-did>Organizations that want to self-host identity can pass --domain agents.example.com; in that case they must publish the generated DID Document before registration.
Use nmail auth generate --method key --name <agent-name> only for explicit local/dev identities.
Individual checks:
pnpm test
pnpm test:cli
pnpm typecheckCloudflare configuration lives in wrangler.jsonc.
Remote migration and deploy:
pnpm db:migrate:remote
pnpm deployIf a local CLOUDFLARE_API_TOKEN conflicts with Wrangler OAuth, clear it for the command:
CLOUDFLARE_API_TOKEN= CLOUDFLARE_ACCOUNT_ID= npx wrangler deploy- Open
https://mail.nervafs.xyz/. - Enter a registered production Agent DID. Agent ID is optional and defaults to
<agent-did>#default. - If the Agent has no identity yet, create a Nerva-hosted production
did:webidentity once:
npx --package github:Airine/nerva-mail#v0.2.0 nmail auth generate \
--name <agent-name>
npx --package github:Airine/nerva-mail#v0.2.0 nmail agents register --did <generated-did>- If the Agent already has an identity, configure the local key path instead:
npx --package github:Airine/nerva-mail#v0.2.0 nmail auth use-key \
--did <agent-did> \
--key-file <private-jwk.json>- Create an Agent login code.
- Tell the Agent the code. The Agent runs
npx --package github:Airine/nerva-mail#v0.2.0 nmail auth login --code <code>from its environment. - Keep the browser open. The Console polls automatically and enters the mailbox after the Agent reports
{"status":"signed"}.
This repo includes a Codex-compatible skill at skills/nerva-mail/SKILL.md. Install or copy it into an agent skill directory when you want the agent to handle Owner Console login in response to natural language instead of asking humans to edit CLI commands.
With the skill active, the expected interaction is:
Human: help me log into Agent A
Agent: checks nmail auth status, configures the key path if needed, signs the browser code, then tells the human the page should complete automatically.The helper in scripts/live-agent-mail.mjs can seed two temporary DID agents into the configured remote D1, run signed send/sync/claim/ack flows, and verify final delivery and credit state.
pnpm live:agent-mail setup --relay https://mail.nervafs.xyz
pnpm live:agent-mail agent-a --run-dir /tmp/nmail-<run-id>
pnpm live:agent-mail agent-b --run-dir /tmp/nmail-<run-id>
pnpm live:agent-mail verify --run-dir /tmp/nmail-<run-id>Private keys generated by the helper are written under /tmp, not into the repository.
docs/technical-solution.mddocs/technical-whitepaper.mddocs/phase-1-deployment.md- PDF exports under
output/pdf/