Skip to content

Add new MCP server + send_image_to_user tool for outbound image delivery#99

Merged
RichardAtCT merged 2 commits intoRichardAtCT:mainfrom
guillaumegay13:feature/outbound-image-support
Feb 26, 2026
Merged

Add new MCP server + send_image_to_user tool for outbound image delivery#99
RichardAtCT merged 2 commits intoRichardAtCT:mainfrom
guillaumegay13:feature/outbound-image-support

Conversation

@guillaumegay13
Copy link
Copy Markdown
Contributor

This PR introduces MCP (Model Context Protocol) integration to the project. A new MCP stdio server
exposes custom tools that Claude can call during conversations. The first tool is send_image_to_user,
which lets Claude send images to Telegram users explicitly rather than relying on regex-based guessing
from response text.

The MCP server lives in src/mcp/telegram_server.py and is built with FastMCP, making it straightforward
to add more Telegram-specific tools in the future (e.g. send_file_to_user, send_notification,
ask_user_confirmation, etc.). Adding a new tool is as simple as defining a new function decorated with
@mcp.tool() in that file.

How it works: when Claude calls send_image_to_user(file_path, caption), the stream callback intercepts
the tool call, validates the path against the approved directory (symlink resolution, 50MB size cap,
extension allowlisting), and collects the image. After the response completes, images are delivered to
Telegram as inline photos (raster under 10MB) or as documents (SVG/large files). When the response text
is short enough it gets embedded as a caption on the image.

Files added: src/mcp/telegram_server.py (the MCP server), config/mcp.example.json (example config,
actual mcp.json is gitignored), tests/unit/test_mcp/test_telegram_server.py.

Files changed: src/bot/utils/image_extractor.py (stripped down to validate_image_path and
should_send_as_photo), src/bot/orchestrator.py and src/bot/handlers/message.py (stream callback
intercepts MCP tool calls), src/events/handlers.py, src/events/types.py, src/notifications/service.py
(removed previous auto-detection code).

All 428 tests pass, linting is clean.

guillaumegay13 and others added 2 commits February 23, 2026 16:09
When Claude generates or reads image files (charts, slides, diagrams),
automatically detect them and send as Telegram photos/albums instead of
just text references to file paths.

Images are detected from two sources: response text (regex matching paths
in backticks, quotes, markdown syntax, bare paths) and tool call inputs
(Read/Write/Edit of image files). When the response fits in a caption
(≤1024 chars), text and images are combined into a single message;
otherwise text is sent first followed by a grouped album.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace regex-based auto-detection with an explicit MCP tool that Claude
calls when it wants to send an image to the user. The stream callback
intercepts send_image_to_user tool calls, validates paths against the
approved directory, and delivers images as Telegram photos/documents.

- Add src/mcp/telegram_server.py (FastMCP stdio server with send_image_to_user tool)
- Add validate_image_path() for secure path validation (boundary + symlink checks)
- Intercept MCP tool calls in stream callbacks (orchestrator + classic handler)
- Remove regex/tool-scan auto-detection (extract_images_from_response)
- Remove image_paths from AgentResponseEvent and notification service
- Add config/mcp.example.json, gitignore config/mcp.json

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@guillaumegay13 guillaumegay13 force-pushed the feature/outbound-image-support branch from 456355a to bf23e4e Compare February 25, 2026 09:50
@RichardAtCT RichardAtCT merged commit 1ac560f into RichardAtCT:main Feb 26, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants