{"_id":"@anthony-maio/halobot","_rev":"3-fe3b8a12f9e110f0b586884ba61ee83a","name":"@anthony-maio/halobot","dist-tags":{"latest":"2.2.0"},"versions":{"2.1.0":{"name":"@anthony-maio/halobot","version":"2.1.0","keywords":["mcp","discord","ai-agent","human-in-the-loop","claude","model-context-protocol","halobot"],"author":{"name":"Anthony Maio"},"license":"ISC","_id":"@anthony-maio/halobot@2.1.0","maintainers":[{"name":"anthony-maio","email":"anthony.maio@gmail.com"}],"homepage":"https://github.com/anthony-maio/halobot#readme","bugs":{"url":"https://github.com/anthony-maio/halobot/issues"},"bin":{"halobot":"dist/index.js"},"dist":{"shasum":"7c13b3c15302340018a08b4c3c1fea6192745d63","tarball":"https://registry.npmjs.org/@anthony-maio/halobot/-/halobot-2.1.0.tgz","fileCount":9,"integrity":"sha512-xXtkp/oQRdxBKqdYxyw5X7dAFm84cXce9KmsPGYWhFfCmJC8Rn0fwNEp8dTkVzqs+RRwResXU+pH7OpkVbN1Jw==","signatures":[{"sig":"MEUCICV4JvuHiQhD95wjmWIudOZEqQnaeHkQ4pbs9GtuBvIAAiEAnPxRF9zrSqstbUpCyIkilCOMISMnQ3qJv0f1+sB3Few=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":63469},"main":"dist/index.js","type":"commonjs","types":"./dist/index.d.ts","gitHead":"73f4471d65604403279661315eb5068ebadcc2bf","scripts":{"dev":"tsx src/index.ts","test":"tsx src/index.test.ts","build":"tsc","setup":"tsx src/index.ts setup","start":"node dist/index.js","doctor":"tsx src/index.ts doctor"},"_npmUser":{"name":"anthony-maio","email":"anthony.maio@gmail.com"},"overrides":{"undici":"^6.24.1","path-to-regexp":"^8.4.1"},"repository":{"url":"git+https://github.com/anthony-maio/halobot.git","type":"git"},"_npmVersion":"10.9.3","description":"MCP server that connects AI agents to humans via Discord threads (Human-Agent Loop Over Bot)","directories":{},"_nodeVersion":"22.20.0","dependencies":{"zod":"^4.3.6","dotenv":"^17.3.1","discord.js":"^14.25.1","@modelcontextprotocol/sdk":"^1.29.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","typescript":"^5.9.3","@types/node":"^24.12.0"},"_npmOperationalInternal":{"tmp":"tmp/halobot_2.1.0_1774973438241_0.02458879353258414","host":"s3://npm-registry-packages-npm-production"}},"2.1.1":{"name":"@anthony-maio/halobot","version":"2.1.1","keywords":["mcp","discord","ai-agent","human-in-the-loop","claude","model-context-protocol","halobot"],"author":{"name":"Anthony Maio"},"license":"ISC","_id":"@anthony-maio/halobot@2.1.1","maintainers":[{"name":"anthony-maio","email":"anthony.maio@gmail.com"}],"homepage":"https://github.com/anthony-maio/halobot#readme","bugs":{"url":"https://github.com/anthony-maio/halobot/issues"},"bin":{"halobot":"dist/main.js"},"dist":{"shasum":"f1ee1083cb7037189c75dc01dfa28f5b25ac3b28","tarball":"https://registry.npmjs.org/@anthony-maio/halobot/-/halobot-2.1.1.tgz","fileCount":10,"integrity":"sha512-k/9BrPgfsuEeV1fV+rnd6ubKzhOkBAuxkjf3kbZz4eLlbotEbFJC/CQaVezybzBs19loVTtFd/ZrfiCfacmE8w==","signatures":[{"sig":"MEYCIQCG1c2ujFjNC3L6rydV3Ql5khopRyCGAXrTB3gXmbW9yAIhAJ1QjTEV77KAO4RVlUccREMe8nujp4nY4oy1aLloAtaR","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":63367},"main":"dist/main.js","type":"commonjs","types":"./dist/main.d.ts","gitHead":"32e655751efac7c56ceedb277fe9de205ac5e069","scripts":{"dev":"tsx src/index.ts","test":"tsx src/index.test.ts","build":"tsc","setup":"tsx src/index.ts setup","start":"node dist/index.js","doctor":"tsx src/index.ts doctor"},"_npmUser":{"name":"anthony-maio","email":"anthony.maio@gmail.com"},"overrides":{"undici":"^6.24.1","path-to-regexp":"^8.4.1"},"repository":{"url":"git+https://github.com/anthony-maio/halobot.git","type":"git"},"_npmVersion":"10.9.3","description":"MCP server that connects AI agents to humans via Discord threads (Human-Agent Loop Over Bot)","directories":{},"_nodeVersion":"22.20.0","dependencies":{"zod":"^4.3.6","dotenv":"^17.3.1","discord.js":"^14.25.1","@modelcontextprotocol/sdk":"^1.29.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","typescript":"^5.9.3","@types/node":"^24.12.0"},"_npmOperationalInternal":{"tmp":"tmp/halobot_2.1.1_1774978972984_0.12377533319127498","host":"s3://npm-registry-packages-npm-production"}},"2.2.0":{"name":"@anthony-maio/halobot","version":"2.2.0","description":"MCP server that connects AI agents to humans via Discord threads (Human-Agent Loop Over Bot)","main":"dist/main.js","bin":{"halobot":"dist/main.js"},"scripts":{"build":"tsc","start":"node dist/index.js","dev":"tsx src/index.ts","test":"tsx src/index.test.ts","setup":"tsx src/index.ts setup","doctor":"tsx src/index.ts doctor"},"repository":{"type":"git","url":"git+https://github.com/anthony-maio/halobot.git"},"keywords":["mcp","discord","ai-agent","human-in-the-loop","claude","model-context-protocol","halobot"],"author":{"name":"Anthony Maio"},"license":"ISC","type":"commonjs","bugs":{"url":"https://github.com/anthony-maio/halobot/issues"},"homepage":"https://github.com/anthony-maio/halobot#readme","dependencies":{"@modelcontextprotocol/sdk":"^1.29.0","discord.js":"^14.25.1","dotenv":"^17.3.1","zod":"^4.3.6"},"devDependencies":{"@types/node":"^24.12.0","tsx":"^4.21.0","typescript":"^5.9.3"},"overrides":{"undici":"^6.24.1","path-to-regexp":"^8.4.1"},"_id":"@anthony-maio/halobot@2.2.0","gitHead":"32e655751efac7c56ceedb277fe9de205ac5e069","types":"./dist/main.d.ts","_nodeVersion":"22.20.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-MKL0Fx14GMsjrmf9frHZV7h4cErRCrRmJoeuTq/wm2np4oFrSXNNLZ12GdAkzXbwhMH2OlzJcA+H46V9QIBGIQ==","shasum":"0dab54c68175455a58bf3e99d67b71a29f6be12e","tarball":"https://registry.npmjs.org/@anthony-maio/halobot/-/halobot-2.2.0.tgz","fileCount":10,"unpackedSize":72550,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDI9CujlK7YMgY6XBxfyZAB9OKbllasuc2DYXD+eQA+zwIhAP87oRORJTsqwhCvxQLYTnOsNs53fZiyXPHA1yshoK3L"}]},"_npmUser":{"name":"anthony-maio","email":"anthony.maio@gmail.com"},"directories":{},"maintainers":[{"name":"anthony-maio","email":"anthony.maio@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/halobot_2.2.0_1775269396704_0.00571915087978736"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-31T16:10:38.164Z","modified":"2026-04-04T02:23:16.976Z","2.1.0":"2026-03-31T16:10:38.404Z","2.1.1":"2026-03-31T17:42:53.168Z","2.2.0":"2026-04-04T02:23:16.851Z"},"bugs":{"url":"https://github.com/anthony-maio/halobot/issues"},"author":{"name":"Anthony Maio"},"license":"ISC","homepage":"https://github.com/anthony-maio/halobot#readme","keywords":["mcp","discord","ai-agent","human-in-the-loop","claude","model-context-protocol","halobot"],"repository":{"type":"git","url":"git+https://github.com/anthony-maio/halobot.git"},"description":"MCP server that connects AI agents to humans via Discord threads (Human-Agent Loop Over Bot)","maintainers":[{"name":"anthony-maio","email":"anthony.maio@gmail.com"}],"readme":"# halobot\r\n\r\n**Human-Agent Loop Over Bot** — an MCP server that gives any AI agent a Discord communication channel, from low-level message access to high-level, thread-based human-in-the-loop conversations.\r\n\r\n**Why does this exist?** Claude Code has dispatch. Cursor has its own notification system. Every AI tool reinvents \"talk to the human.\" This is the MCP answer: one Discord server, any agent, zero vendor lock-in.\r\n\r\n## How It Works\r\n\r\n```\r\n┌─────────────┐     STDIO/MCP      ┌──────────────────┐     Discord API    ┌─────────────┐\r\n│  Any Agent   │◄──────────────────►│    halobot       │◄──────────────────►│   Discord    │\r\n│ (Claude Code,│                    │   MCP Server     │   create thread    │   Server     │\r\n│  Cursor,     │  11 MCP tools      │                  │   post message     │              │\r\n│  custom)     │                    │   Discord Bot    │   wait for reply   │  👤 You      │\r\n└─────────────┘                     └──────────────────┘                    └─────────────┘\r\n```\r\n\r\n### Thread-Based Conversations (Recommended)\r\n\r\n1. Agent calls `send_thread_message` — bot creates a thread, pings you\r\n2. You reply in the thread\r\n3. Agent calls `wait_for_reply` to get your response\r\n4. Long messages automatically chunk across multiple Discord messages\r\n\r\n### Low-Level Access\r\n\r\nAgents can also directly list guilds/channels, send raw messages, read cache, fetch history, and poll for keyword matches — useful for monitoring, logging, or custom flows.\r\n\r\n## MCP Tools\r\n\r\n### High-Level (Thread Conversations)\r\n\r\n| Tool | Description |\r\n|------|-------------|\r\n| `send_thread_message` | Send a message to a whitelisted user via a thread. Creates a new thread or posts in an existing one. |\r\n| `wait_for_reply` | Poll a thread for the human's reply (configurable timeout). |\r\n| `send_and_wait` | Send + wait in one call. Best for simple Q&A exchanges. |\r\n| `list_conversations` | List all active thread conversations. |\r\n| `get_thread_messages` | Fetch full message history from a thread. |\r\n\r\n### Low-Level (Raw Discord)\r\n\r\n| Tool | Description |\r\n|------|-------------|\r\n| `list_guilds` | List all servers the bot is in. |\r\n| `list_channels` | List text channels in a guild. |\r\n| `send_message` | Send a message to any channel. |\r\n| `read_messages` | Read recent messages from the in-memory cache. |\r\n| `get_channel_history` | Fetch paginated message history via API. |\r\n| `wait_for_message` | Poll until a matching message arrives (keyword filter). |\r\n\r\n## Quick Start\r\n\r\n```bash\r\n# Install globally\r\nnpm install -g @anthony-maio/halobot\r\n\r\n# Interactive setup — walks you through everything\r\nhalobot setup\r\n```\r\n\r\nThe setup wizard will:\r\n1. Link you to the Discord Developer Portal to create a bot\r\n2. Generate the invite URL with correct permissions\r\n3. Collect your channel and user IDs\r\n4. Validate everything works (login, permissions, channel access)\r\n5. Optionally add halobot to Claude Code automatically\r\n\r\n### Manual Setup\r\n\r\nIf you prefer to configure manually:\r\n\r\n#### 1. Create a Discord Bot\r\n\r\n1. Go to [Discord Developer Portal](https://discord.com/developers/applications) → New Application\r\n2. Navigate to **Bot** → create bot\r\n3. Enable **Message Content Intent** under Privileged Gateway Intents\r\n4. Copy the bot token\r\n5. Invite the bot using OAuth2 URL Generator with `bot` scope and these permissions:\r\n   - Send Messages, Create Public Threads, Send Messages in Threads\r\n   - Read Message History, Manage Threads, View Channels\r\n\r\n#### 2. Configure Your MCP Client\r\n\r\n**Claude Code (CLI):**\r\n\r\n```bash\r\nclaude mcp add halobot \\\r\n  -e DISCORD_BOT_TOKEN=your-token \\\r\n  -e DISCORD_CHANNEL_ID=your-channel-id \\\r\n  -e DISCORD_ALLOWED_USERS=your-user-id \\\r\n  -- halobot\r\n```\r\n\r\n**Claude Desktop (`claude_desktop_config.json`):**\r\n\r\n```json\r\n{\r\n  \"mcpServers\": {\r\n    \"halobot\": {\r\n      \"command\": \"halobot\",\r\n      \"env\": {\r\n        \"DISCORD_BOT_TOKEN\": \"your-token\",\r\n        \"DISCORD_CHANNEL_ID\": \"your-channel-id\",\r\n        \"DISCORD_ALLOWED_USERS\": \"your-user-id\"\r\n      }\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n**Finding IDs:** Enable Developer Mode in Discord settings → right-click channel/user → Copy ID.\r\n\r\n### Diagnostics\r\n\r\n```bash\r\n# Check your setup\r\nhalobot doctor\r\n\r\n# Check setup and send a test message\r\nhalobot doctor --test\r\n```\r\n\r\n## Usage Examples\r\n\r\n**Agent asks a question and waits for your answer:**\r\n```\r\n→ send_and_wait(content=\"I found 3 approaches for the auth refactor. Want me to list them?\")\r\n← { \"status\": \"replied\", \"thread_id\": \"123\", \"reply\": \"Yeah, show me all three\" }\r\n```\r\n\r\n**Agent sends a status update in an ongoing conversation:**\r\n```\r\n→ send_thread_message(content=\"Finished refactoring auth. 47 tests pass.\", thread_id=\"123\")\r\n← { \"status\": \"sent\", \"thread_id\": \"123\" }\r\n```\r\n\r\n**Agent checks conversation history:**\r\n```\r\n→ get_thread_messages(thread_id=\"123\", limit=20)\r\n← { \"messages\": [{ \"author\": \"Agent\", \"content\": \"...\", ... }, ...] }\r\n```\r\n\r\n**Agent monitors a channel for approvals (low-level):**\r\n```\r\n→ send_message(channel_id=\"456\", message=\"Deploy to prod? Reply 'approve' to confirm.\")\r\n← { \"message_id\": \"789\" }\r\n→ wait_for_message(channel_id=\"456\", keyword=\"approve\", after_message_id=\"789\", timeout_seconds=120)\r\n← { \"content\": \"approve\", ... }\r\n```\r\n\r\n## Security\r\n\r\n- **Whitelist enforcement.** Thread-based tools only allow users in `DISCORD_ALLOWED_USERS`.\r\n- **Thread isolation.** Each agent conversation gets its own thread.\r\n- **No inbound commands.** The bot doesn't accept arbitrary commands from Discord.\r\n- **Logs to stderr.** MCP protocol uses stdout; all logging goes to stderr.\r\n- **Low-level tools are unrestricted** — they access any channel the bot can see. Use thread-based tools for controlled human-in-the-loop flows.\r\n\r\n## Architecture\r\n\r\nThe server runs two things concurrently:\r\n\r\n1. **Discord bot** (discord.js) — connects to Discord, manages threads, caches messages\r\n2. **MCP server** (@modelcontextprotocol/sdk) — listens on STDIO for tool calls\r\n\r\nThe Discord client logs in immediately on startup. MCP tools wait for the client to be ready before executing. Messages longer than Discord's 2000-char limit are automatically chunked at newline boundaries.\r\n\r\n## Development\r\n\r\n```bash\r\n# Run tests (no live Discord connection required)\r\nnpm test\r\n\r\n# Dev mode with hot-reload\r\nnpm run dev\r\n\r\n# TypeScript watch\r\nnpx tsc --watch\r\n```\r\n\r\n## Future Ideas\r\n\r\n- [ ] SSE transport for remote/multi-agent access\r\n- [ ] File/image attachment support via threads\r\n- [ ] Reaction-based quick responses (👍 = yes, 👎 = no)\r\n- [ ] Persistent conversation state across server restarts\r\n- [ ] Rate limiting per agent\r\n- [ ] Webhook mode for push-based replies (no polling)\r\n\r\n## License\r\n\r\nISC\r\n","readmeFilename":"README.md"}