{
  "markdown": "<div align=\"center\">\n\n# telegram-slack-mcp\n\n**Give Claude your actual chats.**\n\nTwo MCP servers that connect Claude to your *personal* Telegram and Slack accounts —\nyour real DMs, groups, and channels, not a bot inbox.\n\n[![npm](https://img.shields.io/npm/v/telegram-slack-mcp?color=cb3837&logo=npm)](https://www.npmjs.com/package/telegram-slack-mcp)\n[![PyPI](https://img.shields.io/pypi/v/telegram-slack-mcp?color=3775a9&logo=pypi&logoColor=white)](https://pypi.org/project/telegram-slack-mcp/)\n[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)\n\n</div>\n\n```bash\nclaude mcp add telegram -- npx -y telegram-slack-mcp telegram\nclaude mcp add slack    -- npx -y telegram-slack-mcp slack\n```\n\nThen just talk:\n\n> *\"what's unread on telegram from actual people?\"*\n> *\"read my last 30 messages with Priya and draft a reply\"*\n> *\"search all my slack workspaces for the deploy postmortem\"*\n> *\"what's in the screenshot Priya sent me?\"*\n\n---\n\n## Why this exists\n\nMost Telegram integrations use the **Bot API**, which only sees messages sent *to a bot\nyou created*. It cannot read your existing conversations. `telegram-slack-mcp` uses **MTProto**,\nthe same protocol the official app uses, authenticating as you — so Claude sees the\nchats you actually have.\n\nFor Slack, the usual connector is scoped to one workspace. `telegram-slack-mcp` takes one user\ntoken per workspace and treats them as a single surface, so \"search everywhere\" means\neverywhere.\n\n## Install\n\nPick whichever runtime you already have. Both ship the same tools.\n\n### Node\n\n```bash\nclaude mcp add telegram -- npx -y telegram-slack-mcp telegram\nclaude mcp add slack    -- npx -y telegram-slack-mcp slack\n```\n\n### Python\n\n```bash\nclaude mcp add telegram -- uvx telegram-slack-mcp telegram\nclaude mcp add slack    -- uvx telegram-slack-mcp slack\n```\n\n### Claude Code plugin\n\n```\n/plugin marketplace add nileshpatil6/telegram-slack-mcp\n/plugin install telegram@telegram-slack-mcp\n/plugin install slack@telegram-slack-mcp\n```\n\n<details>\n<summary>Other MCP clients (Claude Desktop, Cursor, …)</summary>\n\n```json\n{\n  \"mcpServers\": {\n    \"telegram\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"telegram-slack-mcp\", \"telegram\"],\n      \"env\": { \"TELEGRAM_API_ID\": \"1234567\", \"TELEGRAM_API_HASH\": \"your_hash\" }\n    },\n    \"slack\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"telegram-slack-mcp\", \"slack\"],\n      \"env\": { \"SLACK_USER_TOKENS\": \"xoxp-one,xoxp-two\" }\n    }\n  }\n}\n```\n\n</details>\n\n## Setup\n\n### Telegram — 2 minutes\n\n1. Go to <https://my.telegram.org> → **API development tools** → create an app.\n2. Copy the `api_id` and `api_hash`, and set them:\n\n   ```bash\n   claude mcp add telegram      -e TELEGRAM_API_ID=1234567      -e TELEGRAM_API_HASH=your_hash      -- npx -y telegram-slack-mcp telegram\n   ```\n\n3. Link your account. Either ask Claude — **\"log into telegram\"** — or do it yourself in a\n   terminal, which needs no MCP client at all:\n\n   ```bash\n   TELEGRAM_API_ID=1234567 TELEGRAM_API_HASH=your_hash npx -y telegram-slack-mcp login\n   ```\n\n   ```powershell\n   # PowerShell\n   $env:TELEGRAM_API_ID=\"1234567\"; $env:TELEGRAM_API_HASH=\"your_hash\"\n   npx -y telegram-slack-mcp login\n   ```\n\n   Either way you scan a QR and the session is saved to `~/.chat-mcp`.\n\n   Through Claude:\n\n   It calls `login`, which returns a link to a page showing a QR code (and the code as\n   text, if your client renders it). Scan it from Telegram on your phone — **Settings →\n   Devices → Link Desktop Device** — then it calls `login_status` to confirm. No phone\n   number, no SMS code, no 2FA password typed anywhere. On the same machine you can click\n   \"open in Telegram Desktop\" instead of scanning.\n\n   The session is saved to `~/.chat-mcp` and persists; you do this once.\n\n<details>\n<summary>Can't scan? Use the phone-number flow</summary>\n\n`login_start(phone)` sends you a code, `login_complete(code, password?)` finishes.\nNote that with this path your phone number and login code pass through the conversation\nas tool arguments, so they land in the model's context. The QR flow keeps them out of it.\n\n</details>\n\n### Slack — 5 minutes\n\n1. Go to <https://api.slack.com/apps> → **Create New App** → **From a manifest**.\n2. Paste [`slack-app-manifest.yaml`](slack-app-manifest.yaml) — it prefills every scope.\n3. **Install to Workspace**, then copy the **User OAuth Token** (`xoxp-…`, not `xoxb-`).\n4. Repeat step 3 for each workspace you want. Same app, one token each.\n5. Ask Claude: **\"connect my slack\"** — the `login` tool prompts for the tokens, verifies\n   each one against Slack, and saves them to `~/.chat-mcp`. Nothing to put in your config.\n\n   Prefer environment variables? That still works:\n\n   ```bash\n   claude mcp add slack -e SLACK_USER_TOKENS=xoxp-aaa,xoxp-bbb -- npx -y telegram-slack-mcp slack\n   ```\n\nSlack has no local OAuth flow, which is why you create the app yourself: Slack's OAuth\nrequires a client secret and an HTTPS redirect URL, so a package distributed over npm\ncannot complete it without either shipping a secret publicly or running a callback\nserver. This project has no server, so it asks for the token instead.\n\n## Tools\n\n### Telegram\n\n| tool | what it does |\n|---|---|\n| `login()` | **scan a QR to link your account** — no phone number or code |\n| `login_status()` | check whether the QR has been scanned yet |\n| `login_start(phone)` | fallback: send yourself a login code |\n| `login_complete(code, password?)` | finish login, save the session |\n| `whoami()` | which account is connected |\n| `list_chats(limit, query, unread_only, kind)` | recent chats; `kind` filters to `dm`, `group`, `channel`, `bot`… |\n| `read_chat(chat, limit, before_id)` | messages of one chat — `chat` takes @username, id, or part of a name |\n| `search_messages(query, chat?, limit)` | full-text search, one chat or all |\n| `unread_summary(limit, per_chat, kind)` | catch-up view; `kind: \"dm\"` skips the channel noise |\n| `read_media(chat, message_id, max_kb)` | **view a photo or file** — returns the actual image, not just its type |\n| `send_message(chat, text, reply_to?)` | reply as you — **off unless `TELEGRAM_ALLOW_SEND=1`** |\n\n### Slack\n\n| tool | what it does |\n|---|---|\n| `login()` | prompts for your `xoxp-` tokens, verifies them, saves them |\n| `whoami()` | every connected workspace and who you are in each |\n| `list_channels(limit, query, workspace, types)` | channels across workspaces |\n| `list_dms(limit, workspace)` | 1:1 and group DMs |\n| `read_channel(channel, limit, workspace, before_ts)` | one channel or DM |\n| `read_thread(channel, thread_ts, limit, workspace)` | replies inside a thread |\n| `search_messages(query, limit, workspace)` | supports `in:#chan`, `from:@user` |\n| `unread_summary(limit, per_chat, workspace)` | what's unread everywhere |\n| `read_file(file_id, workspace, max_kb)` | **view a file shared in Slack** — returns the actual image |\n| `send_message(channel, text, workspace, thread_ts?)` | post as you — **off unless `SLACK_ALLOW_SEND=1`** |\n\nEvery Slack tool takes an optional **`workspace`** (any substring of the name). Leave it\nblank to act across all of them; it's only required when a channel name exists in more\nthan one, and the error tells you which.\n\n## Configuration\n\n| variable | default | meaning |\n|---|---|---|\n| `TELEGRAM_API_ID` | — | from my.telegram.org |\n| `TELEGRAM_API_HASH` | — | from my.telegram.org |\n| `TELEGRAM_ALLOW_SEND` | `0` | `1` lets Claude send Telegram messages as you |\n| `SLACK_USER_TOKENS` | — | one `xoxp-` token per workspace, comma separated |\n| `SLACK_ALLOW_SEND` | `0` | `1` lets Claude post to Slack as you |\n| `CHAT_MCP_DATA_DIR` | `~/.chat-mcp` | where the Telegram session is stored |\n\nSending is **off by default** in both servers. Reading is the safe default; you opt into\nwriting deliberately.\n\n## Privacy\n\n**Nothing is sent to any server belonging to this project. There is no such server.**\n\n`telegram-slack-mcp` runs entirely on your machine. The only network traffic it makes is directly\nto Telegram's and Slack's own APIs, using your own credentials. There is no telemetry,\nno analytics, no crash reporting, no license check, no \"phone home\" — grep the source,\nthere is no endpoint to find.\n\nThe data path is exactly this:\n\n```\nyour machine  <-->  Telegram / Slack APIs      (your credentials, your account)\nyour machine  <-->  Claude                     (only what you ask Claude to read)\n```\n\nYour credentials never reach Claude. Your session file and `xoxp-` tokens stay in\n`~/.chat-mcp` and in your environment; the servers use them locally to make API calls\nand pass back only the messages themselves.\n\nWhat *does* reach Claude is the chat content you ask about — because that is the point\nof the tool. If you ask Claude to read a conversation, that conversation goes into your\nClaude conversation and is handled under Anthropic's privacy policy, exactly like text\nyou paste in yourself. Nothing else is read, and nothing is read in the background: the\nservers only act when Claude calls a tool.\n\nThe author of this project cannot see any of it.\n\n## Security\n\nRead this part.\n\n- **These act as you, not as a bot.** Anything sent shows as sent by your account, and\n  people in those chats cannot tell the difference.\n- **The stored session is a full credential.** `~/.chat-mcp/telegram.session` and your\n  `xoxp-` tokens are equivalent to being logged in as you. Anyone who copies them has\n  your account. They never leave your machine, and nothing here phones home.\n- **Everything Claude reads enters the model's context.** Don't point this at accounts\n  holding data you would not send to a model.\n- **Telegram calls this a userbot.** Automating a personal account is restricted by\n  Telegram's ToS. Light personal read-and-reply use is common and low risk; bulk\n  automation gets accounts banned. Your call, your account.\n- Revoke any time: Telegram → Settings → Devices, or delete the token in Slack's app\n  settings. Deleting `~/.chat-mcp` drops the local session.\n\n## Troubleshooting\n\n**\"Telegram not logged in yet\"** — run the login flow: ask Claude to log in with your\nphone number. It persists after that; if it keeps reappearing, check that\n`CHAT_MCP_DATA_DIR` is writable.\n\n**\"Missing Telegram credentials\"** — `TELEGRAM_API_ID` / `TELEGRAM_API_HASH` aren't\nreaching the server. With `claude mcp add`, pass them with `-e`.\n\n**Slack returns nothing at all** — you're almost certainly authorized against an empty\nor wrong workspace. Run `whoami` to see which workspaces are actually connected.\n\n**`\"#general\" exists in several workspaces`** — pass `workspace` to disambiguate; the\nerror lists your options.\n\n**Slack search returns `not_allowed_token_type`** — the token is a bot token (`xoxb-`).\nYou need the **User** OAuth token (`xoxp-`).\n\n## Development\n\n```bash\ngit clone https://github.com/nileshpatil6/telegram-slack-mcp\ncd telegram-slack-mcp\nnpm install && npm run build\nnode dist/cli.js telegram        # run the server on stdio\n\ncd python && python -m build     # build the Python distribution\n```\n\n## License\n\nMIT\n",
  "bytes": 11030,
  "sha": "9c0d61b6d9a9cb00e78e5f5fd596902d859ab00be59c2aa7244f49cdbeef04e8",
  "repo_slug": "nileshpatil6/telegram-slack-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_nileshpatil6_telegram_slack_mc_e85a8a01/readme"
}