# Nexus MCP Bridge MCP server that bridges claude.ai to a homelab Telegram group chat. Logs all messages and files to libsql, exposes three MCP tools over HTTP on the NetBird mesh. ## Architecture ``` claude.ai ──HTTP──► MCP Bridge (mgmt.mg:8321) ──Telegram API──► Group Chat │ │ libsql (local) Mikkel + Homelab Bot + MCP Bot media/ (files) ``` Single Python process running: - **Telegram bot** — polls group chat, logs everything to libsql, sends outbound messages - **FastMCP HTTP server** — exposes `send_message`, `pull_updates`, `queue_status` tools ## Setup Guide ### Step 1: Create a new Telegram bot 1. Open Telegram, message [@BotFather](https://t.me/BotFather) 2. Send `/newbot` 3. Name: `Nexus MCP Bridge` (or whatever you like) 4. Username: `nexus_mcp_bot` (must be unique, pick something available) 5. Copy the **bot token** BotFather gives you ### Step 2: Create the Telegram group 1. In Telegram, create a **new group** 2. Name: `Homelab Bridge` (or your preference) 3. Add members: - Your existing homelab bot (`@georgsen_homelab_bot`) - The new MCP bot (search by the username you chose) 4. **Important:** Make both bots **group admins** so they can read all messages - Tap group name → Edit → Administrators → Add both bots - Bots need at minimum: "Read messages" permission (enabled by default for admins) ### Step 3: Get the group chat ID Option A — Send a message in the group, then check: ```bash curl -s "https://api.telegram.org/bot/getUpdates" | python3 -m json.tool ``` Look for `"chat": {"id": -100XXXXXXXXXX}` — the negative number is the group chat ID. Option B — The bridge logs the chat ID on startup. You can start it once, send a message in the group, and check the logs. ### Step 4: Configure credentials ```bash cd ~/repos/telegram-bot-mcp cp credentials.example credentials ``` Edit `credentials`: ``` MCP_BOT_TOKEN= GROUP_CHAT_ID= HOMELAB_BOT_ID=8521598773 ``` ### Step 5: Install and test ```bash cd ~/repos/telegram-bot-mcp # Create venv (if not already done) python3 -m venv .venv # Install dependencies .venv/bin/pip install -r requirements.txt # Test run (Ctrl+C to stop) .venv/bin/python -m mcp_bridge ``` You should see: ``` Database initialized at /home/mikkel/repos/telegram-bot-mcp/data/bridge.db MCP server starting on 0.0.0.0:8321 Telegram bot polling started MCP Bridge bot started as @nexus_mcp_bot (ID: XXXXXXX) Monitoring group chat: -100XXXXXXXXXX ``` Send a message in the group — you should see it logged. ### Step 6: Install systemd service ```bash cp mcp-bridge.service ~/.config/systemd/user/ systemctl --user daemon-reload systemctl --user enable --now mcp-bridge systemctl --user status mcp-bridge ``` View logs: ```bash journalctl --user -u mcp-bridge -f ``` ### Step 7: Configure claude.ai MCP connection In claude.ai settings, add a new MCP server: - **URL:** `http://mgmt.mg:8321/mcp` - **Transport:** Streamable HTTP This works because mgmt.mg resolves via NetBird mesh — no public exposure needed. ## MCP Tools ### send_message Send a message to the group, attributed as `[claude.ai]`. ```json {"message": "Fix the nexus.mg DNS record to 100.79.65.206"} ``` ### pull_updates Get conversation messages with cursor-based pagination. ```json {"since_id": 0, "limit": 50} ``` Returns messages from all participants with attachment metadata. Use the `cursor` value from the response as `since_id` in the next call. ### queue_status Quick summary: total messages, last activity, pending outbound count. ## File Structure ``` ├── mcp_bridge/ │ ├── __main__.py # Entry point (bot + MCP server) │ ├── config.py # Configuration loader │ ├── db.py # libsql database layer │ ├── telegram_bot.py # Telegram bot (logging + sending) │ ├── mcp_server.py # FastMCP tool definitions │ └── models.py # Data models ├── data/ # libsql database (auto-created) ├── media/ # Downloaded attachments (auto-created) ├── credentials # Bot token + chat ID (not in git) ├── credentials.example # Template ├── requirements.txt └── mcp-bridge.service # systemd unit file ``` ## Troubleshooting **Bot doesn't see group messages:** - Ensure bot is a group admin - Check BotFather: `/mybots` → Bot Settings → Group Privacy → Turn OFF (bots have "privacy mode" ON by default — they only see commands unless it's disabled) **Can't get group chat ID:** - Make sure you sent a message AFTER adding the bot - For supergroups, the ID starts with `-100` **MCP server unreachable from claude.ai:** - Verify NetBird is connected: `netbird status` - Test locally: `curl http://mgmt.mg:8321/mcp` - Check firewall: port 8321 must be open