capture-and-slack-mcp

capture-and-slack-mcp

Relays a result screenshot to Slack so you can review a coding agent's output without opening the app.

Category
Visit Server

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

  • uv and 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 import or KDE spectacle installed. Precise per-window targeting uses xdotool if present, else xwininfo (already on most X11 desktops) — no install needed. Match by window title or WM_CLASS substring; a class like QClonifyApp disambiguates from an editor tab that merely has "Clonify" in its title.

Slack setup (one time)

  1. Go to https://api.slack.com/appsCreate New App → From an app manifest, pick your workspace, and paste:
    {
      "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 }
    }
    
    Scopes: 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).
  2. Install to Workspace → authorize → copy the Bot User OAuth Token (xoxb-…) from OAuth & Permissions.
  3. 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-slack in it.
  4. Provide the token to the server (do not commit it): cp .env.example .env and fill in SLACK_BOT_TOKEN and SLACK_DEFAULT_CHANNEL, or export them in your shell.
  5. (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.pyslack_sdk wrapper: 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 .env loader).
  • errors.pyErrorCode + CaptureSlackError (JSON envelope).

License

MIT

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured