Add new MCP server + send_image_to_user tool for outbound image delivery#99
Merged
RichardAtCT merged 2 commits intoRichardAtCT:mainfrom Feb 26, 2026
Merged
Conversation
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>
456355a to
bf23e4e
Compare
This was referenced Feb 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.