cli.pyâĸ10.9 kB
#!/usr/bin/env python3
"""CLI for telegram-mcp-server setup and configuration"""
import os
import sys
import json
import asyncio
from pathlib import Path
def get_claude_config_path(scope="user"):
"""
Get Claude Code config path based on scope
Args:
scope: "user" (default), "project", or "local"
Returns:
Path to config file
"""
if scope == "user":
return Path.home() / ".claude" / "mcp.json"
elif scope == "project":
return Path.cwd() / ".mcp.json"
elif scope == "local":
return Path.cwd() / ".claude" / "mcp.json"
else:
raise ValueError(f"Invalid scope: {scope}")
def get_codex_config_path():
"""Get Codex config path"""
return Path.home() / ".codex" / "config.toml"
async def interactive_setup():
"""Interactive setup wizard"""
print("đ¤ Telegram MCP Server - Setup Wizard")
print("=" * 50)
print()
# Step 0: Choose client and scope
print("Step 0: Choose Configuration")
print("-" * 50)
print("Which AI coding assistant are you using?")
print(" 1. Claude Code (Anthropic)")
print(" 2. Codex (OpenAI)")
print(" 3. Both")
print()
client_choice = input("Enter choice [1]: ").strip() or "1"
scope = None
if client_choice in ["1", "3"]:
print()
print("Choose configuration scope for Claude Code:")
print(" 1. User scope (global, ~/.claude/mcp.json)")
print(" 2. Project scope (shared, .mcp.json in project root)")
print(" 3. Local scope (project-specific, .claude/mcp.json)")
print()
print("đĄ Recommendation:")
print(" - User scope: Personal use across all projects")
print(" - Project scope: Team collaboration (checked into git)")
print(" - Local scope: Project-specific, not shared")
print()
scope_choice = input("Enter choice [1]: ").strip() or "1"
scope_map = {"1": "user", "2": "project", "3": "local"}
scope = scope_map.get(scope_choice, "user")
if client_choice == "2":
print()
print("âšī¸ Note: Codex only supports global configuration (~/.codex/config.toml)")
print(" All projects will share the same MCP configuration.")
print()
# Step 1: Bot Token
print("Step 1: Telegram Bot Token")
print("-" * 50)
print("1. Open Telegram and search for @BotFather")
print("2. Send: /newbot")
print("3. Follow instructions to create your bot")
print("4. Copy the Bot Token (format: 123456789:ABCdef...)")
print()
bot_token = input("Enter your Bot Token: ").strip()
if not bot_token:
print("â Bot Token is required")
sys.exit(1)
# Validate token format
if ":" not in bot_token:
print("â ī¸ Warning: Token format looks incorrect (should contain ':')")
# Step 2: Verify bot
print()
print("Step 2: Verifying bot...")
print("-" * 50)
try:
from telegram import Bot
bot = Bot(token=bot_token)
bot_info = await bot.get_me()
print(f"â
Bot verified: @{bot_info.username}")
except Exception as e:
print(f"â Failed to verify bot: {e}")
print("Please check your Bot Token and try again")
sys.exit(1)
# Step 3: Chat ID
print()
print("Step 3: Get Chat ID")
print("-" * 50)
print("1. Open Telegram and search for your bot")
print("2. Click START or send any message")
print("3. Press Enter here to auto-detect your Chat ID")
print()
input("Press Enter after sending a message to your bot...")
try:
updates = await bot.get_updates()
if updates:
chat_id = str(updates[-1].message.chat.id)
print(f"â
Chat ID detected: {chat_id}")
else:
print("â ī¸ No messages found. Please enter manually:")
print(" Visit: https://api.telegram.org/bot{}/getUpdates".format(bot_token))
print(" Find: \"chat\":{\"id\":123456789}")
chat_id = input("Enter your Chat ID: ").strip()
except Exception as e:
print(f"â ī¸ Auto-detection failed: {e}")
print("Please enter manually:")
chat_id = input("Enter your Chat ID: ").strip()
if not chat_id:
print("â Chat ID is required")
sys.exit(1)
# Step 4: Generate config
print()
print("Step 4: Generating configuration")
print("-" * 50)
# Detect installation method
if os.path.exists(Path.home() / ".local" / "bin" / "uvx"):
command = "uvx"
args = ["telegram-mcp-server"]
else:
command = sys.executable
args = ["-m", "telegram_mcp_server"]
# Configure Claude Code
if client_choice in ["1", "3"]:
config_path = get_claude_config_path(scope)
config_path.parent.mkdir(parents=True, exist_ok=True)
# Load existing config or create new
if config_path.exists():
with open(config_path, 'r') as f:
config = json.load(f)
else:
config = {}
# Ensure mcpServers key exists
if "mcpServers" not in config:
config["mcpServers"] = {}
# Add telegram server config
config["mcpServers"]["telegram"] = {
"command": command,
"args": args,
"env": {
"TELEGRAM_BOT_TOKEN": bot_token,
"TELEGRAM_CHAT_ID": chat_id
}
}
# Save config
with open(config_path, 'w') as f:
json.dump(config, f, indent=2)
print(f"â
Claude Code configuration saved to: {config_path}")
if scope == "project":
print("đĄ Remember to commit .mcp.json to version control for team sharing")
# Configure Codex
if client_choice in ["2", "3"]:
try:
import toml
except ImportError:
print("â ī¸ Installing toml package for Codex configuration...")
import subprocess
subprocess.check_call([sys.executable, "-m", "pip", "install", "toml"])
import toml
codex_config_path = get_codex_config_path()
codex_config_path.parent.mkdir(parents=True, exist_ok=True)
# Load existing config or create new
if codex_config_path.exists():
with open(codex_config_path, 'r') as f:
codex_config = toml.load(f)
else:
codex_config = {}
# Ensure mcp_servers section exists
if "mcp_servers" not in codex_config:
codex_config["mcp_servers"] = {}
# Add telegram server config
codex_config["mcp_servers"]["telegram"] = {
"command": command,
"args": args,
"tool_timeout_sec": 604800, # 7 days for unattended mode
"env": {
"TELEGRAM_BOT_TOKEN": bot_token,
"TELEGRAM_CHAT_ID": chat_id
}
}
# Save config
with open(codex_config_path, 'w') as f:
toml.dump(codex_config, f)
print(f"â
Codex configuration saved to: {codex_config_path}")
# Step 5: Test connection
print()
print("Step 5: Testing connection")
print("-" * 50)
try:
await bot.send_message(
chat_id=chat_id,
text="â
Telegram MCP Server configured successfully!\n\n"
"You can now start using Claude Code with Telegram integration."
)
print("â
Test message sent to Telegram")
except Exception as e:
print(f"â ī¸ Failed to send test message: {e}")
# Done
print()
print("=" * 50)
print("đ Setup complete!")
print()
print("Next steps:")
print(" 1. Start your AI assistant:")
if client_choice in ["1", "3"]:
print(" - Claude Code: claude")
if client_choice in ["2", "3"]:
print(" - Codex: codex")
print()
print(" 2. Check MCP connection: /mcp")
print(" 3. Test: Use telegram_notify to send a message")
print()
print(" In Telegram:")
print(" - Send: /help")
print(" - Try: 'Enter unattended mode. Task: analyze project'")
print()
print("Documentation: https://github.com/batianVolyc/telegram-mcp-server")
def show_config():
"""Show current configuration"""
config_path = get_claude_config_path()
if not config_path.exists():
print("â No configuration found")
print(f"Expected location: {config_path}")
print()
print("Run: telegram-mcp-server --setup")
return
with open(config_path, 'r') as f:
config = json.load(f)
if "telegram" not in config.get("mcpServers", {}):
print("â Telegram MCP Server not configured")
print()
print("Run: telegram-mcp-server --setup")
return
telegram_config = config["mcpServers"]["telegram"]
print("đ Current Configuration")
print("=" * 50)
print(f"Config file: {config_path}")
print()
print(f"Command: {telegram_config.get('command')}")
print(f"Args: {telegram_config.get('args')}")
print()
env = telegram_config.get("env", {})
bot_token = env.get("TELEGRAM_BOT_TOKEN", "")
chat_id = env.get("TELEGRAM_CHAT_ID", "")
if bot_token:
print(f"Bot Token: {bot_token[:10]}...{bot_token[-5:]}")
else:
print("Bot Token: â Not set")
if chat_id:
print(f"Chat ID: {chat_id}")
else:
print("Chat ID: â Not set")
print()
print("=" * 50)
def main():
"""Main CLI entry point"""
if len(sys.argv) > 1:
arg = sys.argv[1]
if arg in ["--setup", "-s", "setup"]:
asyncio.run(interactive_setup())
elif arg in ["--config", "-c", "config"]:
show_config()
elif arg in ["--help", "-h", "help"]:
print("Telegram MCP Server - CLI")
print()
print("Usage:")
print(" telegram-mcp-server Run MCP server")
print(" telegram-mcp-server --setup Interactive setup wizard")
print(" telegram-mcp-server --config Show current configuration")
print(" telegram-mcp-server --help Show this help")
print()
print("Documentation: https://github.com/batianVolyc/telegram-mcp-server")
else:
print(f"Unknown option: {arg}")
print("Run: telegram-mcp-server --help")
sys.exit(1)
else:
# Run MCP server
from . import __main__
asyncio.run(__main__.main())
if __name__ == "__main__":
main()