Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Telegram MCP Package
42 changes: 23 additions & 19 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3129,25 +3129,29 @@ async def create_poll(
)


if __name__ == "__main__":
nest_asyncio.apply()
async def _main() -> None:
try:
# Start the Telethon client non-interactively
print("Starting Telegram client...")
await client.start()

async def main() -> None:
try:
# Start the Telethon client non-interactively
print("Starting Telegram client...")
await client.start()
print("Telegram client started. Running MCP server...")
# Use the asynchronous entrypoint instead of mcp.run()
await mcp.run_stdio_async()
except Exception as e:
print(f"Error starting client: {e}", file=sys.stderr)
if isinstance(e, sqlite3.OperationalError) and "database is locked" in str(e):
print(
"Database lock detected. Please ensure no other instances are running.",
file=sys.stderr,
)
sys.exit(1)


def main() -> None:
nest_asyncio.apply()
asyncio.run(_main())

print("Telegram client started. Running MCP server...")
# Use the asynchronous entrypoint instead of mcp.run()
await mcp.run_stdio_async()
except Exception as e:
print(f"Error starting client: {e}", file=sys.stderr)
if isinstance(e, sqlite3.OperationalError) and "database is locked" in str(e):
print(
"Database lock detected. Please ensure no other instances are running.",
file=sys.stderr,
)
sys.exit(1)

asyncio.run(main())
if __name__ == "__main__":
main()
10 changes: 8 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
[build-system]
requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta"
package-mode = false

[project]
name = "telegram-mcp"
Expand All @@ -26,7 +25,7 @@ requires-python = ">=3.10"
dependencies = [
"dotenv>=0.9.9",
"httpx>=0.28.1",
"mcp[cli]>=1.4.1",
"mcp[cli]>=1.8.0",
"nest-asyncio>=1.6.0",
"python-dotenv>=1.1.0",
"python-json-logger>=3.3.0",
Expand All @@ -37,6 +36,13 @@ dependencies = [
"Homepage" = "https://github.com/chigwell/telegram-mcp"
"Bug Tracker" = "https://github.com/chigwell/telegram-mcp/issues"

[tool.setuptools]
py-modules = ["main", "session_string_generator"]

[project.scripts]
telegram-mcp = "main:main"
telegram-mcp-generate-session = "session_string_generator:main"

[tool.black]
line-length = 99
target-version = ['py311']
Expand Down
150 changes: 78 additions & 72 deletions session_string_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,75 +28,81 @@
# Load environment variables from .env file
load_dotenv()

API_ID = os.getenv("TELEGRAM_API_ID")
API_HASH = os.getenv("TELEGRAM_API_HASH")

if not API_ID or not API_HASH:
print("Error: TELEGRAM_API_ID and TELEGRAM_API_HASH must be set in .env file")
print("Create an .env file with your credentials from https://my.telegram.org/apps")
sys.exit(1)

# Convert API_ID to integer
try:
API_ID = int(API_ID)
except ValueError:
print("Error: TELEGRAM_API_ID must be an integer")
sys.exit(1)

print("\n----- Telegram Session String Generator -----\n")
print("This script will generate a session string for your Telegram account.")
print(
"You will be asked to enter your phone number and the verification code sent to your Telegram app."
)
print("The generated session string can be added to your .env file.")
print(
"\nYour credentials will NOT be stored on any server and are only used for local authentication.\n"
)

try:
# Connect to Telegram and generate the session string
with TelegramClient(StringSession(), API_ID, API_HASH) as client:
# The client.session.save() function from StringSession returns the session string
session_string = StringSession.save(client.session)

print("\nAuthentication successful!")
print("\n----- Your Session String -----")
print(f"\n{session_string}\n")
print("Add this to your .env file as:")
print(f"TELEGRAM_SESSION_STRING={session_string}")
print("\nIMPORTANT: Keep this string private and never share it with anyone!")

# Optional: auto-update the .env file
choice = input(
"\nWould you like to automatically update your .env file with this session string? (y/N): "
)
if choice.lower() == "y":
try:
# Read the current .env file
with open(".env", "r") as file:
env_contents = file.readlines()

# Update or add the SESSION_STRING line
session_string_line_found = False
for i, line in enumerate(env_contents):
if line.startswith("TELEGRAM_SESSION_STRING="):
env_contents[i] = f"TELEGRAM_SESSION_STRING={session_string}\n"
session_string_line_found = True
break

if not session_string_line_found:
env_contents.append(f"TELEGRAM_SESSION_STRING={session_string}\n")

# Write back to the .env file
with open(".env", "w") as file:
file.writelines(env_contents)

print("\n.env file updated successfully!")
except Exception as e:
print(f"\nError updating .env file: {e}")
print("Please manually add the session string to your .env file.")

except Exception as e:
print(f"\nError: {e}")
print("Failed to generate session string. Please try again.")
sys.exit(1)

def main() -> None:
API_ID = os.getenv("TELEGRAM_API_ID")
API_HASH = os.getenv("TELEGRAM_API_HASH")

if not API_ID or not API_HASH:
print("Error: TELEGRAM_API_ID and TELEGRAM_API_HASH must be set in .env file")
print("Create an .env file with your credentials from https://my.telegram.org/apps")
sys.exit(1)

# Convert API_ID to integer
try:
API_ID = int(API_ID)
except ValueError:
print("Error: TELEGRAM_API_ID must be an integer")
sys.exit(1)

print("\n----- Telegram Session String Generator -----\n")
print("This script will generate a session string for your Telegram account.")
print(
"You will be asked to enter your phone number and the verification code sent to your Telegram app."
)
print("The generated session string can be added to your .env file.")
print(
"\nYour credentials will NOT be stored on any server and are only used for local authentication.\n"
)

try:
# Connect to Telegram and generate the session string
with TelegramClient(StringSession(), API_ID, API_HASH) as client:
# The client.session.save() function from StringSession returns the session string
session_string = StringSession.save(client.session)

print("\nAuthentication successful!")
print("\n----- Your Session String -----")
print(f"\n{session_string}\n")
print("Add this to your .env file as:")
print(f"TELEGRAM_SESSION_STRING={session_string}")
print("\nIMPORTANT: Keep this string private and never share it with anyone!")

# Optional: auto-update the .env file
choice = input(
"\nWould you like to automatically update your .env file with this session string? (y/N): "
)
if choice.lower() == "y":
try:
# Read the current .env file
with open(".env", "r") as file:
env_contents = file.readlines()

# Update or add the SESSION_STRING line
session_string_line_found = False
for i, line in enumerate(env_contents):
if line.startswith("TELEGRAM_SESSION_STRING="):
env_contents[i] = f"TELEGRAM_SESSION_STRING={session_string}\n"
session_string_line_found = True
break

if not session_string_line_found:
env_contents.append(f"TELEGRAM_SESSION_STRING={session_string}\n")

# Write back to the .env file
with open(".env", "w") as file:
file.writelines(env_contents)

print("\n.env file updated successfully!")
except Exception as e:
print(f"\nError updating .env file: {e}")
print("Please manually add the session string to your .env file.")

except Exception as e:
print(f"\nError: {e}")
print("Failed to generate session string. Please try again.")
sys.exit(1)


if __name__ == "__main__":
main()
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.