Content
<!-- Generated by https://github.com/flowgent-labs/mcpfather -->
# telegram-mcp
[](https://go.dev/)
[](https://modelcontextprotocol.io/)
[](https://prometheus.io/)
[](https://opentelemetry.io/)
[](https://openid.net/connect/)
[](https://ldap.com/)
[](https://helm.sh/)
> An Enterprise-grade MCP server, specifically designed for AI to call Telegram MTProto API APIs, generated from MCPFather — exposes **395 native tools**. Each API operation becomes an AI-callable tool with typed schemas and customized aggregate virtual tools, auth forwarding, and observability built-in, and even use as regular CLI.
## Quick Start
```sh
make
# Or with OpenTelemetry distributed tracing (gRPC or HTTP)
make build-with-otel-grpc # OTLP gRPC exporter
make build-with-otel-http # OTLP HTTP/protobuf exporter
```
### Start in `HTTP` mode (example)
```sh
# Configure your upstream API
export MCP__UPSTREAM__ENDPOINT=https://api.example.com
export MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN=your-token
./bin/telegram-mcp --transport http --port 8080 &
```
- Inspection MCP frontend Authentication (OAuth2.1).
```bash
export MCP__AUTH__FRONTEND__OIDC__ENABLED=true
export MCP__AUTH__FRONTEND__OIDC__ISSUER="https://keycloak.example.com/realms/master"
export MCP__AUTH__FRONTEND__OIDC__AUDIENCE="telegram-mcp"
./bin/telegram-mcp -v 10 --transport http --port 8080
# Obtain the OAuth2.1 metadata.
curl -s https://iam.example.com/realms/master/.well-known/openid-configuration
curl -s localhost:8080/.well-known/oauth-protected-resource
#{"resource":"telegram-mcp","authorization_servers":["https://keycloak.example.com/realms/master"],"bearer_methods_supported":["header"]}
```
### Run in `CLI` mode (example)
```sh
./bin/telegram-mcp -v 1 -t cli list
./bin/telegram-mcp -v 1 -t cli <tool-name> [OPTIONS]
```
## Options
| Flag | Default | Description |
|------|---------|-------------|
| `-t, --transport` | `stdio` | `stdio` / `http` / `cli` |
| `-p, --port` | `8080` | HTTP server port |
| `--metrics-port` | `0` | Override mgmt port (0 = use config) |
| `-v, --verbose` | `0` | Log verbosity (0–10) |
| `--print-default-config` | — | Print default config.yaml to stdout |
## Authentication
Auth is split into two independent layers — neither shares credentials with the other:
| Layer | Config YAML path | Env var prefix | Role |
|---|---|---|---|
| **Frontend** | `auth.frontend.oidc` | `MCP__AUTH__FRONTEND__OIDC__*` | Validates AI agent bearer tokens (inbound) |
| **Backend OIDC** | `auth.backend.oidc` | `MCP__AUTH__BACKEND__OIDC__*` | Server's own OIDC client_credentials for upstream APIs |
| **Backend LDAP** | `auth.backend.ldap` | `MCP__AUTH__BACKEND__LDAP__*` | Server's own LDAP service-account bind for upstream APIs |
| **Backend Static** | `auth.backend.static` | `MCP__AUTH__BACKEND__STATIC__*` | Server's own static token/cookie for upstream APIs |
**Frontend (inbound)** — validates bearer tokens presented by AI agents (MCP clients).
Only applies to `--transport http`; stdio has no network boundary. Standard OIDC JWT
bearer validation per RFC 9728 / MCP Authorization spec.
**Backend (outbound)** — credentials the MCP server uses to call upstream APIs.
Token priority (first available wins):
1. **OIDC** client_credentials grant (`auth.backend.oidc.*`)
2. **LDAP** service account bind (`auth.backend.ldap.*`)
3. **Static** bearer token (`auth.backend.static.bearer_token`)
The AI agent's inbound token is **never** forwarded upstream (MCP spec: Token Passthrough Prohibition).
Cookie-based auth is also available via `auth.backend.static.cookie_token`.
## Configuration
Create `~/.telegram-mcp/config.yaml` (run `--print-default-config` for a full template):
```yaml
upstream:
endpoint: "" # upstream API base URL (e.g. https://api.example.com)
# When true, the MCP session ID is forwarded as X-MCP-Session-ID header.
enable_mcp_session_forward: true
runtime:
download_dir: ""
log_authorization: false
# ---- Authentication ----
# frontend = inbound: validates bearer tokens presented by MCP clients (AI agents).
# backend = outbound: credentials the server uses to call upstream APIs.
# The two are independent — the inbound token is never reused outbound
# (see MCP Authorization spec: Token Passthrough Prohibition).
auth:
frontend:
# Standard OAuth 2.1 / OIDC JWT bearer validation (Resource Server role, RFC 9728).
# Only enforced on the http transport; stdio has no network boundary.
oidc:
enabled: false
issuer: "" # e.g. https://idp.example.com/realms/myrealm
jwks_uri: "" # optional override (auto-discovered from issuer if empty)
audience: "" # expected JWT "aud" claim; also published as the RFC 9728 protected-resource identifier
# When true, validated frontend JWT claims (sub, email) are forwarded upstream
# as X-MCP-Client-Token-Sub and X-MCP-Client-Token-Email headers.
enable_client_token_claim_forward: true
# Additional JWT claims to forward as X-MCP-Client-Token-<Header-Name> headers.
# e.g. ["given_name", "family_name", "preferred_username"]
# additional_client_token_claim_forward: []
# Outbound: credentials the server uses to call upstream APIs.
backend:
oidc:
enabled: true
issuer: https://idp.example.com/realms/myrealm
client_id: my-client
client_secret: "${MCP__AUTH__BACKEND__OIDC__CLIENT_SECRET}"
scopes: openid
# token_url: "" # auto-discovered from issuer /.well-known
ldap:
enabled: false
url: ldaps://ldap.example.com
base_dn: dc=example,dc=com
bind_dn: cn=svc,dc=example,dc=com
bind_password: "${MCP__AUTH__BACKEND__LDAP__BIND_PASSWORD}"
static:
bearer_token: "${MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN}" # or set cookie_token
nativeTools:
expose:
register_all_tools_by_default: true # expose all native tools
# includes: [Tool1, Tool2] # or whitelist specific tools
# excludes: [Tool3] # hide noisy tools
```
All values can be set via `MCP__`-prefixed environment variables (e.g. `MCP__AUTH__BACKEND__OIDC__CLIENT_ID`).
## Management — Metrics, Tracing, Pprof
```yaml
mgmt:
enabled: true
host: 0.0.0.0
port: 9991
otel:
enabled: false
endpoint: localhost:4317
protocol: grpc
sample_rate: 1.0
metrics:
enabled: true
prometheus: true
export_interval: 30s
pprof:
enabled: false
server_bind: 0.0.0.0:6669
```
```sh
./bin/telegram-mcp --transport http --port 8080
curl http://localhost:9991/metrics # Prometheus endpoint
curl http://localhost:9991/health # health check
```
Trace spans are named `mcp.tool.<name>`. W3C `traceparent` is propagated to upstream calls.
## Available Tools (395)
| Tool | Description |
|------|-------------|
| `AccountAcceptauthorization` | Invoke account.acceptAuthorization - MTProto RPC method: account.acceptAuthorization Returns: Bool |
| `AccountCancelpasswordemail` | Invoke account.cancelPasswordEmail - MTProto RPC method: account.cancelPasswordEmail Returns: Bool |
| `AccountChangephone` | Invoke account.changePhone - MTProto RPC method: account.changePhone Returns: User |
| `AccountCheckusername` | Invoke account.checkUsername - MTProto RPC method: account.checkUsername Returns: Bool |
| `AccountConfirmpasswordemail` | Invoke account.confirmPasswordEmail - MTProto RPC method: account.confirmPasswordEmail Returns: Bool |
| `AccountConfirmphone` | Invoke account.confirmPhone - MTProto RPC method: account.confirmPhone Returns: Bool |
| `AccountCreatetheme` | Invoke account.createTheme - MTProto RPC method: account.createTheme Returns: Theme |
| `AccountDeclinepasswordreset` | Invoke account.declinePasswordReset - MTProto RPC method: account.declinePasswordReset Returns: Bool |
| `AccountDeleteaccount` | Invoke account.deleteAccount - MTProto RPC method: account.deleteAccount Returns: Bool |
| `AccountDeletesecurevalue` | Invoke account.deleteSecureValue - MTProto RPC method: account.deleteSecureValue Returns: Bool |
| `AccountFinishtakeoutsession` | Invoke account.finishTakeoutSession - MTProto RPC method: account.finishTakeoutSession Returns: Bool |
| `AccountGetaccountttl` | Invoke account.getAccountTTL - MTProto RPC method: account.getAccountTTL Returns: AccountDaysTTL |
| `AccountGetallsecurevalues` | Invoke account.getAllSecureValues - MTProto RPC method: account.getAllSecureValues Returns: Vector<SecureValue> |
| `AccountGetauthorizationform` | Invoke account.getAuthorizationForm - MTProto RPC method: account.getAuthorizationForm Returns: account.AuthorizationForm |
| `AccountGetauthorizations` | Invoke account.getAuthorizations - MTProto RPC method: account.getAuthorizations Returns: account.Authorizations |
| … | *380 more tools not shown* |
## Virtual Tools
Compose native tools via a declarative pipeline DSL:
```yaml
virtualTools:
- name: MyVirtualTool
description: Chain multiple native tools together
inputSchema:
type: object
properties:
appId: { type: string }
required: [appId]
pipeline:
- id: getApp
kind: call
spec: { tool: GetApplication, args: { applicationId: "$input.appId" } }
- id: appName
kind: jq
spec: { from: "$getApp", expr: .name }
- id: done
kind: return
spec: { from: "$appName" }
```
Pipeline kinds: `call`, `jq`, `foreach`, `emit`, `return`.
## Agent Integration
### OpenCode
- `~/.config/opencode/opencode.json`:
```json
{
"mcp": {
"telegram-mcp": {
"type": "local",
"command": ["bash", "-c", "/path/to/telegram-mcp"],
"args": ["--transport", "stdio"],
"env": {
"MCP__UPSTREAM__ENDPOINT": "https://api.example.com",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN": "your-token",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN_FILE": "/path/to/fallback/.credentials"
},
"enabled": true
}
}
}
```
### Claude Code
- `~/.claude.json`:
```json
{
"mcpServers": {
"telegram-mcp": {
"command": "/path/to/telegram-mcp",
"args": ["--transport", "stdio"],
"env": {
"MCP__UPSTREAM__ENDPOINT": "https://api.example.com",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN": "your-token",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN_FILE": "/path/to/fallback/.credentials"
}
}
}
}
```
### Codex CLI
- `~/.codex/config.toml`:
```toml
[mcp_servers.telegram-mcp]
url = "http://localhost:8080/mcp"
bearer_token_env_var = "MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN"
```
### Cursor
- `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"telegram-mcp": {
"command": "/path/to/telegram-mcp",
"args": ["--transport", "stdio"],
"env": {
"MCP__UPSTREAM__ENDPOINT": "https://api.example.com",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN": "your-token",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN_FILE": "/path/to/fallback/.credentials"
}
}
}
}
```
### OpenCode (Remote)
- `~/.config/opencode/opencode.json`:
```json
{
"mcp": {
"telegram-mcp": {
"type": "remote",
"url": "http://localhost:8080/mcp",
"env": {
"MCP__UPSTREAM__ENDPOINT": "https://api.example.com",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN": "your-token",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN_FILE": "/path/to/fallback/.credentials"
}
}
}
}
```
### Claude Code (Remote)
- `~/.claude.json` (User MCPs):
```json
{
"mcpServers": {
"telegram-mcp": {
"url": "http://localhost:8080/mcp",
"env": {
"MCP__UPSTREAM__ENDPOINT": "https://api.example.com",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN": "your-token",
"MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN_FILE": "/path/to/fallback/.credentials"
}
}
}
}
```
### Codex CLI (Remote)
- `~/.codex/config.toml`:
```toml
[mcp_servers.telegram-mcp]
url = "http://localhost:8080/mcp"
bearer_token_env_var = "MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN"
```
### Cursor (Remote)
- `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"telegram-mcp": {
"url": "http://localhost:8080/mcp"
}
}
}
```
## Deployment — Docker
### Build
```sh
make build-image
```
Or manually:
```sh
docker build -t ghcr.io/<YOUR_ORG>/telegram-mcp:latest -f deploy/docker/Dockerfile .
docker push ghcr.io/<YOUR_ORG>/telegram-mcp:latest
```
### Run
Pull the pre-built image from GitHub Container Registry:
```sh
docker pull ghcr.io/<YOUR_ORG>/telegram-mcp:latest
```
First generate a default config, then mount it when running:
```sh
docker run --rm ghcr.io/<YOUR_ORG>/telegram-mcp:latest --print-default-config > ~/.telegram-mcp/config.yaml
```
- **Static bearer token**
```sh
docker run -d --name telegram-mcp \
-p 8080:8080 -p 9991:9991 \
-e MCP__UPSTREAM__ENDPOINT="https://api.example.com" \
-e MCP__AUTH__BACKEND__STATIC__BEARER_TOKEN="YOUR_BEARER_TOKEN" \
-v ~/.telegram-mcp:/home/mcp/.telegram-mcp \
ghcr.io/<YOUR_ORG>/telegram-mcp:latest \
--transport http --port 8080
```
- **OIDC backend auth**
```sh
docker run -d --name telegram-mcp \
-p 8080:8080 -p 9991:9991 \
-e MCP__UPSTREAM__ENDPOINT="https://api.example.com" \
-e MCP__AUTH__BACKEND__OIDC__ENABLED=true \
-e MCP__AUTH__BACKEND__OIDC__ISSUER="https://idp.example.com/realms/myrealm" \
-e MCP__AUTH__BACKEND__OIDC__CLIENT_ID="my-client" \
-e MCP__AUTH__BACKEND__OIDC__CLIENT_SECRET="YOUR_CLIENT_SECRET" \
-v ~/.telegram-mcp:/home/mcp/.telegram-mcp \
ghcr.io/<YOUR_ORG>/telegram-mcp:latest \
--transport http --port 8080
```
- **LDAP backend auth**
```sh
docker run -d --name telegram-mcp \
-p 8080:8080 -p 9991:9991 \
-e MCP__UPSTREAM__ENDPOINT="https://api.example.com" \
-e MCP__AUTH__BACKEND__LDAP__ENABLED=true \
-e MCP__AUTH__BACKEND__LDAP__URL="ldaps://ldap.example.com" \
-e MCP__AUTH__BACKEND__LDAP__BASE_DN="dc=example,dc=com" \
-e MCP__AUTH__BACKEND__LDAP__BIND_DN="cn=svc,dc=example,dc=com" \
-e MCP__AUTH__BACKEND__LDAP__BIND_PASSWORD="YOUR_BIND_PASSWORD" \
-v ~/.telegram-mcp:/home/mcp/.telegram-mcp \
ghcr.io/<YOUR_ORG>/telegram-mcp:latest \
--transport http --port 8080
```
### Test with mcpclient.sh
After the container starts, use the bundled `mcpclient.sh` to verify.
> **Note:** `mcpclient.sh` only supports **backend static** token auth. If the server requires
> **frontend OIDC/LDAP** authentication, use a real AI-agent MCP client instead.
```sh
# Point to the mapped host port (include /mcp path)
export MCP_SERVER_ENDPOINT=http://localhost:18080/mcp
# Call any tool (example: AccountAcceptauthorization)
./mcpclient.sh call AccountAcceptauthorization '{"<param>":"<value>"}'
# List all available tools
./mcpclient.sh list-tools
```
> **Tip:** Map the host config directory for persistent configuration:
> `-v ~/.telegram-mcp:/home/mcp/.telegram-mcp`
## Deployment — Kubernetes (Helm)
First generate a default config, then mount it when running:
```sh
docker run --rm ghcr.io/<YOUR_ORG>/telegram-mcp:latest --print-default-config > ~/.telegram-mcp/config.yaml
```
- **Static bearer token**
```sh
helm upgrade -i telegram-mcp deploy/helm \
--set image.repository=ghcr.io/<YOUR_ORG>/telegram-mcp \
--set image.tag=latest \
--set secret.static.create=true \
--set secret.static.bearerToken="YOUR_BEARER_TOKEN" \
--set config.upstream.endpoint="https://api.example.com"
```
- **OIDC authentication**
```sh
helm upgrade -i telegram-mcp deploy/helm \
--set image.repository=ghcr.io/<YOUR_ORG>/telegram-mcp \
--set image.tag=latest \
--set secret.static.create=true \
--set secret.static.oidcClientSecret="YOUR_OIDC_CLIENT_SECRET" \
--set config.auth.backend.oidc.enabled=true \
--set config.auth.backend.oidc.issuer="https://idp.example.com" \
--set config.auth.backend.oidc.clientId="my-client" \
--set config.upstream.endpoint="https://api.example.com"
```
- **LDAP authentication**
```sh
helm upgrade -i telegram-mcp deploy/helm \
--set image.repository=ghcr.io/<YOUR_ORG>/telegram-mcp \
--set image.tag=latest \
--set secret.static.create=true \
--set secret.static.ldapBindPassword="YOUR_LDAP_BIND_PASSWORD" \
--set config.auth.backend.ldap.enabled=true \
--set config.auth.backend.ldap.url="ldaps://ldap.example.com" \
--set config.auth.backend.ldap.bindDN="cn=svc,dc=example,dc=com" \
--set config.upstream.endpoint="https://api.example.com"
```
See `deploy/helm/values.yaml` for all configurable parameters.
## Contributing
We welcome contributions! Here's how you can help:
1. **Fork** the repository and create a feature branch
2. **Make your changes** — add features, fix bugs, or improve documentation
3. **Add tests** — every new feature or bug fix should include unit tests
4. **Run the test suite** — `make test` must pass with no regressions
5. **Submit a Pull Request** — describe what you changed and why
### Development Setup
```sh
git clone https://github.com/<YOUR_ORG>/telegram-mcp.git
cd telegram-mcp
make build
make test
```
### Code Style
- Follow standard Go conventions (`go fmt`, `go vet`)
- Keep functions small and focused
- Write clear commit messages
Please read [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines and our [Code of Conduct](CODE_OF_CONDUCT.md).
## License
This project is licensed under the MIT License — see the [LICENSE](LICENSE) file for details.
## Contact
For questions, suggestions, or support:
- **GitHub Issues**: [Create an issue](../../telegram-mcp/issues)
- **Discussions**: [Start a discussion](../../telegram-mcp/discussions)
- **Email**: <jameswong1376@gmail.com>
## Acknowledgments
This MCP server was generated by [MCPFather](https://github.com/flowgent-labs/mcpfather), an enterprise-grade OpenAPI-to-MCP code generator.
Built with these excellent open-source projects:
- [mcp-go](https://github.com/mark3labs/mcp-go) — Go SDK for the Model Context Protocol
- [OpenTelemetry](https://opentelemetry.io/) — observability framework for metrics and tracing
- [Prometheus](https://prometheus.io/) — metrics collection and alerting
- [Viper](https://github.com/spf13/viper) — Go configuration management
- [go-jq](https://github.com/itchyny/gojq) — Pure Go implementation of jq
- [Keycloak](https://www.keycloak.org/) — Open Source Identity and Access Management
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available