notebookvb
This commit is contained in:
+127
@@ -0,0 +1,127 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
MCP server pro Telegram — FastMCP
|
||||
Spustit: python mcp_telegram.py
|
||||
|
||||
Dává agentům nástroje pro komunikaci s Vladem přes Telegram.
|
||||
|
||||
Nástroje:
|
||||
notifikace — pošle Vladovi zprávu přes bota (oznámení, nečeká na odpověď)
|
||||
zeptej_se — pošle Vladovi otázku přes bota a POČKÁ na jeho odpověď
|
||||
posli_jako_agent — pošle Vladovi zprávu z účtu agenta "Claude Buzalka" (persona)
|
||||
zeptej_se_jako_agent — otázka z účtu agenta + čekání na odpověď
|
||||
|
||||
Dvě cesty:
|
||||
• BOT (@Vlado_Claude_Bot) — bezpečné, bez rizika banu; doporučené pro notifikace/dotazy.
|
||||
• USER účet (Claude Buzalka) — vystupuje jako "osoba"; má riziko banu (nový účet).
|
||||
|
||||
POZOR (bot): getUpdates smí pollovat jen JEDEN proces. Když běží víc agentů, kteří
|
||||
naráz čekají na odpověď přes bota, kradou si zprávy. Pro souběžné dotazy víc agentů
|
||||
použij user účet (každý agent vlastní session) — viz Knihovny/telegram_user.py.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
||||
# Kořen projektu na sys.path, ať jdou importovat sdílené knihovny
|
||||
BASE_DIR = Path(__file__).resolve().parent
|
||||
sys.path.insert(0, str(BASE_DIR))
|
||||
|
||||
from Knihovny.telegram_notify import posli_telegram, zeptej_se_telegram
|
||||
from Knihovny.telegram_user import posli_jako_ja, zeptej_se_jako
|
||||
|
||||
|
||||
def log(msg: str):
|
||||
print(msg, file=sys.stderr, flush=True)
|
||||
|
||||
|
||||
def _v_threadu(fn, *args, **kwargs):
|
||||
"""Spustí synchronní (telethon.sync) funkci ve vlastním vlákně s čistou
|
||||
event-loop, aby nekolidovala s běžící async smyčkou FastMCP."""
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
try:
|
||||
return fn(*args, **kwargs)
|
||||
finally:
|
||||
loop.close()
|
||||
asyncio.set_event_loop(None)
|
||||
|
||||
|
||||
# Vladův hlavní Telegram účet (user id == chat_id u bota)
|
||||
VLADO_UID = 6639316354
|
||||
|
||||
mcp = FastMCP("telegram")
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# BOT — bezpečná cesta
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
@mcp.tool()
|
||||
def notifikace(text: str, tise: bool = False) -> dict:
|
||||
"""Pošle Vladovi oznámení přes Telegram bota (nečeká na odpověď).
|
||||
|
||||
Použij pro informování o průběhu, dokončení úlohy, chybě apod.
|
||||
|
||||
:param text: text zprávy
|
||||
:param tise: True = tichá zpráva bez zvuku/upozornění
|
||||
:return: {"ok": True}
|
||||
"""
|
||||
posli_telegram(text, disable_notification=tise)
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def zeptej_se(otazka: str, timeout_s: int = 180) -> dict:
|
||||
"""Pošle Vladovi otázku přes bota a POČKÁ na jeho textovou odpověď.
|
||||
|
||||
Vhodné, když agent během běhu potřebuje rozhodnutí. Blokuje až `timeout_s` sekund.
|
||||
|
||||
:param otazka: text otázky (klidně s nabídkou možností, např. "(ano/ne)")
|
||||
:param timeout_s: jak dlouho čekat na odpověď
|
||||
:return: {"odpoved": <text>} nebo {"odpoved": None, "timeout": True}
|
||||
"""
|
||||
odp = zeptej_se_telegram(otazka, timeout=timeout_s)
|
||||
if odp is None:
|
||||
return {"odpoved": None, "timeout": True}
|
||||
return {"odpoved": odp}
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# USER účet "Claude Buzalka" — persona (riziko banu)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
@mcp.tool()
|
||||
async def posli_jako_agent(text: str) -> dict:
|
||||
"""Pošle Vladovi zprávu z účtu agenta "Claude Buzalka" (ne z bota).
|
||||
|
||||
:param text: text zprávy
|
||||
:return: {"ok": True}
|
||||
"""
|
||||
await asyncio.to_thread(_v_threadu, posli_jako_ja, VLADO_UID, text)
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def zeptej_se_jako_agent(otazka: str, agent: str = "Claude", timeout_s: int = 180) -> dict:
|
||||
"""Pošle Vladovi otázku z účtu agenta a POČKÁ na odpověď (stačí běžná zpráva).
|
||||
|
||||
:param otazka: text otázky
|
||||
:param agent: jméno agenta (štítek + session); výchozí "Claude"
|
||||
:param timeout_s: jak dlouho čekat
|
||||
:return: {"odpoved": <text>} nebo {"odpoved": None, "timeout": True}
|
||||
"""
|
||||
odp = await asyncio.to_thread(
|
||||
_v_threadu, zeptej_se_jako, agent, otazka,
|
||||
komu=VLADO_UID, session=None, timeout=timeout_s, vyzaduj_reply=False,
|
||||
)
|
||||
if odp is None:
|
||||
return {"odpoved": None, "timeout": True}
|
||||
return {"odpoved": odp}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
log("MCP Telegram server spuštěn (FastMCP)")
|
||||
mcp.run()
|
||||
Reference in New Issue
Block a user