Agent comms
Agent comms is Molar's communication relay for test scenarios. It receives inbound SMS, email, and voice webhooks, persists payloads, and exposes OTP polling for sign-in flows that use one-time codes.
Package: @molar/agent-comms-core (port 8790 in local dev)
What it does
| Endpoint | Purpose |
|---|---|
POST /webhook | Signed inbound webhooks (message.received, text.received, calls) |
WebSocket /phone/media/ws | Live phone media (optional voice agent demo) |
POST /otp/poll | Cartographer polls for extracted OTP codes |
| OTP tunnel | Hosted relay for synthetic test numbers and mailboxes |
Production OTP poll endpoint: https://otp.molar.it/otp/poll (or your self-hosted agent comms URL)
Why it exists
Real user flows often need:
- SMS OTP from Clerk, Auth0, or custom auth
- Email magic links and verification codes
- Voice IVR steps (advanced)
Clones fake the vendor APIs, but something must receive the OTP message. Agent comms fills that gap without sending tests through production SMS/email.
OTP extraction flow
- Scenario uses a synthetic phone or email provisioned for the run
- Your app sends OTP to that address (or a Clone emulates send → agent comms receives)
- Webhook hits agent comms; code extracted (regex first, LLM fallback if needed)
- Cartographer polls
/otp/pollwith bearer secret
Poll API
POST https://otp.molar.it/otp/poll
Authorization: Bearer <MOLAR_OTP_POLL_SECRET>
Content-Type: application/json
{"totp_identifier": "+15551234567"}
Response:
{"verification_code": "482901"}
Or {} while waiting (poll with backoff).
Configure webhook_url on credentials and map totp_identifier to the expected sender. See Cartographer auth/otp_service.py.
Run locally
pnpm --filter @molar/agent-comms-core dev
# Or Python package directly
cd packages/agent-comms-core/python
cp .env.example .env
uv sync && uv run molar-comms-server
Required environment variables
| Variable | Purpose |
|---|---|
MOLAR_AGENT_COMMS_API_KEY | Agent comms API authentication |
MOLAR_AGENT_COMMS_SIGNING_KEY | Webhook signature verification |
MOLAR_AGENT_COMMS_TUNNEL_NAME | Tunnel subdomain (e.g. molar-agent) |
OPENAI_API_KEY | LLM fallback for OTP extraction / voice demo |
Optional:
| Variable | Default | Purpose |
|---|---|---|
MOLAR_AGENT_COMMS_API_BASE | Molar cloud | Comms API host |
MOLAR_AGENT_COMMS_TUNNEL_ZONE | molar.it | Tunnel parent domain |
LISTEN_PORT | 8790 | HTTP listen port |
MOLAR_AGENT_COMMS_REQUIRE_SIGNATURE | true | Reject unsigned webhooks (set false local only) |
USE_OPENAI_REALTIME | false | Bridge phone WS to OpenAI Realtime |
Received payloads are written to python/payloads/ for debugging.
Production defaults
For the hosted Molar relay:
MOLAR_AGENT_COMMS_API_BASE=https://api.molar.it
MOLAR_AGENT_COMMS_TUNNEL_ZONE=molar.it
MOLAR_AGENT_COMMS_TUNNEL_NAME=molar-agent
LISTEN_PORT=8790
Security
- Webhooks require a valid signature header when
MOLAR_AGENT_COMMS_REQUIRE_SIGNATURE=true - OTP poll endpoint requires
MOLAR_OTP_POLL_SECRET— not public - Tunnel uses outbound HTTP/2 only (no inbound firewall holes)
Scenario integration
Declare synthetic user in frontmatter:
synthetic_user:
pattern: 'test-${run.id}@molar.it'
Use ${synthetic_user.email} or phone fields in steps; pair with Clerk/email Clone setup in ## Setup.
Related
- Clones — email and auth vendor clones
- Scenario compiler — synthetic_user
- LLM gateway — separate from OTP extraction OpenAI key
- Environment variables