Send Telegram messages from the command line or from AI agents via the Model Context Protocol (MCP).
sent is a small Bun monorepo with a shared core library, a CLI, a local stdio MCP server, and a remote HTTP MCP server.
- Send text messages to any Telegram chat via the Bot API
- Validated inputs and responses with Zod
- CLI for one-off sends from the terminal
- Local MCP server (stdio) for editors and agent runtimes
- Remote MCP server (HTTP) for networked or hosted clients
- Bun 1.x
- A Telegram bot token from @BotFather
- A chat ID for the destination (user, group, or channel)
sent/
├── packages/
│ ├── core/ # Shared Telegram send logic and Zod schemas
│ ├── cli/ # `sent` command-line tool
│ └── local-mcp/ # Stdio MCP server
└── apps/
└── remote-mcp/ # HTTP MCP server (Hono)
| Package / app | Name | Role |
|---|---|---|
packages/core |
sent-core |
sendTelegramMessage + shared schemas |
packages/cli |
sent |
CLI: sent telegram <chatId> <message> |
packages/local-mcp |
sent-mcp |
Local MCP over stdio |
apps/remote-mcp |
sent-remote-mcp |
Remote MCP over HTTP |
bun installSet your bot token:
export TELEGRAM_BOT_TOKEN="your-bot-token"You can also put it in a .env file at the repo root (gitignored). See .env.example.
bun run dev:cli telegram <chatId> "<message>"Example:
bun run dev:cli telegram 123456789 "Hello from sent"On success:
Sent Telegram message to chat 123456789
Telegram message ID: 42
TELEGRAM_BOT_TOKEN must be set in the environment.
Start the local server:
bun run dev:local-mcpOr wire it into an MCP client. This repo includes example configs:
mcp.json
{
"mcpServers": {
"sent": {
"type": "stdio",
"command": "bun",
"args": ["run", "dev:local-mcp"],
"env": {
"TELEGRAM_BOT_TOKEN": "<your-bot-token>"
}
}
}
}opencode.json (OpenCode)
{
"mcp": {
"sent": {
"type": "local",
"command": ["bun", "run", "dev:local-mcp"],
"env": {
"TELEGRAM_BOT_TOKEN": "<your-bot-token>"
},
"enabled": true
}
}
}bun run dev:remote-mcpThe server listens on PORT (default 3000) and exposes:
POST /:botToken/mcp
Pass the Telegram bot token in the URL path. Clients connect to that MCP endpoint and call the same tool as the local server.
Both MCP servers register:
| Tool | Description |
|---|---|
send-telegram-message |
Send a text message on Telegram |
Input
| Field | Type | Required | Description |
|---|---|---|---|
chatId |
string | yes | Telegram chat ID |
message |
string | yes | Message text |
Result
Structured content includes chatId and messageId from the Telegram API.
The local server reads TELEGRAM_BOT_TOKEN from the environment. The remote server uses the token from the request path.
sent-core exports:
import { sendTelegramMessage } from "sent-core";
const result = await sendTelegramMessage({
chatId: "123456789",
message: "Hello",
botToken: process.env.TELEGRAM_BOT_TOKEN!,
});
// { chatId: string, messageId: number }Schemas (telegramMessageInputSchema, telegramMessageOptionSchema, and related types) are also exported for reuse in tools and CLIs.
| Script | Description |
|---|---|
bun run dev:cli |
Run the CLI |
bun run dev:local-mcp |
Run the local MCP server |
bun run dev:remote-mcp |
Run the remote MCP server |