# Telegram Mcp Tdlib

> TDLib-powered Telegram MCP server for JVM/Kotlin. Full client access for AI agents.

- **Type:** MCP server
- **Install:** `agentstack add mcp-tolboy-telegram-mcp-tdlib`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [tolboy](https://agentstack.voostack.com/s/tolboy)
- **Installs:** 0
- **Category:** [Communication](https://agentstack.voostack.com/c/communication)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [tolboy](https://github.com/tolboy)
- **Source:** https://github.com/tolboy/telegram-mcp-tdlib

## Install

```sh
agentstack add mcp-tolboy-telegram-mcp-tdlib
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Telegram MCP Server

[](LICENSE)
[](https://github.com/tolboy/telegram-mcp-tdlib/actions/workflows/ci.yml)
[](https://github.com/tolboy/telegram-mcp-tdlib/actions/workflows/security.yml)
[](https://github.com/tolboy/telegram-mcp-tdlib/releases/latest)

**Telegram MCP for real accounts — safe by default, TDLib-powered, production-ready.**

A local-first [Model Context Protocol](https://modelcontextprotocol.io/) server that gives
an AI agent real Telegram-account access without handing it the keys to your account. It
starts read-only, hides write tools until you opt in, and runs over **STDIO** for desktop
clients or **Streamable HTTP** at `/mcp` for managed deployments.

### Why this one?

- **Safe by default** — boots in read-only mode with a small `inbox`/`reader` profile;
  write and quota-consuming tools are *hidden from the model*, not merely blocked, until you
  turn them on.
- **Real user accounts, not just bots** — built on **TDLib** (via tdlight-java), so an agent
  can read and act on your actual account, not only a Bot API subset.
- **Isolated multi-account** — each account gets its own session, mandatory selection, and
  scoped API keys; reads never fan out across accounts.
- **Two transports** — STDIO for Claude Desktop / Cursor / VS Code / Codex, Streamable HTTP
  for a managed service.
- **No JDK to install** — runtime-inclusive release bundles for Windows, Linux x64/ARM64, and
  Apple-silicon macOS, with checksums, an SBOM, and signed container digests.

> The image is an illustrative mockup; a real screencast is on the way.

## Safe first run

Runtime-inclusive releases need no JDK, Gradle, Git, Python, or Node.js. Use a test account
for your first run if you can.

**1. Install** (macOS Apple silicon / Linux with Homebrew):

```bash
brew install --formula https://github.com/tolboy/telegram-mcp-tdlib/releases/latest/download/telegram-mcp.rb
```

Windows with Scoop:

```powershell
scoop install https://github.com/tolboy/telegram-mcp-tdlib/releases/latest/download/telegram-mcp.json
```

**2. Log in** with a QR scan — the one-time code never touches your shell history:

```bash
telegram-mcp auth --method qr
```

**3. Serve a small, read-only surface** over STDIO:

```bash
MCP_TOOL_PROFILE=inbox MCP_READ_ONLY=true telegram-mcp serve --transport stdio
```

Now point an AI client at it (below) and try a first prompt that cannot change anything:

> “Summarize my last 20 conversations. Do not send or modify anything.”

In this mode write and quota-consuming tools are absent from the tool list entirely, so the
model has nothing destructive to call. Switch to `MCP_READ_ONLY=false` only after you have
reviewed the surface; destructive actions still require confirmation by default.

## Connect your client

STDIO is the low-friction path for desktop clients. Minimal entry:

```json
{
  "mcpServers": {
    "telegram": {
      "command": "telegram-mcp",
      "args": ["serve", "--transport", "stdio"],
      "env": {
        "TDLIB_API_ID": "123456",
        "TDLIB_API_HASH_FILE": "/absolute/path/to/telegram-api-hash",
        "MCP_TOOL_PROFILE": "inbox",
        "MCP_READ_ONLY": "true"
      }
    }
  }
}
```

- **Claude Desktop** — add the block above to `claude_desktop_config.json`
  (Settings → Developer → Edit Config), then restart the app.
- **Cursor** — add it to `~/.cursor/mcp.json` (or Settings → MCP → Add).
- **VS Code** — use `.vscode/mcp.json`; VS Code names the top-level key `servers` instead of
  `mcpServers`, otherwise the entry is identical.

For a managed HTTP deployment instead of STDIO:

```bash
docker run --rm -p 127.0.0.1:8080:8080 \
  -e TDLIB_API_ID -e TDLIB_API_HASH -e MCP_API_KEY \
  ghcr.io/tolboy/telegram-mcp-tdlib:latest
```

See [CLI and STDIO](docs/CLI_AND_STDIO.md), [interactive authentication](docs/INTERACTIVE_AUTH.md), and [client compatibility](docs/MCP_CLIENT_COMPATIBILITY.md) for exact platform/client variants.

## Recipes

Copy-paste configurations and prompts for real tasks, each with the smallest
tool surface that can do the job:
[summarize your inbox](docs/recipes/summarize-inbox.md),
[find a lost message](docs/recipes/find-lost-message.md),
[research public groups](docs/recipes/research-public-groups.md),
[read-only community health check](docs/recipes/community-review-readonly.md),
and [draft replies without sending](docs/recipes/safe-draft-reply.md) —
index in [docs/recipes](docs/recipes/README.md).

## How it compares

Most Telegram MCP servers wrap the Bot API or a Telethon user session and expose every
capability to the model at once. This project optimizes for connecting an agent to a **real
account you care about**, safely:

| Dimension | This server | Typical Telethon / Bot-API MCP servers |
|---|---|---|
| Account access | Real user account via TDLib (tdlight-java) | Often bot-only, or a single Telethon user session |
| Default posture | Read-only; write/quota tools **hidden** until enabled | Usually all tools exposed from the start |
| Multi-account | Isolated sessions, mandatory selection, scoped keys, **no cross-account read fan-out** | Single account, or implicit fan-out |
| Transports | STDIO **and** Streamable HTTP `/mcp` | Usually STDIO only |
| Guardrails | Confirmation gating, audit log, anti-spam limits, chat allow-list, untrusted-content marking | Minimal |
| Distribution | Signed runtime bundles (no JDK), SBOM + provenance, GHCR image | Source install via pip/npx |

A fuller architectural comparison (TDLib vs Telethon vs Bot API, and why "hidden,
not blocked" matters) is in [docs/COMPARISON.md](docs/COMPARISON.md). The detailed,
dated benchmark against the leading public servers — including features
deliberately declined (raw MTProto escape hatch, ownership transfer, bulk contact export) —
is in [PUBLIC_BENCHMARK_AND_ROADMAP.md](docs/PUBLIC_BENCHMARK_AND_ROADMAP.md).

## Tool profiles

You don't expose 110 tools on day one. `MCP_TOOL_PROFILE` narrows the advertised surface
*before a client ever sees it*, without weakening account scoping, read-only mode,
confirmation, audit, or anti-spam:

| Profile | Surface |
|---|---|
| `reader` | Always non-mutating — safe for a first look |
| `inbox` | Personal messages, drafts, media, contacts, privacy |
| `community-admin` | Moderation, group/channel, permissions, bot commands |
| `research` | Bounded account/public discovery and reading |
| `all` | The full inventory (opt in deliberately) |

See [TOOL_PROFILES.md](docs/TOOL_PROFILES.md) for the exact intent of each surface.

## Features

- **110 MCP tools** — messages, polls, read receipts, scheduled sends, chats, folders,
  invite-link administration, contacts, media, drafts, privacy, bot commands, detailed group
  permissions, profile, search, and account routing.
- **TDLib via tdlight-java** — real user accounts, not just the Bot API.
- **Isolated multi-account mode** — independent sessions, mandatory account selection, and
  optional per-key account scopes with no cross-account read fan-out.
- **Safe by default** — read-only tool surface, confirmation mode for destructive actions,
  and task-focused profiles (`reader`/`inbox`/`community-admin`/`research`/`all`).
- **Two transports** — STDIO for desktop clients and Streamable HTTP `/mcp`
  (Spring AI 2.0 / MCP SDK 2.0), with API-key auth.
- **Guardrails** — audit logging, anti-spam via Resilience4j rate limiter (30 req/s) and
  circuit breaker, chat allow-list, prompt-injection patterns, and untrusted-content marking.
- **Observability** — Micrometer metrics, Prometheus endpoint, and structured JSON logging
  with MDC (`traceId`, `sessionId`, `toolName`).
- **Verified, runtime-inclusive releases** — Windows x64, Linux x64/ARM64, and Apple-silicon
  macOS bundles with checksums, an SBOM, and signed container digests — no JDK required.

More capabilities

- **Entity resolution** — resolve `@username`, `+phone`, or numeric IDs transparently.
- **MCP behavior annotations** — every advertised tool declares read-only, destructive,
  retry, and open-world hints for safer client UX.
- **Structured, marked output** — backward-compatible JSON text plus `structuredContent`;
  Telegram-controlled fields are explicitly untrusted and presentation-control Unicode is
  escaped.
- **Host-friendly discovery** via `/.well-known/mcp-server.json` for installers, desktop
  hosts, and service managers.
- **File security service** for safe media uploads; **Actuator** health/info/metrics;
  **graceful shutdown** with configurable timeout.
- **Multi-stage Docker** build + docker-compose with dev hot-reload.
- **Runtime-inclusive app images** — the supported release archives include their own Java
  runtime and pass an actual STDIO handshake before publication.
- **Offline session doctor** — inspect configured TDLib state paths and lock availability
  without starting TDLib or printing secrets.
- **Clean Architecture** — config / model / client / service / tool / security / util /
  exception.
- **Language-neutral public search** — callers pass synonyms, translations, and spelling
  variants in any language; product-specific policy interpretation stays in the MCP host.

## Tech Stack

| Component        | Version          |
|------------------|------------------|
| Java             | 25               |
| Kotlin           | 2.4.0            |
| Spring Boot      | 4.1.0            |
| Spring AI MCP    | 2.0.0            |
| MCP Java SDK     | 2.0.0            |
| TDLib (tdlight)  | 3.5.3+td.1.8.65  |
| Gradle           | 9.6.1            |
| Resilience4j     | 2.4.0            |

## Quick Start

### Prerequisites

- Java 25+ (or use Docker)
- Telegram API credentials from https://my.telegram.org (`TDLIB_API_ID`, `TDLIB_API_HASH`)
- Exactly one authentication mode: `TDLIB_PHONE_NUMBER` for user-account mode or `TDLIB_BOT_TOKEN` for bot mode

### 1. Clone and configure

```bash
git clone https://github.com/tolboy/telegram-mcp-tdlib.git
cd telegram-mcp-tdlib
cp .env.example .env
# Edit .env — set TDLIB_API_ID, TDLIB_API_HASH, one of TDLIB_PHONE_NUMBER/TDLIB_BOT_TOKEN, and MCP_API_KEY
```

On Windows PowerShell, use `Copy-Item .env.example .env` instead of `cp`.

### 2. Run locally

```bash
./gradlew bootRun
```

The server starts on `http://localhost:8080`. Its MCP Streamable HTTP endpoint is `http://localhost:8080/mcp`.

### Your first 60 seconds

1. Add a remote **Streamable HTTP** MCP server in your client with URL
   `http://127.0.0.1:8080/mcp` and `Authorization: Bearer `.
   The stable connection data for Claude Desktop, Cursor, VS Code, and
   Inspector is kept in [MCP_CLIENT_COMPATIBILITY.md](docs/MCP_CLIENT_COMPATIBILITY.md).
2. Start safely with `MCP_READ_ONLY=true` and one focused surface, for example
   `MCP_TOOL_PROFILE=inbox` or `MCP_TOOL_PROFILE=research`.
3. Ask the client one of these concrete first questions:

   - **Inbox:** “Summarize my last 20 relevant conversations. Do not send or modify anything.”
   - **Community:** “Show recent admin actions and default permissions in this group; propose changes, but do not apply them.”
   - **Research:** “Find public chats matching these English and Russian query variants, and report evidence from descriptions and recent messages.”

Switch to `MCP_READ_ONLY=false` only after reviewing the discovered surface;
confirmation remains enabled by default for destructive actions.

On Windows, Gradle outputs default to the system temp directory to avoid file-lock issues in synchronized folders. Set `KTM_BUILD_DIR` or pass `-Pktm.buildDir=...` to override.

### 3. Run with Docker

```bash
docker compose up --build
```

The compose stack persists TDLib session data in the `tdlib-data` volume, downloads in `telegram-downloads`, and mounts `${MCP_UPLOADS_DIR:-./docker-data/uploads}` into the container as `/data/uploads` for upload/download tools.

By default, compose binds the service to `127.0.0.1` via `MCP_BIND_HOST` so the local boxed/developer scenario is not exposed on the LAN by accident.

Dev mode with hot-reload:

```bash
docker compose --profile dev up telegram-mcp-dev
```

With Prometheus monitoring:

```bash
docker compose --profile monitoring up
```

Production note: terminate TLS in front of the container (reverse proxy, ingress, or load balancer). API keys should not traverse plaintext HTTP outside trusted local development networks.

Deployment guidance for local boxed installs vs remote/VPS exposure is documented in `docs/DEPLOYMENT_MODES.md`.

Connector discovery for a multi-server MCP host or installer is documented in `docs/CONNECTOR_DISCOVERY.md`.

Client compatibility, a portable JSON-Schema profile, and a Streamable HTTP smoke test are documented in [MCP_CLIENT_COMPATIBILITY.md](docs/MCP_CLIENT_COMPATIBILITY.md).

Offline-safe TDLib session inspection and clearing are documented in [SESSION_MAINTENANCE.md](docs/SESSION_MAINTENANCE.md).

The comparison with the leading public Telegram MCP servers and the prioritized follow-up work are documented in [PUBLIC_BENCHMARK_AND_ROADMAP.md](docs/PUBLIC_BENCHMARK_AND_ROADMAP.md).

## Releases

CI runs on every pull request and push to `master`. A signed-off release is a Git tag in the `vX.Y.Z` form; the release workflow builds and publishes the corresponding GHCR image tags (`latest`, `X.Y.Z`, `X.Y`, and immutable `sha-`), plus checked release bundles for Windows x64, Linux x64/ARM64, and macOS ARM64. Public releases include an SPDX SBOM for the runnable JAR, GitHub provenance attestations for release assets, and a keyless Sigstore signature plus provenance for the container digest. See [release-bundle verification](docs/RELEASE_BUNDLES.md#supply-chain-verification).

Use a concrete semver tag for reproducible deployments. `v1.0.0` is the first Streamable HTTP / MCP SDK 2.0 public baseline; `v1.1.0` adds account isolation, scoped keys, and cross-platform native packaging; `v1.2.0` adds premium voice-note transcription and the neutral package namespace; `v1.3.0` adds privacy, bot-command, detailed group-permission controls, and verified release bundles; `v1.4.0` adds focused MCP tool profiles; `v1.7.x` adds the STDIO transport, CLI with an interactive auth wizard, structured tool output, optional OAuth resource-server mode, and runtime-inclusive release images. The complete history is in [CHANGELOG.md](CHANGELOG.md).

> The current TDLight native release publishes an Apple-silicon macOS binary but not an Intel macOS classifier. The server supports Intel macOS at the JVM/path level, but TDLib-backed Telegram access on that platform requires an upstream native package before it can run.

To create the runtime-inclusive app image for the current matching platform:

```powershell
./scripts/package-app-image.ps1 -Version  -Target windows-x64 -OutputDirectory release-assets
```

The build verifies the actual `BOOT-INF/lib` contents, launcher-reported version,
and a live STDIO handshake. See [RELEASE_BUNDLES.md](docs/RELEASE_BUNDLES.md)
for the target matrix.

```bash
git checkout master
git pull --rebase origin master
git tag -a vX.Y.Z -m "Telegram MCP Server vX.Y.Z"
git push origin master vX.Y.Z
```

## Environment Variables

### TDLib (primary Telegram client)

| Variable                | Required    | Default         | Description |
|-------------------------|-------------|-----------------|-------------|
| `TDLIB_API_ID`          | Yes*        | —               | API ID from https://my.telegram.org |
| `TDLIB_API_HASH`        | Yes*        | —               | API hash from https://my.telegram.org |
| `TDLIB_API_HASH_FILE`   | No          | —               | Secret-file alternative to `TDLIB_API_HASH` |
| `TDLIB_PHONE_NUMBER`    | No†         | —               | Phone for user-account mode (full API access) |
| `TDLIB_BOT_TOKEN`       | No†         | —               | Bot token for bot mode |
| `TDLIB_BOT_TOKEN_FILE`  | No          | —               | Secret-file alternative to bot token |
| `TDLIB_2FA_PASSWORD`    | No          | —               | 2FA password (supply for headless startup) |
| `TDLIB_2FA_PASSWORD

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [tolboy](https://github.com/tolboy)
- **Source:** [tolboy/telegram-mcp-tdlib](https://github.com/tolboy/telegram-mcp-tdlib)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-tolboy-telegram-mcp-tdlib
- Seller: https://agentstack.voostack.com/s/tolboy
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
