capture-and-slack-mcp
Relays a result screenshot to Slack so you can review a coding agent's output without opening the app.
README
capture-and-slack-mcp
An MCP server that relays a result screenshot to Slack so you can review a coding agent's output without opening the app.
You hand an agent a task on your desktop app (e.g. Clonify, a Qt/VTK CAD tool), and end it with "…and send me the result via the capture-and-slack MCP." The agent renders the result to an image and this server posts it to your Slack DM or a channel. You glance at Slack instead of launching the app.
This server does not drive any GUI — it only relays images.
How it fits the loop
agent finishes a task
├─ (A, preferred) runs a repro/test that offscreen-renders the result → /tmp/result.png
│ → send_to_slack(["/tmp/result.png"], "3mm gaussian emboss done")
└─ (B, fallback) the app window is on screen (X11)
→ capture_window_and_post("result", window="Clonify")
→ Slack files_upload_v2 → you see the image in your Slack DM/channel
Path A is the robust one: the app's own headless render (VTK SetOffScreenRendering(1) +
vtkWindowToImageFilter, optionally under QT_QPA_PLATFORM=offscreen) writes a PNG, and this
server just posts it. Path B screenshots the live window and is for when no offscreen render exists.
Tools
| Tool | What it does |
|---|---|
send_to_slack(images, message="", channel=None, title=None, echo_image=False) |
Post one or more existing image files to Slack as a single message. Returns a JSON status with the permalink(s). Primary tool. |
capture_window_and_post(message="", window=None, channel=None, trim=True, echo_image=False) |
Screenshot the running window (X11/KDE) and post it. window defaults to CAPTURE_WINDOW_TITLE; use "active" or "full". |
capture_window(window=None, trim=True) |
Screenshot without posting and return it for inspection. Compose with send_to_slack. No Slack token needed. |
Image paths must be absolute (the server's working directory differs from the agent's).
Errors come back as a JSON envelope {"code","message","hint"} in an isError result.
Requirements
uvand Python ≥ 3.12.- A Slack bot token (see Slack setup — image uploads need
files_upload_v2; webhooks can't attach files). - For live capture only: an X11 session with ImageMagick
importor KDEspectacleinstalled. Precise per-window targeting usesxdotoolif present, elsexwininfo(already on most X11 desktops) — no install needed. Match by window title or WM_CLASS substring; a class likeQClonifyAppdisambiguates from an editor tab that merely has "Clonify" in its title.
Slack setup (one time)
- Go to https://api.slack.com/apps → Create New App → From an app manifest, pick your
workspace, and paste:
Scopes:{ "display_information": { "name": "Capture and Slack Bot" }, "features": { "bot_user": { "display_name": "capture-and-slack", "always_online": true } }, "oauth_config": { "scopes": { "bot": ["files:write", "chat:write", "im:write"] } }, "settings": { "org_deploy_enabled": false, "socket_mode_enabled": false } }files:write(upload),chat:write(the caption),im:write(open a DM when the destination is a user ID; drop it if you'll only post to channels). - Install to Workspace → authorize → copy the Bot User OAuth Token (
xoxb-…) from OAuth & Permissions. - Pick a destination ID:
- DM to yourself: your member ID
U…(Slack profile → ⋮ → Copy member ID). The bot can DM you without an invite. - A channel: the channel ID
C…(channel → View details), and run/invite @capture-and-slackin it.
- DM to yourself: your member ID
- Provide the token to the server (do not commit it):
cp .env.example .envand fill inSLACK_BOT_TOKENandSLACK_DEFAULT_CHANNEL, or export them in your shell. - (Optional, for precise window targeting)
sudo pacman -S xdotool.
Install & test
uv sync
uv run pytest
Register with Claude Code
Project-scoped (.mcp.json is already in this repo):
{
"mcpServers": {
"capture-and-slack": {
"command": "uv",
"args": ["run", "--directory", "/home/baho/Desktop/capture-and-slack-mcp", "capture-and-slack-mcp"]
}
}
}
The server reads SLACK_BOT_TOKEN / SLACK_DEFAULT_CHANNEL from the environment or a git-ignored
.env. (Keep the token out of .mcp.json, which is committed.)
Configuration
| Env var | Default | Purpose |
|---|---|---|
SLACK_BOT_TOKEN |
— | Bot token (xoxb-…). Required to post. |
SLACK_DEFAULT_CHANNEL |
— | Default destination: U… (DM), C… (channel), or D… (DM channel). |
CAPTURE_WINDOW_TITLE |
Clonify |
Default window title substring for live captures. |
CAPTURE_SLACK_MAX_FILE_MB |
25 |
Reject larger image files before uploading. |
CAPTURE_SLACK_SCRATCH_DIR |
<tmp>/capture_and_slack_mcp |
Where captured PNGs are written. |
Development
Module map — only server.py imports the MCP SDK:
server.py— the 3 tools +main().slack_client.py—slack_sdkwrapper:files_upload_v2, DM resolution, error translation.capture.py— X11/KDE window capture. Layered fallback: resolve window id (xdotool → xwininfo) and grab it directly → active window (spectacle) → fullscreen.images.py— Pillow: path/content validation, auto-trim, PNG byte reads.config.py— env-driven settings (with a tiny.envloader).errors.py—ErrorCode+CaptureSlackError(JSON envelope).
License
MIT
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。