Install
$ agentstack add skill-mr-kelly-skills-kelly-messenger ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Kelly Messenger
Overview
Use this skill as Kelly's unified chat inbox operator. It aggregates messages from WhatsApp, Discord, Slack, and Telegram (extensible to WeChat, iMessage, LINE, Messenger) into one file-backed App-in-Skill app: a command-desk overview, a unified inbox with chat transcripts and a reply composer, an outbox review queue for outgoing replies, and account/connector health.
Default interaction mode: App UI. Unless the user explicitly asks for chat-only handling, check onboarding/config, refresh or load the local message snapshot, start/reuse the local app with app/start.sh, and give the actual local URL. Use chat-only mode only when the user says "纯聊天", "chat only", "不要打开 UI", or similar.
App UI Screenshots
OverviewMessaging command desk with reply-decision counts, per-platform sync status, and oldest-waiting indicator. ConversationChat transcript with an agent-suggested reply prefilled in the composer, ready to edit and queue.
Unified inboxConversations across WhatsApp, Slack, Discord, and Telegram sorted by latest activity with waiting-time badges. Reply outboxApproval queue for outgoing replies: every message is reviewed before the agent sends it via platform connectors.
Boundary
- The app reads and writes local files only and never touches any network beyond
127.0.0.1. It cannot send messages: the composer only queues drafts into the local outbox. - Every outgoing message is approval-required. The skill executes only replies whose outbox status is
approved, viascripts/send_outbox.ts(dry-run by default) or, forbrowser_agent/manualconnectors, by the agent performing the handoff after--sendmarks themhandoff_to_agent. - Own accounts only: read and send exclusively through accounts the user owns and has configured. Respect each platform's terms of service and rate limits; prefer official APIs; keep sync read-only.
- Never store passwords, QR-login payloads, or session tokens. For
browser_agentcollection the agent drives the user's own already-authenticated web session and stores only message text needed for review. - Treat all chat content as sensitive. Do not commit
config.local.json, env files,app/.data/, exports, tokens, or customer PII.
First Run And Onboarding
On invocation, check app/.data/onboarding.json and private config readiness. If onboarding is absent/incomplete, guide setup before syncing real accounts.
Private config priority:
KELLY_MESSENGER_CONFIG=/absolute/path/to/config.jsonskills/kelly-messenger/config.local.json~/.config/kelly-messenger/config.jsonskills/kelly-messenger/config.example.jsonas template only
Env priority:
- Existing environment variables
KELLY_MESSENGER_ENV_FILE=/absolute/path/to/.env- Repository root
.env skills/kelly-messenger/.env.local~/.config/kelly-messenger/.env
Onboarding asks, turn by turn: which platforms to connect, which connector method per account, and which env var names hold the tokens. Ask for non-secret details only: platform, display name, workspace/server, channels or chats to watch, reply style, and env var names. Never ask the user to paste secret values into chat; secrets belong only in local env files.
Connector reality per platform (declare as "connector" on each account):
slack— official Web API (conversations.historyto read,chat.postMessageto send) with a bot/user token from env (bot_token_env/user_token_env).discord— official REST API with a bot token from env (bot_token_env); the bot must be in the servers/channels it should read.telegram— Telegram Bot API (getUpdatesto read,sendMessageto send) with a bot token from env (bot_token_env); the bot must share the chats.whatsapp_cloud— WhatsApp Business Cloud API withaccess_token_env+phone_number_id_env. Inbound messages arrive via webhook only, so history is collected via ingest; sends use the Cloud API.browser_agent— the agent drives the user's own web session (e.g. WhatsApp Web) with the browser skill, then writes a payload throughscripts/ingest_messages.ts. No passwords or QR secrets are ever stored.manual— the user or agent prepares an ingest payload by hand. Use for anything else (WeChat, iMessage, LINE, Messenger).
When setup is complete and the user confirms, write app/.data/onboarding.json:
{
"completed": true,
"completed_at": "ISO timestamp",
"config_version": "1"
}
Local App
Start the app with:
skills/kelly-messenger/app/start.sh
The app uses local HTTP on 127.0.0.1, preferring ports 3000 through 4000, or KELLY_MESSENGER_UI_PORT when set. /api/state identifies the app as kelly-messenger.
Required app views (hash routes):
#/overview: messaging command desk. Human-attention numbers (conversations needing a reply decision, approved replies waiting for send, blocked), oldest-waiting indicator, per-platform account cards (unread, conversations, last sync, connector method), and recent activity.#/inboxand#/inbox/: the unified inbox. Left: conversations across all platforms sorted by latest activity with platform badge, title, preview, unread dot, and waiting time. Right: chat transcript (incoming left, Kelly's outgoing right, sender names, timestamps, channel/workspace metadata) plus a reply composer with an agent-suggested_replyprefill when present, a note field, and aQueue replybutton. Queued replies appear as dashed "queued" bubbles.#/outbox: review queue over outgoing replies with workflow statesneeds_review/changes_requested/approved/done/blocked, stable refs (Reply #1), editable draft text, reason/context, and decision buttons (approve / request changes / save edit / block).donemeans sent, with the execution result shown.#/accounts: connected accounts with platform, workspace, connector method, env readiness boolean, last sync, conversation/unread counts, and warnings.#/settings: sanitized config summary (data provider, config path, onboarding state, reply style, accounts with env readiness booleans), sync log, and last execution report. Never secrets.
Demo mode:
?demo=overview,?demo=inbox,?demo=chat(opens the featured conversationwa-lena-pricingwith an agent-suggested reply prefilled), and?demo=outboxselect named deterministic mock scenes.lang=enorlang=zhforces UI chrome language for screenshots. Deep links such as/?demo=chat&lang=en#/inbox/wa-lena-pricingwork.- Demo mode never reads or writes
app/.data/. Composer and outbox buttons still work but act on in-memory state only and show a demo notice.
UI language: English and Chinese chrome with Auto default following the browser language; explicit selector persisted locally. Keep message content, sender names, and chat titles in their original language.
File Contract
Read references/messenger-schema.md before editing the app, scripts, or any generated JSON.
app/.data/messages_snapshot.json: accounts, conversations with transcripts, metrics, sync log. Written only byscripts/sync_messages.tsandscripts/ingest_messages.ts.app/.data/outbox.json: the decisions file — queued/decided outgoing replies keyed by reply id with conversation ref, text, status, decision, timestamps.app/.data/agent_tasks.json: queued agent work;request_changesdecisions land here asrevise_replytasks.app/.data/execution_report.json: latest send run results.app/.data/onboarding.json: onboarding completion marker.app/.data/agent.lock: temporary lock while the skill syncs, ingests, or sends. While it exists the app rejects writes and renders the composer and outbox read-only.
Validate with node scripts/validate_ui_schema.ts before relying on a snapshot in the UI.
Sync Workflow
- Detect mode. Default to App UI.
- Load private config. If only
config.example.jsonexists, enter onboarding. - For API connectors (
slack,discord,telegram,whatsapp_cloud), runnode scripts/sync_messages.ts. It uses global fetch only, prints a clear friendly message when tokens are missing, refuses to run under an active lock, acquires the lock itself, merges into the snapshot by stable message ids, appendssync_logentries, and releases the lock. - For
browser_agentplatforms, use the browser skill on the user's own session to read conversations, build an ingest payload (see the schema), and runnode scripts/ingest_messages.ts payload.json— the single write-path for collected messages. Same formanual. - Start/reuse the UI and report the URL. Surface connector problems as snapshot warnings, not silent failures.
Reply And Outbox Workflow
- Queue: the user writes or edits a reply in the composer (optionally starting from the agent's
suggested_reply) and clicksQueue reply; the app writes it tooutbox.jsonasneeds_review. The agent may also queue drafts (suggested_by: "agent") with areason. - Review: in
#/outboxthe user approves, edits (Save edit), requests changes, or blocks each reply.request_changesenqueues arevise_replytask inagent_tasks.json. - Agent revision loop: poll
agent_tasks.json, redraft the reply text honoring the comment and the configreply_style, set the reply back toneeds_review, and mark the task done. - Send: only after the user asks to send, run
node scripts/send_outbox.ts(dry-run) and show the plan. With explicit approval, runnode scripts/send_outbox.ts --send: it re-checks the lock and each reply's approval immediately before sending, sends API-connector replies via the official APIs, marksbrowser_agent/manualreplies ashandoff_to_agentfor the agent to deliver through the user's session, sets sent replies todone, and writesexecution_report.json. - Report per-reply results back to the user with the stable
Reply #Nrefs.
Safety Defaults
- Never send without an
approvedstatus recorded in the outbox, and never bypass the dry-run →--sendsequence. - Prefer read-scoped tokens where the platform offers them; keep sync strictly read-only.
- Redact tokens and token-like strings from logs, reports, and UI state; expose only env-var readiness booleans.
- Keep sends idempotent: stable reply ids, execution results stored on the reply, and re-reading decisions before each send.
- If a send target is missing (
provider_conversation_id), block that reply and ask for configuration instead of guessing. - Honor platform rate limits; on 429s back off rather than retrying aggressively.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: mr-kelly
- Source: mr-kelly/skills
- License: MIT
- Homepage: https://mr-kelly.github.io/skills/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.