send_poll
Create and send a poll to a Telegram chat with a question, answer options, and configurable anonymity, quiz mode, or multiple answers.
Instructions
Send a poll to a Telegram chat.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| chat_id | Yes | Target chat ID. | |
| question | Yes | Poll question (1-300 characters). | |
| options | Yes | List of answer options (2-10 strings). | |
| is_anonymous | No | Whether the poll is anonymous. | |
| type | No | "regular" or "quiz". | regular |
| allows_multiple_answers | No | Allow multiple answers (regular polls only). | |
| disable_notification | No | Send silently. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ok | Yes | ||
| error | No | ||
| message_id | No | ||
| chat_id | No | ||
| poll_id | No |
Implementation Reference
- aiogram_mcp/tools/media.py:521-581 (handler)The async handler function for the send_poll MCP tool. Validates chat permissions, enforces rate limiting, sends the poll via aiogram's bot.send_poll, and returns a SendPollResult with message_id, chat_id, and poll_id on success.
async def send_poll( chat_id: int, question: str, options: list[str], is_anonymous: bool = True, type: str = "regular", allows_multiple_answers: bool = False, disable_notification: bool = False, ) -> SendPollResult: """Send a poll to a Telegram chat. Args: chat_id: Target chat ID. question: Poll question (1-300 characters). options: List of answer options (2-10 strings). is_anonymous: Whether the poll is anonymous. type: "regular" or "quiz". allows_multiple_answers: Allow multiple answers (regular polls only). disable_notification: Send silently. """ if not ctx.is_chat_allowed(chat_id): result = SendPollResult(ok=False, error=f"Chat {chat_id} is not allowed.") if ctx.audit_logger: ctx.audit_logger.log( "send_poll", {"chat_id": chat_id, "question": question}, result.ok, result.error, ) return result try: if ctx.rate_limiter: await ctx.rate_limiter.acquire() poll_options: list[InputPollOption | str] = [InputPollOption(text=opt) for opt in options] msg = await ctx.bot.send_poll( chat_id=chat_id, question=question, options=poll_options, is_anonymous=is_anonymous, type=type, allows_multiple_answers=allows_multiple_answers, disable_notification=disable_notification, ) result = SendPollResult( ok=True, message_id=msg.message_id, chat_id=msg.chat.id, poll_id=msg.poll.id if msg.poll else None, ) except (TelegramBadRequest, TelegramForbiddenError) as exc: result = SendPollResult(ok=False, error=str(exc)) if ctx.audit_logger: ctx.audit_logger.log( "send_poll", {"chat_id": chat_id, "question": question}, result.ok, result.error, ) return result - aiogram_mcp/tools/media.py:19-22 (schema)Pydantic result model for the send_poll tool, extending ToolResponse with message_id, chat_id, and poll_id fields.
class SendPollResult(ToolResponse): message_id: int | None = None chat_id: int | None = None poll_id: str | None = None - aiogram_mcp/tools/media.py:518-581 (registration)The send_poll tool is registered via the @mcp.tool decorator inside the register_media_tools function, conditionally based on allowed_tools. This function is called from server.py line 102.
if allowed_tools is None or "send_poll" in allowed_tools: @mcp.tool async def send_poll( chat_id: int, question: str, options: list[str], is_anonymous: bool = True, type: str = "regular", allows_multiple_answers: bool = False, disable_notification: bool = False, ) -> SendPollResult: """Send a poll to a Telegram chat. Args: chat_id: Target chat ID. question: Poll question (1-300 characters). options: List of answer options (2-10 strings). is_anonymous: Whether the poll is anonymous. type: "regular" or "quiz". allows_multiple_answers: Allow multiple answers (regular polls only). disable_notification: Send silently. """ if not ctx.is_chat_allowed(chat_id): result = SendPollResult(ok=False, error=f"Chat {chat_id} is not allowed.") if ctx.audit_logger: ctx.audit_logger.log( "send_poll", {"chat_id": chat_id, "question": question}, result.ok, result.error, ) return result try: if ctx.rate_limiter: await ctx.rate_limiter.acquire() poll_options: list[InputPollOption | str] = [InputPollOption(text=opt) for opt in options] msg = await ctx.bot.send_poll( chat_id=chat_id, question=question, options=poll_options, is_anonymous=is_anonymous, type=type, allows_multiple_answers=allows_multiple_answers, disable_notification=disable_notification, ) result = SendPollResult( ok=True, message_id=msg.message_id, chat_id=msg.chat.id, poll_id=msg.poll.id if msg.poll else None, ) except (TelegramBadRequest, TelegramForbiddenError) as exc: result = SendPollResult(ok=False, error=str(exc)) if ctx.audit_logger: ctx.audit_logger.log( "send_poll", {"chat_id": chat_id, "question": question}, result.ok, result.error, ) return result - aiogram_mcp/server.py:102-102 (registration)Top-level call that triggers registration of the send_poll tool (among other media tools) in the AiogramMCP server initialization.
register_media_tools(self._mcp, self._ctx, allowed_tools=at) - aiogram_mcp/permissions.py:40-40 (helper)Permission mapping declaring send_poll at MESSAGING level, used by get_allowed_tools to determine if the tool should be registered.
"send_poll": PermissionLevel.MESSAGING,