ping-a-human
v0.1.6
Published
An MCP server that adds a human-in-the-loop step to any AI pipeline by reaching a human on their own messaging app (Telegram first).
Maintainers
Readme
ping-a-human
An open-source Model Context Protocol (MCP) server that adds a human-in-the-loop step to any AI pipeline, agent, or automation. It lets an AI notify a human or ask a human and wait for their answer — reaching the person on the messaging app they already use (Telegram first; Slack, WhatsApp, and more later).
Unlike MCP's built-in elicitation (which prompts inside the AI client UI), ping-a-human reaches the
human out-of-band on their own messaging app, so it works even when nobody is watching the AI
session.
Tools
The server exposes two tools over stdio:
notify_human— fire-and-forget. Sends a message to the configured human and returns immediately without waiting for a reply.- Input:
{ message: string }
- Input:
ask_human— sends a question, then blocks until the human replies (or a timeout elapses) and returns their answer.- Input:
{ question: string, choices?: string[], timeoutMs?: number } - With
choices, the options render as tappable Telegram inline buttons and the tapped value is returned (e.g.["Yes", "No"]). - On timeout it returns a clear timed-out result instead of an error, so the calling agent gets a clean signal. Default timeout is 5 minutes.
- Input:
Install
No clone or build required. The server runs straight from npm via your package runner:
npx ping-a-human setup # npm
bunx ping-a-human setup # bun
pnpm dlx ping-a-human setup # pnpmYour MCP client (Claude Desktop, Cursor, etc.) launches it the same way (see step 2) — so end users never install anything globally. Cloning the repo is only needed for contributing.
Quickstart
1. Create a Telegram bot and configure the server
Run the interactive setup wizard — it validates your bot token, auto-detects your chat id, writes the config, and prints the MCP client entry to paste:
npx ping-a-human setupThe wizard walks you through:
- Message @BotFather in Telegram, send
/newbot, and copy the bot token. - Paste the token when prompted — the wizard verifies it via Telegram and shows your bot's
@username. - Send your new bot any message (e.g. "hi") in Telegram, then press Enter — the wizard auto-detects
your
chat_id. - The config is saved to
~/.config/ping-a-human/config.jsonand the wizard prints anmcpServerssnippet.
2. Add the server to your MCP client
Add this to your MCP client config (Claude Desktop, Cursor, etc.):
{
"mcpServers": {
"ping-a-human": {
"command": "npx",
"args": ["-y", "ping-a-human"]
}
}
}Restart the client. It will list notify_human and ask_human.
3. Use it from an agent
- Notify when a long job finishes:
notify_human({ message: "Deploy to prod finished ✅" }). - Ask before a risky action:
ask_human({ question: "Apply this DB migration to prod?", choices: ["Yes", "No"] })— the human taps a button and the agent receives"Yes"or"No". - Ask an open question:
ask_human({ question: "What should the release title be?" })— the agent receives the human's free-text reply.
Configuration
The server reads configuration with this precedence:
- Environment variables
TELEGRAM_BOT_TOKENandTELEGRAM_CHAT_ID(both required together). - A config file at
$PING_A_HUMAN_CONFIG, or~/.config/ping-a-human/config.jsonby default, shaped as:
{ "telegram": { "botToken": "123456:ABC-...", "chatId": "4242" } }The bot token is a secret — it is never logged or echoed. All diagnostics go to stderr; stdout is reserved for the MCP JSON-RPC channel.
Use it in pi
Using the pi coding agent? One command wires ping-a-human into
pi's hooks for notifications, human-in-the-loop approval, a /ping command, and a
global pah CLI:
npx ping-a-human-piSee the ping-a-human-pi package or the
pi guide.
Local development
npm install
npm run build
node dist/index.js # starts the stdio MCP server
node dist/index.js setup # runs the setup wizard
npm test # runs the full test suiteLive smoke test (optional)
With real credentials set, send a real message and wait for a reply:
TELEGRAM_BOT_TOKEN=... TELEGRAM_CHAT_ID=... node scripts/smoke-telegram.mjsWithout credentials it prints a skip notice and exits 0, so it is safe in CI.
End-to-end verification (live)
A repeatable manual procedure that exercises the whole loop against real Telegram:
- Create a bot. In Telegram, message @BotFather, send
/newbot, and copy the token. - Run setup.
npx ping-a-human setup— paste the token, message your bot when prompted, and let the wizard auto-detect yourchat_idand write the config. - Wire up a client. Add the printed
mcpServerssnippet to Claude Desktop / Cursor and restart. - Prove
ask_humanwith buttons. From the client, callask_human({ question: "Proceed?", choices: ["Yes", "No"] }). You should receive a Telegram message with two buttons; tap one and confirm the agent receives that exact value. - Prove
notify_human. Callnotify_human({ message: "hello from my agent" })and confirm the message arrives and the call returns immediately. - Prove the timeout. Call
ask_human({ question: "...", timeoutMs: 10000 })and do not reply; after ~10s the agent should receive a clear timed-out result (not an error).
No MCP client handy? The credential-gated smoke script exercises the live send → reply path directly:
TELEGRAM_BOT_TOKEN=... TELEGRAM_CHAT_ID=... node scripts/smoke-telegram.mjsLicense
MIT — see LICENSE.
