send_photo
Send a photo to a Telegram chat using a URL, with optional caption and formatting. Control notification settings.
Instructions
Send a photo to a Telegram chat.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| chat_id | Yes | ||
| photo_url | Yes | ||
| caption | No | ||
| parse_mode | No | HTML | |
| disable_notification | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ok | Yes | ||
| error | No | ||
| message_id | No | ||
| chat_id | No |
Implementation Reference
- aiogram_mcp/tools/messaging.py:91-134 (handler)The 'send_photo' MCP tool handler. Defined as an async function registered via @mcp.tool decorator. Accepts chat_id, photo_url, caption, parse_mode, disable_notification. Checks chat permission, acquires rate limiter token, calls ctx.bot.send_photo(), audits on completion, returns SendPhotoResult.
@mcp.tool async def send_photo( chat_id: int, photo_url: str, caption: str | None = None, parse_mode: str | None = "HTML", disable_notification: bool = False, ) -> SendPhotoResult: """Send a photo to a Telegram chat.""" if not ctx.is_chat_allowed(chat_id): result = SendPhotoResult(ok=False, error=f"Chat {chat_id} is not allowed.") if ctx.audit_logger: ctx.audit_logger.log( "send_photo", {"chat_id": chat_id, "photo_url": photo_url}, result.ok, result.error, ) return result try: if ctx.rate_limiter: await ctx.rate_limiter.acquire() msg = await ctx.bot.send_photo( chat_id=chat_id, photo=photo_url, caption=caption, parse_mode=normalize_parse_mode(parse_mode), disable_notification=disable_notification, ) result = SendPhotoResult(ok=True, message_id=msg.message_id, chat_id=msg.chat.id) except ValueError as exc: result = SendPhotoResult(ok=False, error=str(exc)) except (TelegramBadRequest, TelegramForbiddenError) as exc: result = SendPhotoResult(ok=False, error=str(exc)) if ctx.audit_logger: ctx.audit_logger.log( "send_photo", {"chat_id": chat_id, "photo_url": photo_url}, result.ok, result.error, ) return result - aiogram_mcp/tools/messaging.py:20-22 (schema)SendPhotoResult model: the Pydantic response schema for send_photo, containing message_id and chat_id fields.
class SendPhotoResult(ToolResponse): message_id: int | None = None chat_id: int | None = None - aiogram_mcp/tools/messaging.py:29-31 (registration)register_messaging_tools function: registers the send_photo tool (alongside send_message, forward_message, etc.) on the FastMCP instance, conditioned on allowed_tools containing 'send_photo'.
def register_messaging_tools( mcp: FastMCP, ctx: BotContext, allowed_tools: set[str] | None = None ) -> None: - aiogram_mcp/server.py:86-88 (registration)AiogramMCP._register_tools calls register_messaging_tools with the permission-filtered allowed_tools set, which gates whether send_photo is registered.
def _register_tools(self) -> None: at = self._allowed_tools register_messaging_tools(self._mcp, self._ctx, allowed_tools=at) - aiogram_mcp/permissions.py:25-51 (helper)send_photo is mapped to PermissionLevel.MESSAGING in TOOL_PERMISSIONS dict, controlling which permission level can access it.
"send_message": PermissionLevel.MESSAGING, "send_photo": PermissionLevel.MESSAGING, "forward_message": PermissionLevel.MESSAGING, "send_interactive_message": PermissionLevel.MESSAGING, "edit_message": PermissionLevel.MESSAGING, "answer_callback_query": PermissionLevel.MESSAGING, "send_document": PermissionLevel.MESSAGING, "send_voice": PermissionLevel.MESSAGING, "send_video": PermissionLevel.MESSAGING, "send_animation": PermissionLevel.MESSAGING, "send_audio": PermissionLevel.MESSAGING, "send_sticker": PermissionLevel.MESSAGING, "send_video_note": PermissionLevel.MESSAGING, "send_contact": PermissionLevel.MESSAGING, "send_location": PermissionLevel.MESSAGING, "send_poll": PermissionLevel.MESSAGING, # moderation (6 tools) "delete_message": PermissionLevel.MODERATION, "pin_message": PermissionLevel.MODERATION, "ban_user": PermissionLevel.MODERATION, "unban_user": PermissionLevel.MODERATION, "set_chat_title": PermissionLevel.MODERATION, "set_chat_description": PermissionLevel.MODERATION, # admin (3 tools) "broadcast": PermissionLevel.ADMIN, "subscribe_events": PermissionLevel.ADMIN, "unsubscribe_events": PermissionLevel.ADMIN,