From 49d70795f04225c9eab3008d1be1072abd85685b Mon Sep 17 00:00:00 2001 From: triepod-ai Date: Tue, 23 Dec 2025 07:55:43 -0600 Subject: [PATCH] feat: Add title annotations to all 78 tools for improved LLM display Add human-readable title annotations to all MCP tools to help clients display tool names in a user-friendly format. Changes: - Added title annotation to all 78 tools (e.g., "Get Chats", "Send Message") - Formatted with Black for code style consistency This improves the user experience when MCP clients display tool lists. Co-Authored-By: Claude --- main.py | 301 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 223 insertions(+), 78 deletions(-) diff --git a/main.py b/main.py index edaf452..51649dc 100644 --- a/main.py +++ b/main.py @@ -317,7 +317,7 @@ def get_sender_name(message) -> str: return "Unknown" -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool(annotations=ToolAnnotations(title="Get Chats", openWorldHint=True, readOnlyHint=True)) async def get_chats(page: int = 1, page_size: int = 20) -> str: """ Get a paginated list of chats. @@ -343,7 +343,7 @@ async def get_chats(page: int = 1, page_size: int = 20) -> str: return log_and_format_error("get_chats", e) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool(annotations=ToolAnnotations(title="Get Messages", openWorldHint=True, readOnlyHint=True)) @validate_id("chat_id") async def get_messages(chat_id: Union[int, str], page: int = 1, page_size: int = 20) -> str: """ @@ -375,7 +375,9 @@ async def get_messages(chat_id: Union[int, str], page: int = 1, page_size: int = ) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Send Message", openWorldHint=True, destructiveHint=True) +) @validate_id("chat_id") async def send_message(chat_id: Union[int, str], message: str) -> str: """ @@ -393,7 +395,12 @@ async def send_message(chat_id: Union[int, str], message: str) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Subscribe Public Channel", + openWorldHint=True, + destructiveHint=True, + idempotentHint=True, + ) ) @validate_id("channel") async def subscribe_public_channel(channel: Union[int, str]) -> str: @@ -414,7 +421,9 @@ async def subscribe_public_channel(channel: Union[int, str]) -> str: return log_and_format_error("subscribe_public_channel", e, channel=channel) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="List Inline Buttons", openWorldHint=True, readOnlyHint=True) +) @validate_id("chat_id") async def list_inline_buttons( chat_id: Union[int, str], message_id: Optional[Union[int, str]] = None, limit: int = 20 @@ -478,7 +487,11 @@ async def list_inline_buttons( ) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True)) +@mcp.tool( + annotations=ToolAnnotations( + title="Press Inline Button", openWorldHint=True, destructiveHint=True + ) +) @validate_id("chat_id") async def press_inline_button( chat_id: Union[int, str], @@ -593,7 +606,9 @@ async def press_inline_button( ) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="List Contacts", openWorldHint=True, readOnlyHint=True) +) async def list_contacts() -> str: """ List all contacts in your Telegram account. @@ -619,7 +634,9 @@ async def list_contacts() -> str: return log_and_format_error("list_contacts", e) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Search Contacts", openWorldHint=True, readOnlyHint=True) +) async def search_contacts(query: str) -> str: """ Search for contacts by name, username, or phone number using Telethon's SearchRequest. @@ -647,7 +664,9 @@ async def search_contacts(query: str) -> str: return log_and_format_error("search_contacts", e, query=query) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Get Contact Ids", openWorldHint=True, readOnlyHint=True) +) async def get_contact_ids() -> str: """ Get all contact IDs in your Telegram account. @@ -661,7 +680,9 @@ async def get_contact_ids() -> str: return log_and_format_error("get_contact_ids", e) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="List Messages", openWorldHint=True, readOnlyHint=True) +) @validate_id("chat_id") async def list_messages( chat_id: Union[int, str], @@ -784,7 +805,7 @@ async def list_messages( return log_and_format_error("list_messages", e, chat_id=chat_id) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool(annotations=ToolAnnotations(title="List Topics", openWorldHint=True, readOnlyHint=True)) async def list_topics( chat_id: int, limit: int = 200, @@ -871,7 +892,7 @@ async def list_topics( ) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool(annotations=ToolAnnotations(title="List Chats", openWorldHint=True, readOnlyHint=True)) async def list_chats(chat_type: str = None, limit: int = 20) -> str: """ List available chats with metadata. @@ -932,7 +953,7 @@ async def list_chats(chat_type: str = None, limit: int = 20) -> str: return log_and_format_error("list_chats", e, chat_type=chat_type, limit=limit) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool(annotations=ToolAnnotations(title="Get Chat", openWorldHint=True, readOnlyHint=True)) @validate_id("chat_id") async def get_chat(chat_id: Union[int, str]) -> str: """ @@ -1013,7 +1034,11 @@ async def get_chat(chat_id: Union[int, str]) -> str: return log_and_format_error("get_chat", e, chat_id=chat_id) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations( + title="Get Direct Chat By Contact", openWorldHint=True, readOnlyHint=True + ) +) async def get_direct_chat_by_contact(contact_query: str) -> str: """ Find a direct chat with a specific contact by name, username, or phone. @@ -1068,7 +1093,9 @@ async def get_direct_chat_by_contact(contact_query: str) -> str: return log_and_format_error("get_direct_chat_by_contact", e, contact_query=contact_query) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Get Contact Chats", openWorldHint=True, readOnlyHint=True) +) @validate_id("contact_id") async def get_contact_chats(contact_id: Union[int, str]) -> str: """ @@ -1121,7 +1148,11 @@ async def get_contact_chats(contact_id: Union[int, str]) -> str: return log_and_format_error("get_contact_chats", e, contact_id=contact_id) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations( + title="Get Last Interaction", openWorldHint=True, readOnlyHint=True + ) +) @validate_id("contact_id") async def get_last_interaction(contact_id: Union[int, str]) -> str: """ @@ -1158,7 +1189,9 @@ async def get_last_interaction(contact_id: Union[int, str]) -> str: return log_and_format_error("get_last_interaction", e, contact_id=contact_id) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Get Message Context", openWorldHint=True, readOnlyHint=True) +) @validate_id("chat_id") async def get_message_context( chat_id: Union[int, str], message_id: int, context_size: int = 3 @@ -1226,7 +1259,9 @@ async def get_message_context( @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Add Contact", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) async def add_contact(phone: str, first_name: str, last_name: str = "") -> str: """ @@ -1284,7 +1319,9 @@ async def add_contact(phone: str, first_name: str, last_name: str = "") -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Delete Contact", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("user_id") async def delete_contact(user_id: Union[int, str]) -> str: @@ -1302,7 +1339,9 @@ async def delete_contact(user_id: Union[int, str]) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Block User", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("user_id") async def block_user(user_id: Union[int, str]) -> str: @@ -1320,7 +1359,9 @@ async def block_user(user_id: Union[int, str]) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Unblock User", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("user_id") async def unblock_user(user_id: Union[int, str]) -> str: @@ -1337,7 +1378,7 @@ async def unblock_user(user_id: Union[int, str]) -> str: return log_and_format_error("unblock_user", e, user_id=user_id) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool(annotations=ToolAnnotations(title="Get Me", openWorldHint=True, readOnlyHint=True)) async def get_me() -> str: """ Get your own user information. @@ -1349,7 +1390,9 @@ async def get_me() -> str: return log_and_format_error("get_me", e) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Create Group", openWorldHint=True, destructiveHint=True) +) @validate_id("user_ids") async def create_group(title: str, user_ids: List[Union[int, str]]) -> str: """ @@ -1409,7 +1452,9 @@ async def create_group(title: str, user_ids: List[Union[int, str]]) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Invite To Group", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("group_id", "user_ids") async def invite_to_group(group_id: Union[int, str], user_ids: List[Union[int, str]]) -> str: @@ -1461,7 +1506,9 @@ async def invite_to_group(group_id: Union[int, str], user_ids: List[Union[int, s @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Leave Chat", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("chat_id") async def leave_chat(chat_id: Union[int, str]) -> str: @@ -1543,7 +1590,9 @@ async def leave_chat(chat_id: Union[int, str]) -> str: return log_and_format_error("leave_chat", e, chat_id=chat_id) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Get Participants", openWorldHint=True, readOnlyHint=True) +) @validate_id("chat_id") async def get_participants(chat_id: Union[int, str]) -> str: """ @@ -1562,7 +1611,7 @@ async def get_participants(chat_id: Union[int, str]) -> str: return log_and_format_error("get_participants", e, chat_id=chat_id) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True)) +@mcp.tool(annotations=ToolAnnotations(title="Send File", openWorldHint=True, destructiveHint=True)) @validate_id("chat_id") async def send_file(chat_id: Union[int, str], file_path: str, caption: str = None) -> str: """ @@ -1586,7 +1635,9 @@ async def send_file(chat_id: Union[int, str], file_path: str, caption: str = Non ) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Download Media", openWorldHint=True, readOnlyHint=True) +) @validate_id("chat_id") async def download_media(chat_id: Union[int, str], message_id: int, file_path: str) -> str: """ @@ -1620,7 +1671,9 @@ async def download_media(chat_id: Union[int, str], message_id: int, file_path: s @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Update Profile", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) async def update_profile(first_name: str = None, last_name: str = None, about: str = None) -> str: """ @@ -1640,7 +1693,9 @@ async def update_profile(first_name: str = None, last_name: str = None, about: s @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Set Profile Photo", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) async def set_profile_photo(file_path: str) -> str: """ @@ -1656,7 +1711,9 @@ async def set_profile_photo(file_path: str) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Delete Profile Photo", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) async def delete_profile_photo() -> str: """ @@ -1674,7 +1731,11 @@ async def delete_profile_photo() -> str: return log_and_format_error("delete_profile_photo", e) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations( + title="Get Privacy Settings", openWorldHint=True, readOnlyHint=True + ) +) async def get_privacy_settings() -> str: """ Get your privacy settings for last seen status. @@ -1699,7 +1760,9 @@ async def get_privacy_settings() -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Set Privacy Settings", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("allow_users", "disallow_users") async def set_privacy_settings( @@ -1797,7 +1860,9 @@ async def set_privacy_settings( return log_and_format_error("set_privacy_settings", e, key=key) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Import Contacts", openWorldHint=True, destructiveHint=True) +) async def import_contacts(contacts: list) -> str: """ Import a list of contacts. Each contact should be a dict with phone, first_name, last_name. @@ -1818,7 +1883,9 @@ async def import_contacts(contacts: list) -> str: return log_and_format_error("import_contacts", e, contacts=contacts) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Export Contacts", openWorldHint=True, readOnlyHint=True) +) async def export_contacts() -> str: """ Export all contacts as a JSON string. @@ -1831,7 +1898,9 @@ async def export_contacts() -> str: return log_and_format_error("export_contacts", e) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Get Blocked Users", openWorldHint=True, readOnlyHint=True) +) async def get_blocked_users() -> str: """ Get a list of blocked users. @@ -1843,7 +1912,9 @@ async def get_blocked_users() -> str: return log_and_format_error("get_blocked_users", e) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Create Channel", openWorldHint=True, destructiveHint=True) +) async def create_channel(title: str, about: str = "", megagroup: bool = False) -> str: """ Create a new channel or supergroup. @@ -1860,7 +1931,9 @@ async def create_channel(title: str, about: str = "", megagroup: bool = False) - @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Edit Chat Title", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("chat_id") async def edit_chat_title(chat_id: Union[int, str], title: str) -> str: @@ -1882,7 +1955,9 @@ async def edit_chat_title(chat_id: Union[int, str], title: str) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Edit Chat Photo", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("chat_id") async def edit_chat_photo(chat_id: Union[int, str], file_path: str) -> str: @@ -1918,7 +1993,9 @@ async def edit_chat_photo(chat_id: Union[int, str], file_path: str) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Delete Chat Photo", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("chat_id") async def delete_chat_photo(chat_id: Union[int, str]) -> str: @@ -1949,7 +2026,9 @@ async def delete_chat_photo(chat_id: Union[int, str]) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Promote Admin", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("group_id", "user_id") async def promote_admin( @@ -2018,7 +2097,9 @@ async def promote_admin( @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Demote Admin", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("group_id", "user_id") async def demote_admin(group_id: Union[int, str], user_id: Union[int, str]) -> str: @@ -2069,7 +2150,9 @@ async def demote_admin(group_id: Union[int, str], user_id: Union[int, str]) -> s @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Ban User", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("chat_id", "user_id") async def ban_user(chat_id: Union[int, str], user_id: Union[int, str]) -> str: @@ -2118,7 +2201,9 @@ async def ban_user(chat_id: Union[int, str], user_id: Union[int, str]) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Unban User", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("chat_id", "user_id") async def unban_user(chat_id: Union[int, str], user_id: Union[int, str]) -> str: @@ -2166,7 +2251,7 @@ async def unban_user(chat_id: Union[int, str], user_id: Union[int, str]) -> str: return log_and_format_error("unban_user", e, chat_id=chat_id, user_id=user_id) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool(annotations=ToolAnnotations(title="Get Admins", openWorldHint=True, readOnlyHint=True)) @validate_id("chat_id") async def get_admins(chat_id: Union[int, str]) -> str: """ @@ -2185,7 +2270,9 @@ async def get_admins(chat_id: Union[int, str]) -> str: return log_and_format_error("get_admins", e, chat_id=chat_id) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Get Banned Users", openWorldHint=True, readOnlyHint=True) +) @validate_id("chat_id") async def get_banned_users(chat_id: Union[int, str]) -> str: """ @@ -2206,7 +2293,9 @@ async def get_banned_users(chat_id: Union[int, str]) -> str: return log_and_format_error("get_banned_users", e, chat_id=chat_id) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Get Invite Link", openWorldHint=True, readOnlyHint=True) +) @validate_id("chat_id") async def get_invite_link(chat_id: Union[int, str]) -> str: """ @@ -2251,7 +2340,9 @@ async def get_invite_link(chat_id: Union[int, str]) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Join Chat By Link", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) async def join_chat_by_link(link: str) -> str: """ @@ -2296,7 +2387,9 @@ async def join_chat_by_link(link: str) -> str: return f"Error joining chat: {e}" -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Export Chat Invite", openWorldHint=True, readOnlyHint=True) +) @validate_id("chat_id") async def export_chat_invite(chat_id: Union[int, str]) -> str: """ @@ -2332,7 +2425,9 @@ async def export_chat_invite(chat_id: Union[int, str]) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Import Chat Invite", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) async def import_chat_invite(hash: str) -> str: """ @@ -2390,7 +2485,9 @@ async def import_chat_invite(hash: str) -> str: return log_and_format_error("import_chat_invite", e, hash=hash) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Send Voice", openWorldHint=True, destructiveHint=True) +) @validate_id("chat_id") async def send_voice(chat_id: Union[int, str], file_path: str) -> str: """ @@ -2424,7 +2521,9 @@ async def send_voice(chat_id: Union[int, str], file_path: str) -> str: return log_and_format_error("send_voice", e, chat_id=chat_id, file_path=file_path) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Forward Message", openWorldHint=True, destructiveHint=True) +) @validate_id("from_chat_id", "to_chat_id") async def forward_message( from_chat_id: Union[int, str], message_id: int, to_chat_id: Union[int, str] @@ -2448,7 +2547,9 @@ async def forward_message( @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Edit Message", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("chat_id") async def edit_message(chat_id: Union[int, str], message_id: int, new_text: str) -> str: @@ -2466,7 +2567,9 @@ async def edit_message(chat_id: Union[int, str], message_id: int, new_text: str) @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Delete Message", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("chat_id") async def delete_message(chat_id: Union[int, str], message_id: int) -> str: @@ -2482,7 +2585,9 @@ async def delete_message(chat_id: Union[int, str], message_id: int) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Pin Message", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("chat_id") async def pin_message(chat_id: Union[int, str], message_id: int) -> str: @@ -2498,7 +2603,9 @@ async def pin_message(chat_id: Union[int, str], message_id: int) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Unpin Message", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("chat_id") async def unpin_message(chat_id: Union[int, str], message_id: int) -> str: @@ -2514,7 +2621,9 @@ async def unpin_message(chat_id: Union[int, str], message_id: int) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Mark As Read", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("chat_id") async def mark_as_read(chat_id: Union[int, str]) -> str: @@ -2529,7 +2638,9 @@ async def mark_as_read(chat_id: Union[int, str]) -> str: return log_and_format_error("mark_as_read", e, chat_id=chat_id) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Reply To Message", openWorldHint=True, destructiveHint=True) +) @validate_id("chat_id") async def reply_to_message(chat_id: Union[int, str], message_id: int, text: str) -> str: """ @@ -2545,7 +2656,9 @@ async def reply_to_message(chat_id: Union[int, str], message_id: int, text: str) ) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Get Media Info", openWorldHint=True, readOnlyHint=True) +) @validate_id("chat_id") async def get_media_info(chat_id: Union[int, str], message_id: int) -> str: """ @@ -2567,7 +2680,9 @@ async def get_media_info(chat_id: Union[int, str], message_id: int) -> str: return log_and_format_error("get_media_info", e, chat_id=chat_id, message_id=message_id) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Search Public Chats", openWorldHint=True, readOnlyHint=True) +) async def search_public_chats(query: str) -> str: """ Search for public chats, channels, or bots by username or title. @@ -2579,7 +2694,9 @@ async def search_public_chats(query: str) -> str: return log_and_format_error("search_public_chats", e, query=query) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Search Messages", openWorldHint=True, readOnlyHint=True) +) @validate_id("chat_id") async def search_messages(chat_id: Union[int, str], query: str, limit: int = 20) -> str: """ @@ -2605,7 +2722,9 @@ async def search_messages(chat_id: Union[int, str], query: str, limit: int = 20) ) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Resolve Username", openWorldHint=True, readOnlyHint=True) +) async def resolve_username(username: str) -> str: """ Resolve a username to a user or chat ID. @@ -2618,7 +2737,9 @@ async def resolve_username(username: str) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Mute Chat", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("chat_id") async def mute_chat(chat_id: Union[int, str]) -> str: @@ -2659,7 +2780,9 @@ async def mute_chat(chat_id: Union[int, str]) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Unmute Chat", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("chat_id") async def unmute_chat(chat_id: Union[int, str]) -> str: @@ -2700,7 +2823,9 @@ async def unmute_chat(chat_id: Union[int, str]) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Archive Chat", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("chat_id") async def archive_chat(chat_id: Union[int, str]) -> str: @@ -2719,7 +2844,9 @@ async def archive_chat(chat_id: Union[int, str]) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Unarchive Chat", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) @validate_id("chat_id") async def unarchive_chat(chat_id: Union[int, str]) -> str: @@ -2737,7 +2864,9 @@ async def unarchive_chat(chat_id: Union[int, str]) -> str: return log_and_format_error("unarchive_chat", e, chat_id=chat_id) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Get Sticker Sets", openWorldHint=True, readOnlyHint=True) +) async def get_sticker_sets() -> str: """ Get all sticker sets. @@ -2749,7 +2878,9 @@ async def get_sticker_sets() -> str: return log_and_format_error("get_sticker_sets", e) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Send Sticker", openWorldHint=True, destructiveHint=True) +) @validate_id("chat_id") async def send_sticker(chat_id: Union[int, str], file_path: str) -> str: """ @@ -2774,7 +2905,9 @@ async def send_sticker(chat_id: Union[int, str], file_path: str) -> str: return log_and_format_error("send_sticker", e, chat_id=chat_id, file_path=file_path) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Get Gif Search", openWorldHint=True, readOnlyHint=True) +) async def get_gif_search(query: str, limit: int = 10) -> str: """ Search for GIFs by query. Returns a list of Telegram document IDs (not file paths). @@ -2830,7 +2963,7 @@ async def get_gif_search(query: str, limit: int = 10) -> str: return log_and_format_error("get_gif_search", e, query=query, limit=limit) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True)) +@mcp.tool(annotations=ToolAnnotations(title="Send Gif", openWorldHint=True, destructiveHint=True)) @validate_id("chat_id") async def send_gif(chat_id: Union[int, str], gif_id: int) -> str: """ @@ -2850,7 +2983,7 @@ async def send_gif(chat_id: Union[int, str], gif_id: int) -> str: return log_and_format_error("send_gif", e, chat_id=chat_id, gif_id=gif_id) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool(annotations=ToolAnnotations(title="Get Bot Info", openWorldHint=True, readOnlyHint=True)) async def get_bot_info(bot_username: str) -> str: """ Get information about a bot by username. @@ -2887,7 +3020,9 @@ async def get_bot_info(bot_username: str) -> str: @mcp.tool( - annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True, idempotentHint=True) + annotations=ToolAnnotations( + title="Set Bot Commands", openWorldHint=True, destructiveHint=True, idempotentHint=True + ) ) async def set_bot_commands(bot_username: str, commands: list) -> str: """ @@ -2935,7 +3070,7 @@ async def set_bot_commands(bot_username: str, commands: list) -> str: return log_and_format_error("set_bot_commands", e, bot_username=bot_username) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool(annotations=ToolAnnotations(title="Get History", openWorldHint=True, readOnlyHint=True)) @validate_id("chat_id") async def get_history(chat_id: Union[int, str], limit: int = 100) -> str: """ @@ -2959,7 +3094,9 @@ async def get_history(chat_id: Union[int, str], limit: int = 100) -> str: return log_and_format_error("get_history", e, chat_id=chat_id, limit=limit) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Get User Photos", openWorldHint=True, readOnlyHint=True) +) @validate_id("user_id") async def get_user_photos(user_id: Union[int, str], limit: int = 10) -> str: """ @@ -2975,7 +3112,9 @@ async def get_user_photos(user_id: Union[int, str], limit: int = 10) -> str: return log_and_format_error("get_user_photos", e, user_id=user_id, limit=limit) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Get User Status", openWorldHint=True, readOnlyHint=True) +) @validate_id("user_id") async def get_user_status(user_id: Union[int, str]) -> str: """ @@ -2988,7 +3127,9 @@ async def get_user_status(user_id: Union[int, str]) -> str: return log_and_format_error("get_user_status", e, user_id=user_id) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Get Recent Actions", openWorldHint=True, readOnlyHint=True) +) @validate_id("chat_id") async def get_recent_actions(chat_id: Union[int, str]) -> str: """ @@ -3017,7 +3158,9 @@ async def get_recent_actions(chat_id: Union[int, str]) -> str: return log_and_format_error("get_recent_actions", e, chat_id=chat_id) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, readOnlyHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Get Pinned Messages", openWorldHint=True, readOnlyHint=True) +) @validate_id("chat_id") async def get_pinned_messages(chat_id: Union[int, str]) -> str: """ @@ -3056,7 +3199,9 @@ async def get_pinned_messages(chat_id: Union[int, str]) -> str: return log_and_format_error("get_pinned_messages", e, chat_id=chat_id) -@mcp.tool(annotations=ToolAnnotations(openWorldHint=True, destructiveHint=True)) +@mcp.tool( + annotations=ToolAnnotations(title="Create Poll", openWorldHint=True, destructiveHint=True) +) async def create_poll( chat_id: int, question: str,