capture-and-slack-mcp
Posts screenshots or image files to Slack channels or direct messages. Can capture a window screenshot from an X11/KDE session and send it, or relay existing image files.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@capture-and-slack-mcpsend the rendered result screenshot to Slack"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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/channelPath 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.
Related MCP server: screenshot-feedback-hook-mcp
Tools
Tool | What it does |
| Post image(s) to Slack as a review: a root anchor message (a Block Kit task card when |
| Screenshot the running window (X11/KDE) and post it as a review. |
| Screenshot without posting and return it for inspection. Compose with |
Safety: when a specific
windowtitle can't be matched to an on-screen window, capture returnsNO_WINDOW_MATCHrather than silently grabbing the focused window or the whole desktop (which would leak unrelated apps/secrets to Slack). Passallow_fullscreen=True(orwindow="full") to opt into the whole-screen fallback deliberately. |wait_for_review(review_id, channel=None, timeout_seconds=50, poll_seconds=5)| Block until the human reacts (👍/👎/👀/✏️) or replies in the review thread. Returnsapproved/rejected/changes/seen, orstill_awaitingon timeout — call again to keep waiting. | |check_review(review_id, channel=None)| Non-blocking single read of the current verdict. Use in your own polling loop. | |ask_review(review_id, question, channel=None, timeout_seconds=50, poll_seconds=5)| Ask the reviewer a follow-up question in Slack (e.g. why they rejected) and wait for their typed answer. Posts + broadcasts the question so an away reviewer sees it. Returnsanswered+reply, orstill_awaiting+ask_id. | |wait_for_reply(review_id, since_ts, channel=None, timeout_seconds=50, poll_seconds=5)| Block until a thread reply appears aftersince_ts(e.g. theask_idfromask_review). Returnsanswered+replyorstill_awaiting. |
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.
Closing the review loop
send_to_slack returns a review_id (the thread's root message ts). The agent seeds a task card,
the human taps 👍/👎 on their phone (or replies "make it 5mm"), and wait_for_review(review_id)
returns the verdict to the agent:
send_to_slack(["/tmp/result.png"], title="3mm emboss", status="pass",
checks={"volume Δ": "+2.1%", "watertight": "yes"}) → {"review_id": "1712…", …}
wait_for_review("1712…", channel="C…") → {"status": "approved", …}Re-render into the same thread by passing thread_ts=review_id to send_to_slack; add
notify=True to broadcast the re-render back to the channel (🔁) so a watching reviewer is re-pinged.
If the agent needs to ask something (e.g. the reviewer rejected and the agent wants to know
why), it must ask in Slack, not in the terminal — the reviewer is watching Slack. ask_review
posts the question into the thread, pings the reviewer, and returns their typed answer:
wait_for_review("1712…", "C…") → {"status": "rejected"}
ask_review("1712…", "Why — emboss too sharp, or wrong face?") → {"status": "answered", "reply": "too sharp"}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:
{ "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", "reactions:write", "reactions:read", "channels:history", "groups:history", "im:history" ] } }, "settings": { "org_deploy_enabled": false, "socket_mode_enabled": false } }Scopes:
files:write(upload),chat:write(the caption/card),im:write(open a DM when the destination is a user ID). For the review loop:reactions:write(seed 👍/👎),reactions:read(read the verdict), and history (channels:historyfor public channels,groups:historyfor private,im:historyfor DMs) to read threaded replies. Drop the loop scopes if you only ever post one-way. If you add scopes to an existing app, reinstall it so the new grants take effect.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.
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 pytestRegister 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 |
| — | Bot token ( |
| — | Default destination: |
|
| Default window title substring for live captures. |
|
| Soft cap: larger images are auto-shrunk (downscale → JPEG) to fit before uploading. |
|
| Hard ceiling: files bigger than this are rejected ( |
|
| Where captured/shrunk PNGs are written (created |
|
| Reap scratch files older than this (minutes) on access; |
| (unset) | Set ( |
|
| Server log level, written to stderr (DEBUG, INFO, WARNING, …). |
|
| Auto-retries for rate-limited (429, honors Retry-After) / connection-error Slack calls. |
|
| Per-request Slack HTTP timeout (seconds). |
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
Available Tools
7 toolsask_reviewA
Ask the reviewer a follow-up question IN SLACK and wait for their typed answer. Posts the
question into the review thread and pings the channel so an away reviewer (watching Slack, not
your terminal) actually sees it — ALWAYS use this instead of asking in the console. Returns the
answer (status 'answered'), or 'still_awaiting' + ask_id on timeout; then keep waiting with
wait_for_reply(review_id, since_ts=ask_id).
| Name | Required | Description | Default |
|---|---|---|---|
| channel | No | The channel/DM the review is in; defaults to SLACK_DEFAULT_CHANNEL. | |
| question | Yes | The question to ask the reviewer (e.g. 'Why did you reject — is the emboss too sharp, or the wrong face?'). | |
| review_id | Yes | The `review_id` of the thread to ask in (from send_to_slack). | |
| poll_seconds | No | Seconds between reply polls. | |
| timeout_seconds | No | Max seconds to block waiting for the answer before returning 'still_awaiting' + ask_id (kept under ~60s client limits). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description thoroughly covers behavior: it posts to the review thread, pings the channel so away reviewers notice, blocks waiting for an answer, returns 'answered' with the answer or 'still_awaiting' with an ask_id on timeout, and includes polling and timeout mechanics. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no fluff. The first sentence front-loads the core action, and the second adds necessary details about behavior and return values. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the primary use case, return values (answer vs. still_awaiting), and the follow-up action (wait_for_reply). However, it omits error handling (e.g., invalid review_id) and does not detail the channel parameter's effect on pinging. Overall sufficient but not exhaustive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage, so the baseline is 3. The description adds some context (e.g., explaining poll_seconds and timeout_seconds usage) but does not significantly enhance the already clear schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool asks a follow-up question in Slack and waits for an answer. It distinguishes itself from siblings like wait_for_reply and send_to_slack by specifying the exact mechanism (posting in thread, pinging channel) and noting that it blocks for a reply.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs to 'ALWAYS use this instead of asking in the console,' providing a clear when-to-use. It also mentions wait_for_reply as a follow-up step. However, it does not compare against other sibling tools like capture_window or check_review, leaving some ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
capture_windowA
Capture a screenshot WITHOUT posting, and return it for inspection. Compose with send_to_slack: look at the image, then post the returned path if it's the right frame. No Slack call, so no token/scopes are needed.
| Name | Required | Description | Default |
|---|---|---|---|
| trim | No | Auto-crop a uniform border/background. | |
| window | No | Window title substring (default CAPTURE_WINDOW_TITLE). Use 'active' for the focused window, or 'full'/'root' for the whole screen. | |
| allow_fullscreen | No | Permit the whole-screen fallback when the title can't be matched (otherwise NO_WINDOW_MATCH). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that no Slack call is made, so no token or scope is needed, and that the screenshot is returned for inspection. However, it does not describe the output format or any side effects, which is a gap given no annotations are provided.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core purpose, and each sentence provides unique value (purpose then usage pattern). No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description explains the core functionality and usage pattern well, but it does not mention the return value format. Given the schema fully documents parameters, the description is mostly complete for a tool with no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters. The description adds no additional meaning about parameters like 'trim', 'window', or 'allow_fullscreen', thus no added value beyond the schema baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it captures a screenshot without posting, and distinguishes from the sibling 'capture_window_and_post' by noting it does not call Slack and does not require tokens/scopes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description suggests composing with 'send_to_slack' to inspect and optionally post the image, indicating when to use this tool versus alternatives. However, it does not explicitly list exclusion criteria or enumerate sibling alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
capture_window_and_postA
Screenshot the running app window (X11/KDE) and post it to Slack as a review. Use only when no offscreen render exists; otherwise prefer send_to_slack with a repro-rendered PNG.
| Name | Required | Description | Default |
|---|---|---|---|
| trim | No | Auto-crop a uniform border/background before posting. | |
| title | No | Task/review title: the card header AND the file title in Slack. Defaults to the file name. | |
| window | No | Window title substring to capture (default CAPTURE_WINDOW_TITLE, e.g. 'Clonify'). Use 'active' for the focused window, or 'full'/'root' for the whole screen. | |
| channel | No | Destination (C.../D.../U...); defaults to SLACK_DEFAULT_CHANNEL. | |
| message | No | Caption shown with the upload. | |
| thread_ts | No | Reply into an existing review thread (pass an earlier `review_id`); omit to start a new one. | |
| echo_image | No | Also return the posted image so you can confirm what was sent. | |
| allow_fullscreen | No | Permit the whole-screen fallback when the window title can't be matched. Off by default so a missed match errors (NO_WINDOW_MATCH) instead of silently posting your whole desktop to Slack. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It details key behaviors: fallback to fullscreen (with allow_fullscreen parameter explaining error vs silent posting), default window title via environment variable, and that thread_ts is for replying. Minor omission is the exact return value, but echo_image parameter partially addresses output.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The main description is two concise sentences. Parameter descriptions are detailed but not verbose. Overall well-structured and easy to parse, though slightly longer due to complete parameter documentation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 8 parameters, no output schema, and no annotations, the description covers the tool's purpose, use case, and parameter details well. However, it does not explicitly describe the return value when echo_image is false (e.g., whether it returns a review_id or just posts), leaving some ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds value beyond schema. For example, title parameter explains its dual role as card header and file title, window parameter explains default env var and special values like 'active', and allow_fullscreen explains error behavior. This extra context justifies above baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Screenshot the running app window (X11/KDE) and post it to Slack as a review.' It provides a specific verb, resource, and action, and explicitly distinguishes from sibling tool send_to_slack by specifying when to use each.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool ('only when no offscreen render exists') and when to prefer the alternative ('otherwise prefer send_to_slack with a repro-rendered PNG'). This is strong usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_reviewA
Non-blocking: read the current review verdict once and return immediately (status approved / rejected / changes / seen / still_awaiting). Use in your own polling loop; use wait_for_review to block until the human responds.
| Name | Required | Description | Default |
|---|---|---|---|
| channel | No | The channel/DM the review was posted to; defaults to SLACK_DEFAULT_CHANNEL. | |
| review_id | Yes | The `review_id` returned by an earlier send/capture call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Declares non-blocking behavior and immediate return. Lists possible return values. With no annotations, it carries full burden; while it implies read-only ('read the current review verdict'), it does not explicitly state no side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no fluff, key information front-loaded. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, it lists possible statuses. Explains non-blocking behavior and usage pattern. Missing error handling details, but sufficient for a simple read tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (baseline 3). Description adds context: review_id origin and channel default behavior, enhancing beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it reads the current review verdict and lists possible statuses. Distinguishes from sibling wait_for_review by emphasizing non-blocking nature.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs to use in polling loop and provides alternative wait_for_review for blocking scenario. Covers both when and when not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_to_slackA
Post one or more existing image files to Slack as a review. Posts a root anchor message (a
Block Kit task card when title/status/checks/links are given) and threads the image(s) beneath
it. Returns a JSON status including review_id (poll it with wait_for_review) and the Slack
permalink(s). This is the primary tool: pair it with a repro/test that renders the result to a
PNG.
| Name | Required | Description | Default |
|---|---|---|---|
| links | No | Name→URL link buttons on the card (e.g. {'Open mesh report':'https://...'}). Up to 5. | |
| title | No | Task/review title: used as the Block Kit card header AND the file title in Slack. Defaults to each file's name. | |
| checks | No | Name→value facts shown as card fields (e.g. {'volume Δ':'+2.1%','watertight':'yes','hausdorff':'0.03mm'}). Up to 10. | |
| images | Yes | Absolute path(s) to image files (usually PNGs a repro/test rendered). Posted in order as ONE Slack message. | |
| notify | No | When replying into an existing thread (thread_ts set), also broadcast the re-render back to the channel (🔁) so a watching reviewer is re-pinged. Ignored for a new review. | |
| status | No | Verdict badge on the card: pass/fail/warn/error/info (e.g. from mesh-validator). Renders as ✅/❌/⚠️. | |
| channel | No | Destination: channel ID (C...), DM channel (D...), or user ID (U...) for a DM. Defaults to SLACK_DEFAULT_CHANNEL. | |
| message | No | Caption shown with the upload (Slack initial_comment). | |
| thread_ts | No | Reply into an existing review thread: pass the `review_id` returned by an earlier call (e.g. to post a re-render). Omit to start a new review thread. | |
| echo_image | No | Also return the posted image(s) so you can visually confirm exactly what was sent. Off by default to save tokens. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It thoroughly discloses behaviors: posts a root anchor message (Block Kit task card when title/status/checks/links given), threads images, returns JSON with review_id and permalink, explains notify behavior (broadcasts to channel when replying), and default channel. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is efficient, with three sentences that front-load the main action and detail. Parentheticals add necessary context without being overly verbose. It avoids unnecessary words, though could be slightly more compact.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 10 parameters, 1 required, and no output schema, the description is very complete. It explains the overall flow, return value structure (review_id and permalink), parameter usage for all key fields, and mentions polling with wait_for_review. It covers essential behavioral details for safe and effective use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description adds meaningful context beyond the schema: e.g., title is 'used as the Block Kit card header AND the file title in Slack,' checks are 'Name→value facts shown as card fields,' images are 'Posted in order as ONE Slack message,' and notify is 'Ignored for a new review.' These details enhance understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Post one or more existing image files to Slack as a review.' It specifies the action (posting), resource (image files to Slack), and purpose (review). It also distinguishes from siblings by calling itself 'the primary tool' and noting the returned review_id can be polled with wait_for_review, setting it apart from other tools like ask_review or capture_window.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context: 'This is the primary tool: pair it with a repro/test that renders the result to a PNG.' It explains that it posts a root anchor message and threads images, and that the review_id can be polled. However, it does not explicitly state when not to use this tool or compare it directly to siblings, so it lacks exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wait_for_replyA
Block until the reviewer posts a thread reply AFTER since_ts, or until timeout. Returns the
reply text (status 'answered') or 'still_awaiting'. Use to keep waiting after ask_review timed out.
| Name | Required | Description | Default |
|---|---|---|---|
| channel | No | Channel/DM of the review; defaults to SLACK_DEFAULT_CHANNEL. | |
| since_ts | Yes | Only a reply AFTER this ts counts — pass the `ask_id` from ask_review (or a prior reply_ts). | |
| review_id | Yes | The `review_id` (thread) to watch. | |
| poll_seconds | No | Seconds between reply polls. | |
| timeout_seconds | No | Max seconds to block before returning 'still_awaiting' (call again to keep waiting). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description discloses blocking behavior, return values, and timeout, but it does not state whether the tool has side effects (e.g., modifying state) or the polling mechanism, though param descriptions cover polling interval.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core action, and every sentence adds value—defining behavior and providing usage guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description explains blocking, conditions, return values, and timeout behavior. It lacks explicit mention of polling frequency but covers it in the `poll_seconds` parameter description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%; the tool description reinforces the use of `since_ts` and `timeout_seconds` but adds little new information beyond the schema's parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it blocks until a thread reply is posted after `since_ts` or timeout, and contrasts with sibling tools like ask_review and wait_for_review by specifying usage after ask_review timeout.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly advises using this tool after ask_review timed out, providing clear context for when to use it, but does not explicitly state when not to use it or compare with all siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wait_for_reviewA
Block until the human reacts (👍/👎/👀/✏️) or replies in the review thread, or until timeout. Returns a JSON verdict: status is approved / rejected / changes / seen, or 'still_awaiting' on timeout (with a hint to call again). Pair with send_to_slack's review_id.
| Name | Required | Description | Default |
|---|---|---|---|
| channel | No | The channel/DM the review was posted to (the `channel` from the send result). Defaults to SLACK_DEFAULT_CHANNEL. | |
| review_id | Yes | The `review_id` returned by send_to_slack / capture_window_and_post (the review thread's root ts). | |
| poll_seconds | No | Seconds between reaction/reply polls. | |
| timeout_seconds | No | Max seconds to block before returning status 'still_awaiting' (kept under typical ~60s MCP client limits). Call again with the same review_id to keep waiting. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, but description discloses blocking behavior, timeout, return verdict format, and re-call hint. Does not cover auth or error cases, but key behavioral traits are addressed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three effective sentences with zero waste. Front-loaded with main action, return format, and pairing hint. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given well-described schema and no output schema, description adequately covers return format and pairing. Could mention blocking duration limit implicitly, but overall complete for the use case.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage 100% (baseline 3). Description adds value: explains review_id origin, channel default (SLACK_DEFAULT_CHANNEL), and the re-call hint on timeout. Enhances parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states the verb 'Block' and the resource 'human reaction/reply in review thread', distinguishing from siblings like check_review (non-blocking) and wait_for_reply (replies only).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear context: blocks until human reacts/replies or timeout, and explicitly pairs with send_to_slack's review_id. Lacks explicit when-not-to-use or alternatives but is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
7 tool updates
v0.1.0- First observed
ask_review - First observed
capture_window - First observed
capture_window_and_post - First observed
check_review - First observed
send_to_slack - First observed
wait_for_reply - First observed
wait_for_review
TDQS
Each tool has a clear, distinct purpose: capture without posting, capture and post, send existing files, ask questions, check status, and two blocking wait variants. No two tools overlap in functionality.
All tool names use snake_case with a consistent verb_noun pattern (ask_review, capture_window, check_review, send_to_slack, wait_for_reply, wait_for_review). The slightly longer 'capture_window_and_post' still follows the same structure and is clear.
With 7 tools, the server is well-scoped for its purpose: capturing screenshots and managing Slack review workflows. Each tool adds necessary functionality without bloat or redundancy.
The tool set covers the main workflow: capture, post, review, follow-up. A minor gap is the lack of a tool to post a regular Slack message without a review, but the core review-focused flow is well-supported.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Human-in-the-loop for AI coding agents — ask questions, get approvals via Slack.
Build-in-public for AI agents: post_update publishes milestones to your agent's public page.
Let your AI agent notify you by email, Slack, Discord, or webhook. One tool: send_notification.
Generate images, GIFs, and PDFs from HTML, URLs, or templates — from your AI agent.
Related MCP Servers
- FlicenseAqualityNot gradedmaintenanceEnables two-way communication between Claude and Slack for posting messages, managing threads, and handling files. It specifically supports asynchronous workflows by allowing Claude to poll for remote user replies and send task notifications.9-
- AlicenseAqualityBmaintenanceA cross-platform screenshot tool that lets coding agents capture and view their output, enabling self-correction through visual feedback.23MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI coding agents to send structured Telegram notifications for events like questions, plan_ready, final, attention_needed, and error.MIT
- FlicenseNot gradedqualityBmaintenanceEnables AI agents to capture screenshots of windows (e.g., WeChat developer tools) and save them locally, allowing the agent to read the image directly and close the code-change-to-review loop without OSS or network.1-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/baho0/capture-and-slack-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server