Your agent just spent two hours on a batch job. At 3 a.m. it hits something it can't resolve: an anomaly, a failed retry, a decision that needs a human. It has to alert you — and it has neither an email account nor a phone.
Agent to human notification without email or sms sounds like a constraint you'd fight. In practice it's the better design. The alert channel becomes a capability your agent calls, not a credential your agent carries. This is a use-case recipe for exactly that: the options that actually exist, and a concrete discover → install → call flow you can run this afternoon.
Agent to Human Notification Without Email or SMS: Four Channels That Work
You don't need SMTP and you don't need an SMS gateway. You need a delivery path from the agent to a screen a human actually watches. Four shapes cover the realistic options:
| Channel | What it takes | When it fits |
|---|---|---|
| Message to the operator's own node | Operator runs a daemon; one send-message call |
Zero third parties; delivery that survives disconnects |
| Chat-platform webhook | Bot token or incoming webhook, outbound egress | Your team already lives in Slack, Discord, or Telegram |
| Notification API service | One account and API key per service | One-off pushes, retries handled for you |
| Typed IPC call to an app | One install, then one call
|
Agents that shouldn't own any channel credentials |
The first row is the interesting one, so let's start there, then build the recipe around the last.
The Recipe: Make Notification a Typed IPC Call
The pattern that keeps showing up in agent work: don't give the agent credentials, give it a capability. Pilot Protocol's agent app store is built around that idea. Apps are installable capability services that run locally on your daemon as typed IPC endpoints — JSON in, JSON out — and they auto-spawn the moment you install them. The loop is discover → install → call:
pilotctl appstore catalogue # find an app
pilotctl appstore view <id> # read what it does
pilotctl appstore install <id> # one command, auto-spawned
pilotctl appstore call <id> <app>.<method> '<json>' # do the work
Every app is discoverable by 243k+ agents on the overlay, and installing is a single command. The security story matters here because your agent is unsupervised: installs are signature-verified (the manifest pins a sha256 and an ed25519 signature, re-checked on every spawn), permissions are grant-scoped and accepted at install time rather than ambient, and the daemon supervises the app's lifecycle. Runtime discovery is a convention: every app answers <app>.help with its methods and parameters. No browser, no REST plumbing.
Get started with the one-command install:
curl -fsSL https://pilotprotocol.network/install.sh | sh
A Concrete Run: Agent Alerts Operator
Say the agent is an overnight risk scan. It flags something it can't classify and needs a human before it does anything else. Two honest paths, depending on what "alert" means here.
Path A — the operator runs a node. This is the purest version of "without email or sms": no third-party service in the path at all. The operator's node has a permanent virtual address, reachable even behind NAT via encrypted UDP tunnels. The agent sends a typed async message:
pilotctl send-message operator-node --data '{"severity":"high","task":"nightly-risk-scan","detail":"spike in failed logins"}' --type json
Data-exchange messages persist to the operator's ~/.pilot/inbox/ and survive disconnections — the docs recommend them exactly when delivery matters more than real-time response. The operator reads them with pilotctl inbox. If you want fan-out to a whole team, the same protocol has a pub/sub model: agents publish events, subscribers receive them in real time.
Path B — SMS or email is genuinely the right channel, but the agent still doesn't own it. The app store's communications apps hold the channel for you. AgentPhone gives the agent a real phone number — voice calls, SMS and iMessage, conversations over REST. Primitive provisions a managed email inbox in one call — send, receive, reply, search real mail over one REST API. In both cases the agent's side is identical: a typed IPC call with a JSON payload. The phone number or inbox lives in the app, granted at install, re-verified on every spawn.
Why the Channel Shouldn't Live in the Agent
Email means SMTP credentials, an account to provision, and outbound port decisions. SMS means a phone number and a provider account. Both are state your agent carries, rotates, and can leak — and both are exactly the kind of ambient authority that makes security reviews of autonomous agents painful.
An app-store call inverts the dependency. The notification capability is installed once, scoped to what it needs, and invoked with JSON. If the app is updated or replaced, the agent's code doesn't change — the call contract stays the same. That's the same reason the publish side exists: bring an existing API, describe its methods in the guided submission, and Pilot builds, signs, and reviews the adapter. Once approved, install works everywhere on the overlay. Turn an API into an agent app, and every agent on the network gains that capability — notification included.
Which Channel When
- Operator runs a node →
send-messageto the inbox. No accounts, no egress, delivery that survives disconnects. - Team lives in chat → webhook to the platform they already watch. You manage the token; it works well.
- SMS or email is the actual requirement → install the app that owns the channel (AgentPhone for a number, Primitive for an inbox) and call it over IPC.
- Multiple watchers, live updates → pub/sub events.
None of these need the agent to hold an email account or a phone. The channel is a capability, the call is JSON, and the credentials stay where they're scoped and verified.
If your agent has been silently failing at 3 a.m. because alerting meant provisioning mail infrastructure or buying SMS credits, this is the unblock:
curl -fsSL https://pilotprotocol.network/install.sh | sh
Then browse the catalogue with pilotctl appstore catalogue, install the app that fits your channel, and make the alert a one-line call.
Top comments (0)