|
1 | 1 | """Media MCP tools.""" |
2 | 2 |
|
| 3 | +from mcp.server.fastmcp import Audio, Image |
| 4 | + |
3 | 5 | from telegram_mcp.runtime import * |
4 | 6 |
|
5 | 7 |
|
| 8 | +MAX_INLINE_MEDIA_BYTES = 20 * 1024 * 1024 |
| 9 | + |
| 10 | + |
| 11 | +@mcp.tool(annotations=ToolAnnotations(title="Get Media", openWorldHint=True, readOnlyHint=True)) |
| 12 | +@with_account(readonly=True) |
| 13 | +@validate_id("chat_id") |
| 14 | +async def get_media( |
| 15 | + chat_id: Union[int, str], message_id: int, account: str = None |
| 16 | +) -> Any: |
| 17 | + """Return a Telegram image or audio attachment as native MCP media content.""" |
| 18 | + try: |
| 19 | + cl = get_client(account) |
| 20 | + entity = await resolve_entity(chat_id, cl) |
| 21 | + msg = await cl.get_messages(entity, ids=message_id) |
| 22 | + if not msg or not msg.media: |
| 23 | + return "No media found in the specified message." |
| 24 | + |
| 25 | + mime = getattr(getattr(msg, "file", None), "mime_type", None) |
| 26 | + if not mime and getattr(msg, "photo", None) is not None: |
| 27 | + mime = "image/jpeg" |
| 28 | + if not mime or not (mime.startswith("image/") or mime.startswith("audio/")): |
| 29 | + return "Native MCP media is available for images and audio only." |
| 30 | + |
| 31 | + data = await cl.download_media(msg, bytes) |
| 32 | + if not data: |
| 33 | + return f"Download failed for message {message_id}." |
| 34 | + if len(data) > MAX_INLINE_MEDIA_BYTES: |
| 35 | + return f"Media is too large for inline MCP delivery ({len(data)} bytes)." |
| 36 | + |
| 37 | + media_type, media_format = mime.split("/", 1) |
| 38 | + if media_type == "image": |
| 39 | + return Image(data=data, format=media_format) |
| 40 | + return Audio(data=data, format=media_format) |
| 41 | + except Exception as e: |
| 42 | + return log_and_format_error("get_media", e, chat_id=chat_id, message_id=message_id) |
| 43 | + |
| 44 | + |
6 | 45 | @mcp.tool(annotations=ToolAnnotations(title="Send File", openWorldHint=True, destructiveHint=True)) |
7 | 46 | @with_account(readonly=False) |
8 | 47 | @validate_id("chat_id") |
|
0 commit comments