Skip to content

Commit 095d00b

Browse files
committed
feat(messages): add forward_messages (batch) tool and strengthen guidance
Small models hosting the MCP client often pick the simpler branch of `Union[int, List[int]]` and fall back to looping single-int forwards, defeating the album-grouping preservation added in the previous commit. Two changes to nudge them toward the correct path: 1. `forward_message`: rewrite the docstring as a directive ("USE A LIST WHENEVER FORWARDING >1 MESSAGE") with an Args block FastMCP parses for per-parameter descriptions. The model now sees the rule front and center in the tool description, not buried in a paragraph. 2. New tool `forward_messages` (plural) with a pure `List[int]` signature — no Union, no anyOf in the resulting JSON Schema. A list-only schema is unambiguous: the model has no "int branch" to fall back on. Backward-compatible: `forward_message` still accepts both `int` and `List[int]`.
1 parent aaa4f28 commit 095d00b

1 file changed

Lines changed: 72 additions & 4 deletions

File tree

telegram_mcp/tools/messages.py

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -694,11 +694,24 @@ async def forward_message(
694694
account: str = None,
695695
) -> str:
696696
"""
697-
Forward one or more messages from one chat to another.
697+
Forward one or more messages from a source chat to a destination chat.
698698
699-
Pass a list of message IDs to forward multiple messages in a single call.
700-
Messages that share a Telegram album (same grouped_id) are preserved as a
701-
grouped album in the destination when forwarded together in one list.
699+
To forward MULTIPLE messages, pass `message_id` as a list of integers in
700+
a SINGLE call (e.g. message_id=[12345, 12346, 12347]). Do NOT call this
701+
tool repeatedly with single ints to forward several messages — the list
702+
form is faster, atomic, and preserves Telegram album grouping (messages
703+
sharing a `grouped_id` arrive as one grouped album in the destination).
704+
705+
Pass a single int only when forwarding exactly one message and you do
706+
not need album grouping. See also: forward_messages (plural) — same
707+
behavior with a list-only signature.
708+
709+
Args:
710+
from_chat_id: Source chat (id or @username).
711+
message_id: A single message id (int) OR a list of message ids
712+
(e.g. [12345, 12346]). USE A LIST WHENEVER FORWARDING >1 MESSAGE.
713+
to_chat_id: Destination chat (id or @username).
714+
account: Optional account label for multi-account mode.
702715
"""
703716
try:
704717
cl = get_client(account)
@@ -719,6 +732,61 @@ async def forward_message(
719732
)
720733

721734

735+
@mcp.tool(
736+
annotations=ToolAnnotations(
737+
title="Forward Messages (batch)", openWorldHint=True, destructiveHint=True
738+
)
739+
)
740+
@with_account(readonly=False)
741+
@validate_id("from_chat_id", "to_chat_id")
742+
async def forward_messages(
743+
from_chat_id: Union[int, str],
744+
message_ids: List[int],
745+
to_chat_id: Union[int, str],
746+
account: str = None,
747+
) -> str:
748+
"""
749+
Forward a BATCH of messages from a source chat to a destination chat in
750+
a single atomic call.
751+
752+
Use this whenever you need to forward more than one message. Pass all
753+
message ids as a list (e.g. message_ids=[12345, 12346, 12347]). Calling
754+
this once with a list is strictly better than calling forward_message
755+
multiple times: it preserves Telegram album grouping (siblings sharing
756+
`grouped_id` arrive as one grouped album), is atomic, and counts as a
757+
single forward op for Telegram rate limits.
758+
759+
For exactly one message, you may use either this tool with a one-item
760+
list or `forward_message` with an int.
761+
762+
Args:
763+
from_chat_id: Source chat (id or @username).
764+
message_ids: List of message ids to forward, in any order
765+
(e.g. [12345, 12346]). Must contain at least one id.
766+
to_chat_id: Destination chat (id or @username).
767+
account: Optional account label for multi-account mode.
768+
"""
769+
try:
770+
if not message_ids:
771+
return "Error: message_ids must contain at least one id."
772+
cl = get_client(account)
773+
from_entity = await resolve_entity(from_chat_id, cl)
774+
to_entity = await resolve_entity(to_chat_id, cl)
775+
await cl.forward_messages(to_entity, list(message_ids), from_entity)
776+
return (
777+
f"{len(message_ids)} messages forwarded from "
778+
f"{from_chat_id} to {to_chat_id}."
779+
)
780+
except Exception as e:
781+
return log_and_format_error(
782+
"forward_messages",
783+
e,
784+
from_chat_id=from_chat_id,
785+
message_ids=message_ids,
786+
to_chat_id=to_chat_id,
787+
)
788+
789+
722790
@mcp.tool(
723791
annotations=ToolAnnotations(
724792
title="Edit Message", openWorldHint=True, destructiveHint=True, idempotentHint=True

0 commit comments

Comments
 (0)