Initial commit: Hermes Agent skills collection
- Trading skills (OKX, dividend, lottery, quantitative) - Creative skills (ASCII art, diagrams, video) - Development skills (GitHub, debugging, TDD) - Research skills (arXiv, blog monitoring) - Productivity skills (email, documents, notes) - MCP integration skills - Custom user skills
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
---
|
||||
description: Skills for working with MCP (Model Context Protocol) servers, tools, and integrations. Documents the built-in native MCP client — configure servers in config.yaml for automatic tool discovery.
|
||||
---
|
||||
@@ -0,0 +1,379 @@
|
||||
---
|
||||
name: native-mcp
|
||||
description: "MCP client: connect servers, register tools (stdio/HTTP)."
|
||||
version: 1.0.0
|
||||
author: Hermes Agent
|
||||
license: MIT
|
||||
platforms: [linux, macos, windows]
|
||||
metadata:
|
||||
hermes:
|
||||
tags: [MCP, Tools, Integrations]
|
||||
related_skills: [mcporter]
|
||||
---
|
||||
|
||||
# Native MCP Client
|
||||
|
||||
Hermes Agent has a built-in MCP client that connects to MCP servers at startup, discovers their tools, and makes them available as first-class tools the agent can call directly. No bridge CLI needed -- tools from MCP servers appear alongside built-in tools like `terminal`, `read_file`, etc.
|
||||
|
||||
## When to Use
|
||||
|
||||
Use this whenever you want to:
|
||||
- Connect to MCP servers and use their tools from within Hermes Agent
|
||||
- Add external capabilities (filesystem access, GitHub, databases, APIs) via MCP
|
||||
- Run local stdio-based MCP servers (npx, uvx, or any command)
|
||||
- Connect to remote HTTP/StreamableHTTP MCP servers
|
||||
- Have MCP tools auto-discovered and available in every conversation
|
||||
|
||||
For ad-hoc, one-off MCP tool calls from the terminal without configuring anything, see the `mcporter` skill instead.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **mcp Python package** -- optional dependency; install with `pip install mcp`. If not installed, MCP support is silently disabled.
|
||||
- **Node.js** -- required for `npx`-based MCP servers (most community servers)
|
||||
- **uv** -- required for `uvx`-based MCP servers (Python-based servers)
|
||||
|
||||
Install the MCP SDK:
|
||||
|
||||
```bash
|
||||
pip install mcp
|
||||
# or, if using uv:
|
||||
uv pip install mcp
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
Add MCP servers to `~/.hermes/config.yaml` under the `mcp_servers` key:
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
time:
|
||||
command: "uvx"
|
||||
args: ["mcp-server-time"]
|
||||
```
|
||||
|
||||
Restart Hermes Agent. On startup it will:
|
||||
1. Connect to the server
|
||||
2. Discover available tools
|
||||
3. Register them with the prefix `mcp_time_*`
|
||||
4. Inject them into all platform toolsets
|
||||
|
||||
You can then use the tools naturally -- just ask the agent to get the current time.
|
||||
|
||||
## Configuration Reference
|
||||
|
||||
Each entry under `mcp_servers` is a server name mapped to its config. There are two transport types: **stdio** (command-based) and **HTTP** (url-based).
|
||||
|
||||
### Stdio Transport (command + args)
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
server_name:
|
||||
command: "npx" # (required) executable to run
|
||||
args: ["-y", "pkg-name"] # (optional) command arguments, default: []
|
||||
env: # (optional) environment variables for the subprocess
|
||||
SOME_API_KEY: "value"
|
||||
timeout: 120 # (optional) per-tool-call timeout in seconds, default: 120
|
||||
connect_timeout: 60 # (optional) initial connection timeout in seconds, default: 60
|
||||
```
|
||||
|
||||
### HTTP Transport (url)
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
server_name:
|
||||
url: "https://my-server.example.com/mcp" # (required) server URL
|
||||
headers: # (optional) HTTP headers
|
||||
Authorization: "Bearer sk-..."
|
||||
timeout: 180 # (optional) per-tool-call timeout in seconds, default: 120
|
||||
connect_timeout: 60 # (optional) initial connection timeout in seconds, default: 60
|
||||
```
|
||||
|
||||
### All Config Options
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
|-------------------|--------|---------|---------------------------------------------------|
|
||||
| `command` | string | -- | Executable to run (stdio transport, required) |
|
||||
| `args` | list | `[]` | Arguments passed to the command |
|
||||
| `env` | dict | `{}` | Extra environment variables for the subprocess |
|
||||
| `url` | string | -- | Server URL (HTTP transport, required) |
|
||||
| `headers` | dict | `{}` | HTTP headers sent with every request |
|
||||
| `timeout` | int | `120` | Per-tool-call timeout in seconds |
|
||||
| `connect_timeout` | int | `60` | Timeout for initial connection and discovery |
|
||||
|
||||
Note: A server config must have either `command` (stdio) or `url` (HTTP), not both.
|
||||
|
||||
## How It Works
|
||||
|
||||
### Startup Discovery
|
||||
|
||||
When Hermes Agent starts, `discover_mcp_tools()` is called during tool initialization:
|
||||
|
||||
1. Reads `mcp_servers` from `~/.hermes/config.yaml`
|
||||
2. For each server, spawns a connection in a dedicated background event loop
|
||||
3. Initializes the MCP session and calls `list_tools()` to discover available tools
|
||||
4. Registers each tool in the Hermes tool registry
|
||||
|
||||
### Tool Naming Convention
|
||||
|
||||
MCP tools are registered with the naming pattern:
|
||||
|
||||
```
|
||||
mcp_{server_name}_{tool_name}
|
||||
```
|
||||
|
||||
Hyphens and dots in names are replaced with underscores for LLM API compatibility.
|
||||
|
||||
Examples:
|
||||
- Server `filesystem`, tool `read_file` → `mcp_filesystem_read_file`
|
||||
- Server `github`, tool `list-issues` → `mcp_github_list_issues`
|
||||
- Server `my-api`, tool `fetch.data` → `mcp_my_api_fetch_data`
|
||||
|
||||
### Auto-Injection
|
||||
|
||||
After discovery, MCP tools are automatically injected into all `hermes-*` platform toolsets (CLI, Discord, Telegram, etc.). This means MCP tools are available in every conversation without any additional configuration.
|
||||
|
||||
### Connection Lifecycle
|
||||
|
||||
- Each server runs as a long-lived asyncio Task in a background daemon thread
|
||||
- Connections persist for the lifetime of the agent process
|
||||
- If a connection drops, automatic reconnection with exponential backoff kicks in (up to 5 retries, max 60s backoff)
|
||||
- On agent shutdown, all connections are gracefully closed
|
||||
|
||||
### Idempotency
|
||||
|
||||
`discover_mcp_tools()` is idempotent -- calling it multiple times only connects to servers that aren't already connected. Failed servers are retried on subsequent calls.
|
||||
|
||||
## Transport Types
|
||||
|
||||
### Stdio Transport
|
||||
|
||||
The most common transport. Hermes launches the MCP server as a subprocess and communicates over stdin/stdout.
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
filesystem:
|
||||
command: "npx"
|
||||
args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"]
|
||||
```
|
||||
|
||||
The subprocess inherits a **filtered** environment (see Security section below) plus any variables you specify in `env`.
|
||||
|
||||
### HTTP / StreamableHTTP Transport
|
||||
|
||||
For remote or shared MCP servers. Requires the `mcp` package to include HTTP client support (`mcp.client.streamable_http`).
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
remote_api:
|
||||
url: "https://mcp.example.com/mcp"
|
||||
headers:
|
||||
Authorization: "Bearer sk-..."
|
||||
```
|
||||
|
||||
If HTTP support is not available in your installed `mcp` version, the server will fail with an ImportError and other servers will continue normally.
|
||||
|
||||
## Security
|
||||
|
||||
### Environment Variable Filtering
|
||||
|
||||
For stdio servers, Hermes does NOT pass your full shell environment to MCP subprocesses. Only safe baseline variables are inherited:
|
||||
|
||||
- `PATH`, `HOME`, `USER`, `LANG`, `LC_ALL`, `TERM`, `SHELL`, `TMPDIR`
|
||||
- Any `XDG_*` variables
|
||||
|
||||
All other environment variables (API keys, tokens, secrets) are excluded unless you explicitly add them via the `env` config key. This prevents accidental credential leakage to untrusted MCP servers.
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
github:
|
||||
command: "npx"
|
||||
args: ["-y", "@modelcontextprotocol/server-github"]
|
||||
env:
|
||||
# Only this token is passed to the subprocess
|
||||
GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_..."
|
||||
```
|
||||
|
||||
### Credential Stripping in Error Messages
|
||||
|
||||
If an MCP tool call fails, any credential-like patterns in the error message are automatically redacted before being shown to the LLM. This covers:
|
||||
|
||||
- GitHub PATs (`ghp_...`)
|
||||
- OpenAI-style keys (`sk-...`)
|
||||
- Bearer tokens
|
||||
- Generic `token=`, `key=`, `API_KEY=`, `password=`, `secret=` patterns
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "MCP SDK not available -- skipping MCP tool discovery"
|
||||
|
||||
The `mcp` Python package is not installed. Install it:
|
||||
|
||||
```bash
|
||||
pip install mcp
|
||||
```
|
||||
|
||||
### "No MCP servers configured"
|
||||
|
||||
No `mcp_servers` key in `~/.hermes/config.yaml`, or it's empty. Add at least one server.
|
||||
|
||||
### "Failed to connect to MCP server 'X'"
|
||||
|
||||
Common causes:
|
||||
- **Command not found**: The `command` binary isn't on PATH. Ensure `npx`, `uvx`, or the relevant command is installed.
|
||||
- **Package not found**: For npx servers, the npm package may not exist or may need `-y` in args to auto-install.
|
||||
- **Timeout**: The server took too long to start. Increase `connect_timeout`.
|
||||
- **Port conflict**: For HTTP servers, the URL may be unreachable.
|
||||
|
||||
### "MCP server 'X' requires HTTP transport but mcp.client.streamable_http is not available"
|
||||
|
||||
Your `mcp` package version doesn't include HTTP client support. Upgrade:
|
||||
|
||||
```bash
|
||||
pip install --upgrade mcp
|
||||
```
|
||||
|
||||
### Tools not appearing
|
||||
|
||||
- Check that the server is listed under `mcp_servers` (not `mcp` or `servers`)
|
||||
- Ensure the YAML indentation is correct
|
||||
- Look at Hermes Agent startup logs for connection messages
|
||||
- Tool names are prefixed with `mcp_{server}_{tool}` -- look for that pattern
|
||||
|
||||
### Connection keeps dropping
|
||||
|
||||
The client retries up to 5 times with exponential backoff (1s, 2s, 4s, 8s, 16s, capped at 60s). If the server is fundamentally unreachable, it gives up after 5 attempts. Check the server process and network connectivity.
|
||||
|
||||
## Examples
|
||||
|
||||
### Time Server (uvx)
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
time:
|
||||
command: "uvx"
|
||||
args: ["mcp-server-time"]
|
||||
```
|
||||
|
||||
Registers tools like `mcp_time_get_current_time`.
|
||||
|
||||
### Filesystem Server (npx)
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
filesystem:
|
||||
command: "npx"
|
||||
args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/documents"]
|
||||
timeout: 30
|
||||
```
|
||||
|
||||
Registers tools like `mcp_filesystem_read_file`, `mcp_filesystem_write_file`, `mcp_filesystem_list_directory`.
|
||||
|
||||
### GitHub Server with Authentication
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
github:
|
||||
command: "npx"
|
||||
args: ["-y", "@modelcontextprotocol/server-github"]
|
||||
env:
|
||||
GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_xxxxxxxxxxxxxxxxxxxx"
|
||||
timeout: 60
|
||||
```
|
||||
|
||||
Registers tools like `mcp_github_list_issues`, `mcp_github_create_pull_request`, etc.
|
||||
|
||||
### Remote HTTP Server
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
company_api:
|
||||
url: "https://mcp.mycompany.com/v1/mcp"
|
||||
headers:
|
||||
Authorization: "Bearer sk-xxxxxxxxxxxxxxxxxxxx"
|
||||
X-Team-Id: "engineering"
|
||||
timeout: 180
|
||||
connect_timeout: 30
|
||||
```
|
||||
|
||||
### LongPort MCP (Financial Data)
|
||||
|
||||
Connects to LongPort's broker/stock-market MCP service. Uses a two-step auth flow: exchange an auth code for a Bearer token at the `/agent` endpoint, then connect the main service with that token.
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
longport:
|
||||
url: "https://mcp.longport.cn"
|
||||
headers:
|
||||
Authorization: "Bearer eyJh...<your_token_here>"
|
||||
timeout: 180
|
||||
connect_timeout: 60
|
||||
```
|
||||
|
||||
**Auth flow** (run once to get the token):
|
||||
1. Temporarily connect to `https://mcp.longport.cn/agent` — it exposes only the `authenticate` tool
|
||||
2. Call `authenticate({ "code": "<one-time code from LongPort App>" })` → returns the access token
|
||||
3. Add the main service config (above) with that token and reconnect
|
||||
|
||||
Remaining tools (quotes, orders, positions, watchlist, candlesticks) are all on the main service. The auth endpoint connection can be removed after token exchange.
|
||||
|
||||
### Multiple Servers
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
time:
|
||||
command: "uvx"
|
||||
args: ["mcp-server-time"]
|
||||
|
||||
filesystem:
|
||||
command: "npx"
|
||||
args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
|
||||
|
||||
github:
|
||||
command: "npx"
|
||||
args: ["-y", "@modelcontextprotocol/server-github"]
|
||||
env:
|
||||
GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_xxxxxxxxxxxxxxxxxxxx"
|
||||
|
||||
company_api:
|
||||
url: "https://mcp.internal.company.com/mcp"
|
||||
headers:
|
||||
Authorization: "Bearer sk-xxxxxxxxxxxxxxxxxxxx"
|
||||
timeout: 300
|
||||
```
|
||||
|
||||
All tools from all servers are registered and available simultaneously. Each server's tools are prefixed with its name to avoid collisions.
|
||||
|
||||
## Sampling (Server-Initiated LLM Requests)
|
||||
|
||||
Hermes supports MCP's `sampling/createMessage` capability — MCP servers can request LLM completions through the agent during tool execution. This enables agent-in-the-loop workflows (data analysis, content generation, decision-making).
|
||||
|
||||
Sampling is **enabled by default**. Configure per server:
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
my_server:
|
||||
command: "npx"
|
||||
args: ["-y", "my-mcp-server"]
|
||||
sampling:
|
||||
enabled: true # default: true
|
||||
model: "gemini-3-flash" # model override (optional)
|
||||
max_tokens_cap: 4096 # max tokens per request
|
||||
timeout: 30 # LLM call timeout (seconds)
|
||||
max_rpm: 10 # max requests per minute
|
||||
allowed_models: [] # model whitelist (empty = all)
|
||||
max_tool_rounds: 5 # tool loop limit (0 = disable)
|
||||
log_level: "info" # audit verbosity
|
||||
```
|
||||
|
||||
Servers can also include `tools` in sampling requests for multi-turn tool-augmented workflows. The `max_tool_rounds` config prevents infinite tool loops. Per-server audit metrics (requests, errors, tokens, tool use count) are tracked via `get_mcp_status()`.
|
||||
|
||||
Disable sampling for untrusted servers with `sampling: { enabled: false }`.
|
||||
|
||||
## Notes
|
||||
|
||||
- For Telegram account access via MCP (contacts, messages, search), see `references/telegram-mcp-servers.md`
|
||||
- MCP tools are called synchronously from the agent's perspective but run asynchronously on a dedicated background event loop
|
||||
- Tool results are returned as JSON with either `{"result": "..."}` or `{"error": "..."}`
|
||||
- The native MCP client is independent of `mcporter` -- you can use both simultaneously
|
||||
- Server connections are persistent and shared across all conversations in the same agent process
|
||||
- Adding or removing servers requires restarting the agent (no hot-reload currently)
|
||||
@@ -0,0 +1,65 @@
|
||||
# Telegram MCP Servers
|
||||
|
||||
Extend Hermes with full Telegram account access (contacts, messages, search, media) via MCP.
|
||||
|
||||
## Top Options (ranked)
|
||||
|
||||
### 1. chaindead/telegram-mcp ⭐ RECOMMENDED
|
||||
- **GitHub**: https://github.com/chaindead/telegram-mcp
|
||||
- **Language**: Go
|
||||
- **Auth**: MTProto (your real TG account, NOT bot)
|
||||
- **Stars**: 330+
|
||||
- **Install**: `brew install chaindead/tap/telegram-mcp` or `npx -y @chaindead/telegram-mcp` or `go install github.com/chaindead/telegram-mcp@latest`
|
||||
- **Features**: Dialog listing, message retrieval, unread filtering, mark as read, draft messages, contacts, media download
|
||||
- **Env vars**: `TG_APP_ID`, `TG_APP_HASH` (from https://my.telegram.org/auth)
|
||||
- **Config for Hermes**:
|
||||
```yaml
|
||||
mcp_servers:
|
||||
telegram:
|
||||
command: "npx"
|
||||
args: ["-y", "@chaindead/telegram-mcp"]
|
||||
env:
|
||||
TG_APP_ID: "your_api_id"
|
||||
TG_APP_HASH: "your_api_hash"
|
||||
```
|
||||
|
||||
### 2. sparfenyuk/mcp-telegram
|
||||
- **GitHub**: https://github.com/sparfenyuk/mcp-telegram
|
||||
- **Language**: Python
|
||||
- **Auth**: MTProto (real account)
|
||||
- **Install**: `uv tool install git+https://github.com/sparfenyuk/mcp-telegram`
|
||||
- **Features**: Dialog list, messages by date, unread messages, contacts, media download, draft messages, mark as read
|
||||
- **Setup**: Requires first-time sign-in:
|
||||
```bash
|
||||
mcp-telegram sign-in --api-id <ID> --api-hash <HASH> --phone-number <PHONE>
|
||||
```
|
||||
- **Config for Hermes**:
|
||||
```yaml
|
||||
mcp_servers:
|
||||
telegram:
|
||||
command: "mcp-telegram"
|
||||
args: ["serve"]
|
||||
```
|
||||
|
||||
### 3. fast-mcp-telegram (leshchenko1979)
|
||||
- **GitHub**: https://github.com/leshchenko1979/fast-mcp-telegram
|
||||
- **Stars**: 46
|
||||
- **Features**: MTProto, multi-user ACL, dual transport (stdio + HTTP SSE), voice transcription
|
||||
- **Install**: `uvx fast-mcp-telegram`
|
||||
|
||||
### 4. Bot API based (mcp-server-telegram)
|
||||
- **Install**: `pip install mcp-server-telegram`
|
||||
- **Auth**: Bot token from @BotFather
|
||||
- **Limitation**: Bots CANNOT read arbitrary user DMs, no contacts, no search
|
||||
- **Use case**: Notification bots, broadcast only
|
||||
|
||||
## Recommendation
|
||||
|
||||
**Use chaindead/telegram-mcp** for full account access. It's Go-based (fast), well-maintained, and supports contacts + message search + media download — exactly what was needed to "查看TG联系人" and "搜索聊天记录".
|
||||
|
||||
### Prerequisites
|
||||
1. Get API credentials: https://my.telegram.org/auth → API development tools
|
||||
2. Note: This is separate from Bot tokens. MTProto API gives full user-account access.
|
||||
|
||||
### Security Note
|
||||
MCP server gets full read access to your Telegram account. Only install servers you trust. The `env` config ensures credentials aren't leaked to other servers.
|
||||
@@ -0,0 +1,148 @@
|
||||
---
|
||||
name: telegram-mcp
|
||||
description: "Connect Telegram account to AI agent via MCP (Model Context Protocol). Read contacts, search messages across chats, manage dialogs, download media — full TG client capability. Use when user asks to view TG contacts, search messages in other chats, or interact with Telegram beyond the built-in bot channel."
|
||||
---
|
||||
|
||||
# Telegram MCP Integration
|
||||
|
||||
Bridges the user's real Telegram account (MTProto API) to Hermes via MCP, unlocking capabilities the built-in bot channel cannot provide.
|
||||
|
||||
## When to Use
|
||||
|
||||
- User asks to view Telegram contacts
|
||||
- User asks to search messages in chats OTHER than the current bot conversation
|
||||
- User wants to read/manage Telegram dialogs (channels, groups, DMs)
|
||||
- User wants to send messages from their personal TG account (not the bot)
|
||||
- User wants to download media files from Telegram
|
||||
|
||||
## What Bot Channel Can vs Cannot Do
|
||||
|
||||
| Capability | Built-in Bot | MCP (MTProto) |
|
||||
|---|---|---|
|
||||
| Send to current chat | ✅ | ✅ |
|
||||
| View contacts | ❌ | ✅ |
|
||||
| Read any chat/dialog | ❌ | ✅ |
|
||||
| Search messages globally | ❌ | ✅ |
|
||||
| Download media | ❌ | ✅ |
|
||||
| Draft messages | ❌ | ✅ |
|
||||
| Mark as read | ❌ | ✅ |
|
||||
|
||||
## Recommended Server: sparfenyuk/mcp-telegram
|
||||
|
||||
**Repo**: https://github.com/sparfenyuk/mcp-telegram
|
||||
|
||||
Python-based, actively maintained, supports:
|
||||
- Dialog list (chats, channels, groups)
|
||||
- Unread message retrieval
|
||||
- Message search by date/time
|
||||
- Contact list
|
||||
- Media download
|
||||
- Draft messages
|
||||
- Mark as read
|
||||
|
||||
### Prerequisites
|
||||
|
||||
1. **Telegram API credentials** from https://my.telegram.org/auth:
|
||||
- `TG_API_ID` (numeric)
|
||||
- `TG_API_HASH` (string)
|
||||
- These are DIFFERENT from a Bot Token — they authenticate your personal account
|
||||
|
||||
2. **Phone number** + 2FA password (if enabled) for first-time login
|
||||
|
||||
3. **Python** with `uv` tool installed
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
uv tool install git+https://github.com/sparfenyuk/mcp-telegram
|
||||
```
|
||||
|
||||
### First-time Login
|
||||
|
||||
```bash
|
||||
mcp-telegram sign-in --api-id <your-api-id> --api-hash <your-api-hash> --phone-number <your-phone-number>
|
||||
```
|
||||
|
||||
Enter the verification code from Telegram. Session is persisted.
|
||||
|
||||
### Hermes Integration (native-mcp)
|
||||
|
||||
Add to `~/.hermes/config.yaml` under `mcp_servers`:
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
telegram-mcp:
|
||||
command: mcp-telegram
|
||||
env:
|
||||
TG_API_ID: "your-api-id"
|
||||
TG_API_HASH: "your-api-hash"
|
||||
```
|
||||
|
||||
Or load the `native-mcp` skill for detailed MCP setup instructions.
|
||||
|
||||
## Alternative Servers
|
||||
|
||||
| Server | Language | Stars | Notes |
|
||||
|---|---|---|---|
|
||||
| chaindead/telegram-mcp | Go | 300+ | Popular, brew install, but Go-based |
|
||||
| fast-mcp-telegram (leshchenko1979) | Python | 46 | Production-grade, ACL, voice transcription |
|
||||
| IQAIcom/mcp-telegram | TypeScript | 7 | Bot API based (not MTProto), limited |
|
||||
|
||||
**Prefer MTProto-based servers** (sparfenyuk, chaindead) over Bot API servers — they authenticate as your real account and can access contacts, all chats, search, etc.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- **API ID ≠ Bot Token**: my.telegram.org gives you API ID/Hash for MTProto (your account). @BotFather gives Bot Token. They are completely different auth mechanisms.
|
||||
- **Session persistence**: First login creates a session file. If it expires, re-run `mcp-telegram sign-in`.
|
||||
- **Rate limits**: Telegram enforces API rate limits. Don't spam requests.
|
||||
- **Privacy**: MTProto gives full account access. Only use on trusted machines.
|
||||
- **Mihomo proxy**: If TG is blocked, set proxy via env or the MCP server's proxy config.
|
||||
- **pydantic-settings env_file conflict**: `TelegramSettings` uses `env_file = ".env"` which reads ALL vars from the `.env` file, not just `TELEGRAM_*` prefixed ones. If other env vars exist (e.g. `LONGBRIDGE_*`), pydantic's `extra=forbid` rejects them with `ValidationError: Extra inputs are not permitted`. **Fix**: unset conflicting vars before running sign-in, or write a custom Telethon script bypassing pydantic entirely.
|
||||
- **python-socks vs pysocks**: Telethon requires `python-socks[asyncio]` (NOT `pysocks`) for SOCKS5 proxy support. Install into the uv tool venv: `uv pip install --python ~/.local/share/uv/tools/mcp-telegram/bin/python3 python-socks[asyncio]`
|
||||
- **Verification code expiry (~30s)**: Telegram MTProto codes expire very quickly. The round-trip of "send code → user reads on phone → tells agent → agent submits" via chat almost always exceeds the window. **Recommended**: Have the user SSH into the server and run the sign-in script directly in an interactive terminal. The script should use `client.start(phone=phone)` which handles the prompt interactively.
|
||||
- **Sign-in script template** (for user to run via SSH):
|
||||
```python
|
||||
from telethon import TelegramClient
|
||||
import socks
|
||||
client = TelegramClient('/path/to/session', API_ID, API_HASH, proxy=(socks.SOCKS5, '127.0.0.1', 7890))
|
||||
await client.start(phone='+XXXXXXXX')
|
||||
```
|
||||
- **fast-mcp-telegram alternative**: Installed via `uv tool install fast-mcp-telegram`. Has better auth flow features but does NOT support SOCKS5 proxy (only MTProto proxy), making it unusable behind Mihomo/Clash. Stick with sparfenyuk/mcp-telegram + python-socks.
|
||||
### ⚠️ `mcp-telegram sign-in` env var conflict (CRITICAL)
|
||||
|
||||
`TelegramSettings` uses `pydantic-settings` with `env_file = ".env"` and `extra = "forbid"`. It reads ALL variables from `~/.hermes/.env` (or CWD `.env`), not just `TELEGRAM_*` prefixed ones. If you have other env vars (e.g. `LONGBRIDGE_*`, `OKX_*`), the sign-in command crashes with `ValidationError: Extra inputs are not permitted`.
|
||||
|
||||
**Fix**: Do NOT use `mcp-telegram sign-in`. Use the direct Telethon login script instead (see `references/telethon-login.py`). It bypasses pydantic-settings entirely.
|
||||
|
||||
### ⚠️ Verification code expiry (CRITICAL)
|
||||
|
||||
Telegram codes expire in ~30 seconds. The round-trip of "send code → user reads on phone → user tells agent → agent submits" almost always exceeds this window.
|
||||
|
||||
**Fix**: User MUST SSH into the server and run the login script directly in a terminal. They type the code immediately when prompted — zero round-trip delay. Copy the script from `references/telethon-login.py` to `/tmp/tg_login.sh` and tell user to `bash /tmp/tg_login.sh`.
|
||||
|
||||
### ⚠️ SOCKS5 proxy for firewalled servers
|
||||
|
||||
Telethon needs `python-socks` (NOT `pysocks`) for SOCKS5 proxy support. After installing `mcp-telegram`, also install:
|
||||
|
||||
```bash
|
||||
uv pip install --python $(which mcp-telegram | sed 's|/bin/mcp-telegram|/bin/python3|') python-socks[asyncio]
|
||||
```
|
||||
|
||||
`fast-mcp-telegram` does NOT support SOCKS5 proxy — it only supports MTProto proxy (`tg://proxy`). Do not use it on servers behind firewalls.
|
||||
|
||||
### ⚠️ Phone number masking in Hermes
|
||||
|
||||
Hermes auto-detects and masks phone numbers in tool output (e.g. `+172****0777`). If you need to pass a phone number to a script, store it in a file first (the file content is not masked), then read it from the script.
|
||||
|
||||
### ⚠️ Login must happen interactively
|
||||
|
||||
The `mcp-telegram sign-in` command uses `input()` which fails in non-interactive terminal contexts. Background processes and `pty` mode also cannot reliably provide stdin. The ONLY reliable approach is direct SSH access.
|
||||
|
||||
### ⚠️ API credential masking in terminal writes
|
||||
|
||||
Hermes auto-masks API keys, secrets, and tokens in tool output and file writes. If you need to write OKX/TG credentials to `~/.bashrc`, the values get replaced with `***`. Workaround: tell the user to run the `cat >> ~/.bashrc` command themselves in a direct terminal session. Never try to write credentials through tools — it silently produces truncated values.
|
||||
|
||||
## References
|
||||
|
||||
See `references/server-comparison.md` for detailed feature comparison of all Telegram MCP servers.
|
||||
See `references/telethon-login.sh` for a ready-to-use login script (bypasses pydantic-settings env conflict).
|
||||
@@ -0,0 +1,74 @@
|
||||
# Telegram MCP Server Comparison (2026-06-15)
|
||||
|
||||
## Server Options Found on GitHub (sorted by popularity)
|
||||
|
||||
### 1. chaindead/telegram-mcp ⭐ 300+
|
||||
- **Language**: Go
|
||||
- **Auth**: MTProto (real account)
|
||||
- **Install**: `brew install chaindead/tap/telegram-mcp` or `go install` or binary
|
||||
- **Features**: Dialog list, unread messages, mark read, drafts, message retrieval, contacts, media download
|
||||
- **Transport**: stdio
|
||||
- **Pros**: Most popular, well-documented, cross-platform
|
||||
- **Cons**: Go binary (harder to debug/extend), requires Go 1.24+ for source install
|
||||
|
||||
### 2. sparfenyuk/mcp-telegram ⭐ active (RECOMMENDED)
|
||||
- **Language**: Python
|
||||
- **Auth**: MTProto (real account)
|
||||
- **Install**: `uv tool install git+https://github.com/sparfenyuk/mcp-telegram`
|
||||
- **Features**: Same as chaindead — dialogs, messages, contacts, media, drafts
|
||||
- **Transport**: stdio
|
||||
- **Pros**: Python (easy to extend), uv-based install, CLI sign-in flow
|
||||
- **Cons**: Less stars than chaindead; **pydantic-settings env var conflict** — sign-in command reads ALL `.env` vars and rejects unknowns. Use direct Telethon login instead (see `telethon-login.py`)
|
||||
|
||||
### 3. fast-mcp-telegram (leshchenko1979) ⭐ 46
|
||||
- **Language**: Python
|
||||
- **Auth**: MTProto (real account)
|
||||
- **Install**: `uv tool install fast-mcp-telegram`
|
||||
- **Features**: Production-grade, multi-user ACL, dual transport (stdio + HTTP SSE), voice transcription
|
||||
- **Transport**: stdio + HTTP SSE
|
||||
- **Pros**: Most feature-rich, ACL for multi-user, voice transcription
|
||||
- **Cons**: **Does NOT support SOCKS5 proxy** — only MTProto proxy (`tg://proxy`). Unusable on servers behind firewalls (e.g. China) that need SOCKS5/HTTP proxy to reach Telegram.
|
||||
|
||||
### 4. zhigang1992/telegram-mcp ⭐ 14
|
||||
- **Language**: TypeScript
|
||||
- **Auth**: MTProto
|
||||
- **Features**: Send/read/search messages, wait for incoming, conversation history
|
||||
- **Transport**: stdio
|
||||
|
||||
### 5. IQAIcom/mcp-telegram ⭐ 7
|
||||
- **Language**: TypeScript
|
||||
- **Auth**: Bot API (BotFather token)
|
||||
- **Features**: Send message, get channel info, forward, pin, get members
|
||||
- **Limitation**: Bot API only — cannot access contacts, personal chats, or global search
|
||||
- **Use case**: Channel/bot management, NOT personal account access
|
||||
|
||||
### 6. moltis ⭐ 2740
|
||||
- **Note**: Full agent platform (Rust), not a standalone MCP server
|
||||
- **Overkill** if you just want Telegram MCP
|
||||
|
||||
## Recommendation
|
||||
|
||||
**For Hermes integration (default)**: Use `sparfenyuk/mcp-telegram` (Python, uv install). Skip `mcp-telegram sign-in` due to pydantic env var conflict — use the direct Telethon login script instead.
|
||||
|
||||
**For firewalled servers (China, etc.)**: MUST use `sparfenyuk/mcp-telegram` — it's the only one supporting SOCKS5 proxy via `python-socks`. `fast-mcp-telegram` will fail to connect.
|
||||
|
||||
**Avoid** Bot API-based servers (like IQAIcom) if you need contacts, cross-chat search, or personal account access.
|
||||
|
||||
## Key Distinction: MTProto vs Bot API
|
||||
|
||||
| | MTProto | Bot API |
|
||||
|---|---|---|
|
||||
| Auth | Your real TG account | Bot token from @BotFather |
|
||||
| Contacts | ✅ | ❌ |
|
||||
| All chats | ✅ | Only where bot is added |
|
||||
| Global search | ✅ | ❌ |
|
||||
| Rate limits | Per-account | Per-bot (more lenient) |
|
||||
| Risk | Account suspension if abused | Low risk |
|
||||
|
||||
## Proxy Support Matrix
|
||||
|
||||
| Server | SOCKS5 | HTTP Proxy | MTProto Proxy |
|
||||
|---|---|---|---|
|
||||
| sparfenyuk/mcp-telegram | ✅ (python-socks) | ❌ | ❌ |
|
||||
| chaindead/telegram-mcp | ❓ | ❓ | ❓ |
|
||||
| fast-mcp-telegram | ❌ | ❌ | ✅ |
|
||||
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Telegram MTProto login script for first-time authentication.
|
||||
Bypasses mcp-telegram's pydantic-settings env_file conflict.
|
||||
|
||||
Usage (user must run interactively via SSH):
|
||||
bash /tmp/tg_login.sh
|
||||
|
||||
The script will:
|
||||
1. Ask for phone number
|
||||
2. Send verification code to Telegram
|
||||
3. Prompt for code (type immediately when received)
|
||||
4. Handle 2FA if needed
|
||||
5. Save session for mcp-telegram to use
|
||||
"""
|
||||
import asyncio
|
||||
from telethon import TelegramClient
|
||||
from telethon.errors import SessionPasswordNeededError
|
||||
import socks
|
||||
import sys
|
||||
import os
|
||||
|
||||
# === Configuration ===
|
||||
# Update these or read from env
|
||||
API_ID = int(os.environ.get('TG_API_ID', '0'))
|
||||
API_HASH = os.environ.get('TG_API_HASH', '')
|
||||
SESSION_PATH = os.path.expanduser('~/.local/share/state/mcp-telegram/mcp_telegram_session')
|
||||
PROXY = (socks.SOCKS5, '127.0.0.1', 7890) # Mihomo
|
||||
|
||||
|
||||
async def main():
|
||||
if not API_ID or not API_HASH:
|
||||
print("Error: Set TG_API_ID and TG_API_HASH environment variables first.")
|
||||
print(" export TG_API_ID=your_id")
|
||||
print(" export TG_API_HASH=your_hash")
|
||||
sys.exit(1)
|
||||
|
||||
phone = input("Phone number (with country code, e.g. +1234567890): ").strip()
|
||||
|
||||
# Ensure session directory exists
|
||||
os.makedirs(os.path.dirname(SESSION_PATH), exist_ok=True)
|
||||
|
||||
client = TelegramClient(SESSION_PATH, API_ID, API_HASH, proxy=PROXY)
|
||||
|
||||
try:
|
||||
await client.start(phone=phone)
|
||||
except SessionPasswordNeededError:
|
||||
pwd = input("2FA password: ").strip()
|
||||
await client.sign_in(password=pwd)
|
||||
|
||||
me = await client.get_me()
|
||||
print(f"\n✅ Login successful!")
|
||||
print(f" User: {me.username} (ID: {me.id})")
|
||||
print(f" Session saved to: {SESSION_PATH}")
|
||||
print(f"\nYou can now use mcp-telegram MCP server.")
|
||||
await client.disconnect()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
# Telegram MTProto login script
|
||||
# Run this via SSH: bash /tmp/tg_login.sh
|
||||
#
|
||||
# This bypasses the mcp-telegram CLI (which has pydantic-settings env conflicts)
|
||||
# and uses Telethon directly with SOCKS5 proxy.
|
||||
|
||||
/home/openclaw/.local/share/uv/tools/mcp-telegram/bin/python3 << 'EOF'
|
||||
import asyncio
|
||||
from telethon import TelegramClient
|
||||
from telethon.errors import SessionPasswordNeededError
|
||||
import socks
|
||||
|
||||
API_ID = 37679203
|
||||
API_HASH = '514a2ba8b7898365c9070da4739e8deb'
|
||||
SESSION = '/home/openclaw/.local/share/state/mcp-telegram/mcp_telegram_session'
|
||||
|
||||
async def main():
|
||||
phone = input("Phone (e.g. +1234567890): ").strip()
|
||||
client = TelegramClient(
|
||||
SESSION, API_ID, API_HASH,
|
||||
proxy=(socks.SOCKS5, '127.0.0.1', 7890)
|
||||
)
|
||||
await client.start(phone=phone)
|
||||
me = await client.get_me()
|
||||
print(f"\n✅ Logged in as: {me.username} (ID: {me.id})")
|
||||
await client.disconnect()
|
||||
|
||||
asyncio.run(main())
|
||||
EOF
|
||||
Reference in New Issue
Block a user