edit_message
Edit the text and inline keyboard of a sent message in a Telegram chat.
Instructions
Edit the text and/or inline keyboard of an existing message.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| chat_id | Yes | Chat containing the message. | |
| message_id | Yes | ID of the message to edit. | |
| text | Yes | New message text. | |
| buttons | No | New inline keyboard (None to remove buttons). | |
| parse_mode | No | HTML, Markdown, MarkdownV2, or None. | HTML |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ok | Yes | ||
| error | No | ||
| message_id | No | ||
| chat_id | No |
Implementation Reference
- aiogram_mcp/tools/interactive.py:139-215 (handler)The MCP tool handler for 'edit_message'. Edits the text and/or inline keyboard of an existing Telegram message using ctx.bot.edit_message_text(). Supports chat permission checks, button validation via _build_keyboard(), rate limiting, parse mode normalization, and audit logging.
@mcp.tool async def edit_message( chat_id: int, message_id: int, text: str, buttons: list[list[dict[str, str]]] | None = None, parse_mode: str | None = "HTML", ) -> EditMessageResult: """Edit the text and/or inline keyboard of an existing message. Args: chat_id: Chat containing the message. message_id: ID of the message to edit. text: New message text. buttons: New inline keyboard (None to remove buttons). parse_mode: HTML, Markdown, MarkdownV2, or None. """ if not ctx.is_chat_allowed(chat_id): result = EditMessageResult( ok=False, error=f"Chat {chat_id} is not in allowed_chat_ids.", ) if ctx.audit_logger: ctx.audit_logger.log( "edit_message", {"chat_id": chat_id, "message_id": message_id, "text": text}, result.ok, result.error, ) return result reply_markup = None if buttons is not None: keyboard = _build_keyboard(buttons) if isinstance(keyboard, str): result = EditMessageResult(ok=False, error=keyboard) if ctx.audit_logger: ctx.audit_logger.log( "edit_message", {"chat_id": chat_id, "message_id": message_id, "text": text}, result.ok, result.error, ) return result reply_markup = keyboard try: if ctx.rate_limiter: await ctx.rate_limiter.acquire() api_result = await ctx.bot.edit_message_text( chat_id=chat_id, message_id=message_id, text=text, parse_mode=normalize_parse_mode(parse_mode), reply_markup=reply_markup, ) if isinstance(api_result, bool): result = EditMessageResult(ok=True, message_id=message_id, chat_id=chat_id) else: result = EditMessageResult( ok=True, message_id=api_result.message_id, chat_id=api_result.chat.id, ) except ValueError as exc: result = EditMessageResult(ok=False, error=str(exc)) except (TelegramBadRequest, TelegramForbiddenError) as exc: result = EditMessageResult(ok=False, error=str(exc)) if ctx.audit_logger: ctx.audit_logger.log( "edit_message", {"chat_id": chat_id, "message_id": message_id, "text": text}, result.ok, result.error, ) return result - Pydantic response model for the edit_message tool, extending ToolResponse with optional message_id and chat_id fields.
class EditMessageResult(ToolResponse): message_id: int | None = None chat_id: int | None = None - aiogram_mcp/tools/interactive.py:137-137 (registration)Conditional registration of the edit_message tool via the @mcp.tool decorator within register_interactive_tools(), gated by the allowed_tools set.
if allowed_tools is None or "edit_message" in allowed_tools: - aiogram_mcp/server.py:101-101 (registration)Registration call site in AiogramMCP._register_tools() that triggers the interactive tools registration (including edit_message).
register_interactive_tools(self._mcp, self._ctx, allowed_tools=at) - aiogram_mcp/permissions.py:29-29 (helper)Permission mapping declaring edit_message at the MESSAGING permission level.
"edit_message": PermissionLevel.MESSAGING,