Skip to main content
Glama

Real terminal colors, Shiki-highlighted code, visual diffs, PDFs and GIFs — one MCP server, 13 tools. Renders with your system Chrome, or auto-installs Chromium at first setup. SSRF protection on by default. Built for agents that write documentation, not just drive browsers.

Quick Start

Three steps, under two minutes:

1. Install

npm install -g snapmcp
# or run without installing: npx -y snapmcp

2. Add to Claude Code (~/.claude/claude.json)

{
  "mcpServers": {
    "snapmcp": {
      "command": "npx",
      "args": ["-y", "snapmcp"],
      "env": {
        "SNAPMCP_DIR": "./captures",
        "SNAPMCP_THEME": "nord"
      }
    }
  }
}

3. Capture

Ask your agent in natural language:

"Capture a terminal screenshot of git log --oneline -5 and a syntax-highlighted PNG of src/index.ts."

The agent calls capture_terminal and capture_file — images land in ./captures/ with your real terminal theme and the chosen syntax theme applied.

OpenCode (opencode.json):

{
  "mcpServers": {
    "snapmcp": {
      "command": "npx",
      "args": ["-y", "snapmcp"],
      "env": {
        "SNAPMCP_DIR": "./captures",
        "SNAPMCP_FORMAT": "jpeg",
        "SNAPMCP_QUALITY": "95"
      }
    }
  }
}

VS Code / Cline / Roo-Cline (settings.json → cline.mcpServers):

{
  "mcpServers": {
    "snapmcp": {
      "command": "npx",
      "args": ["-y", "snapmcp"],
      "env": {
        "SNAPMCP_DIR": "./captures",
        "SNAPMCP_FORMAT": "jpeg"
      }
    }
  }
}

Docker:

docker run -i --rm \
  -e SNAPMCP_DIR=/captures \
  -e SNAPMCP_THEME=nord \
  -v /path/to/output:/captures \
  ghcr.io/reeinharddd/snapmcp

Related MCP server: aifmt

What it looks like

Capture

Preview

Terminal (real detected colors)

Code (Shiki syntax)

Diff (green/red)

Why snapmcp vs Playwright MCP

Different tools for different jobs. Playwright MCP drives a browser through token-efficient accessibility snapshots; snapmcp renders pixel-faithful images for humans to read. If your agent needs to click, use Playwright. If it needs to show, use snapmcp.

Use case

snapmcp

Playwright MCP

Terminal capture with real colors

✅ auto-detects Kitty, Gnome, Alacritty, WezTerm themes

❌ no terminal support

Code → syntax-highlighted image

✅ Shiki, 50+ languages, 27 themes

❌ not its purpose

Git diff → visual red/green image

✅ capture_diff

❌

URL → PDF document

✅ capture_pdf

❌

Animated GIF from captures

✅ capture_gif (zero-dep gifenc)

❌

Markdown → styled document

✅ capture_markdown, capture_document

❌

Browser page screenshot

✅ capture_browser (full-page or viewport)

✅

Browser automation (click, fill, navigate)

❌ screenshots only

✅ accessibility-tree driven, token-efficient — the right tool for this

Most documentation pipelines pair them: Playwright MCP to interact, snapmcp to document.

Tools

Tool

Description

capture_terminal

Terminal output with syntax-colored prompts (auto-detects real terminal theme)

capture_code

Syntax-highlighted code via Shiki (50+ languages, 27 themes)

capture_browser

Full-page or viewport screenshots (uses system Chrome profile when available)

capture_file

File → auto-detected language → highlighted screenshot

capture_markdown

Rendered markdown as a styled document

capture_html

Arbitrary HTML snippet rendered as image

capture_diff

Git diffs with green additions / red deletions

capture_pdf

URL → PDF document

capture_batch

Batch capture multiple items in one call

capture_gif

Animated GIF from multiple screenshots

capture_sequence

Side-by-side animated sequence

capture_document

Create document (MD/HTML/PDF) with embedded captures

snapmcp-hint

Server capability hints for MCP clients

Use cases

Automated documentation — an agent writes a setup guide and embeds real captures: the terminal output of the install command (with your actual theme), the config file syntax-highlighted, the diff of the migration. One prompt, three capture_* calls, images saved next to the markdown.

Visual QA — after a UI change, the agent captures the affected pages with capture_browser, batches before/after with capture_batch, and assembles an animated comparison with capture_gif for the PR description.

Terminal guides — CLI tutorials where the screenshots must match what readers will see: capture_terminal reproduces the real prompt colors instead of a generic dark rectangle.

Security

SSRF protection is on by default — no opt-in required.

Feature

Description

SSRF Protection

On by default (disable with SNAPMCP_SSRF_PROTECTION=false). Blocks IP literals (v4 + v6), localhost variants, and DNS names that resolve to private ranges (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7, fe80::/10, etc.); every page request (redirects included) is re-checked

File Allowlist

SNAPMCP_ALLOWED_PATHS defaults to deny-all when unset; only explicitly allowed paths can be captured

Path Traversal

Prevents ../ escapes, symlink traversal (via realpath), and null byte injection

Input Limits

Terminal 1000 lines; code/markdown/HTML 200KB; diff 500KB; file reads 5MB; max GIF frames 60; max GIF canvas 8192×8192

Audit Log

Optional structured JSON log file with timestamped events

Chromium Sandbox

Sandbox availability checked at startup

Configuration

Environment variables for the MCP server:

Variable

Default

Description

SNAPMCP_DIR

./captures

Output directory for captures

SNAPMCP_THEME

auto-detected

Syntax theme (27 built-in themes + auto-detected terminal)

SNAPMCP_FORMAT

png

Output format (png, jpeg)

SNAPMCP_QUALITY

90

JPEG quality (1-100)

SNAPMCP_PADDING

32

Content padding in pixels

SNAPMCP_SHADOW

none

Drop shadow (none, soft, medium, strong; aliases sm/md/lg)

SNAPMCP_WINDOW_CHROME

false

macOS-style title bar frame

SNAPMCP_BORDER_RADIUS

0

Window corner radius

SNAPMCP_BADGE

false

Footer badge

SNAPMCP_LOG_FILE

—

Audit log file path

SNAPMCP_CHROME_EXECUTABLE

—

Path to Chrome/Chromium binary

SNAPMCP_CHROME_CHANNEL

—

Chrome channel (stable, beta, dev, canary)

SNAPMCP_CHROME_PROFILE

—

Chrome profile directory name

SNAPMCP_ALLOWED_PATHS

(deny-all)

Comma- or semicolon-separated allowed file paths for capture_file

27 built-in Shiki themes: dracula, one-dark-pro, nord, tokyo-night, catppuccin-mocha, catppuccin-latte, ayu-dark, ayu-light, vitesse-dark, vitesse-light, min-dark, min-light, poimandres, rose-pine, rose-pine-moon, rose-pine-dawn, slack-dark, slack-ochin, snazzy-light, github-dark-dimmed, github-light, one-light, solarized-light, solarized-dark, material-theme, material-theme-lighter, material-theme-ocean

CLI

SnapMCP ships with a full CLI beyond the MCP server:

snapmcp        — Start the MCP server
snapmcp init   — Interactive setup wizard (detects Chrome, terminal theme, output dir)
snapmcp doctor — Health check: 7 checks across Node, Chromium, paths, env
snapmcp test   — Generate test captures (terminal + code) to verify the setup

Documentation

Page

Contents

Getting Started

Installation, quick start, MCP client setup

Tools Reference

All 13 tools with parameters and examples

Configuration

All SNAPMCP_* env vars, themes, defaults

CLI Reference

Init, doctor, test commands

Guides

Terminal capture, browser capture, GIF animation

ARCHITECTURE.md

Module map, data flow, security architecture

CONTRIBUTING.md

Dev workflow, testing guidelines, PR checklist

Development

git clone https://github.com/reeinharddd/snapmcp
cd snapmcp
bun install
bun run build    # tsc → dist/
bun test         # 317 tests

Requirements: Node.js ≥ 20 or Bun ≥ 1.2. CI runs on ubuntu / macOS / windows via GitHub Actions.

License

MIT — see LICENSE.

Available Tools

13 tools
capture_batchA

Capture multiple items in a single call. Each capture is processed sequentially with its own parameters. Use for batch documentation generation (e.g., capture terminal output, code file, and browser screenshot together). Maximum 10 captures per call.

ParametersJSON Schema
NameRequiredDescriptionDefault
outputNoOutput directory (default: SNAPMCP_DIR). Captures saved as individual files.
capturesYesArray of captures to process. Each capture specifies its type and type-specific parameters.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. It adds useful behavioral context: 'Each capture is processed sequentially with its own parameters' and 'Maximum 10 captures per call.' However, the max limit is already in the schema, and the description does not cover failure behavior, what happens if one capture fails, or file-output side effects beyond what the schema's output parameter implies.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact: three sentences covering purpose, batch use case, and the key 10-capture limit. The limit repeats schema maxItems, but restating it in the description is helpful for quick scanning. The example earns its place by making the batch intent concrete.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a batch wrapper tool with a rich schema and many sibling tools, the description clarifies why an agent would choose capture_batch over single-capture tools. It does not explain output structure or error handling, but the schema covers per-capture parameters and the output directory, so the description is largely sufficient for selection and invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 the captures array and its per-type properties in detail. The description's mention that 'Each capture is processed sequentially with its own parameters' adds little semantic value beyond the schema, which fully specifies the oneOf structure. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb and resource: 'Capture multiple items in a single call.' It is immediately distinguishable from single-capture siblings like capture_terminal and capture_browser because it frames itself as a batch operation. The example ('capture terminal output, code file, and browser screenshot together') further clarifies the intended resource scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit usage context: 'Use for batch documentation generation' and provides a concrete example of mixed capture types. It does not explicitly say when to avoid this tool in favor of single-capture siblings, but the batch versus single distinction is strongly implied by the wording and sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

capture_browserA

Take a screenshot of a URL using headless Chromium. Uses system Chrome profile when available (set SNAPMCP_CHROME_PROFILE) for authenticated sessions, cookies, and extensions. SSRF protection is enabled by default (SNAPMCP_SSRF_PROTECTION=true) - blocks private IPs, localhost, and DNS-rebounding attacks. Supports full-page or viewport captures.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesURL to capture (http/https). Must pass SSRF validation: no private IPs (10/8, 172.16/12, 192.168/16, fc00::/7), no localhost variants, no DNS-rebinding. Redirects are also validated.
widthNoViewport width in pixels (320-3840). Ignored if fullPage=true.
heightNoViewport height in pixels (240-4096). Ignored if fullPage=true.
outputNoOutput filename (default: auto-generated as 'browser-<timestamp>.png' or '.jpeg' based on SNAPMCP_FORMAT). Include extension to override format.
fullPageNoCapture full scrollable page (true) or just the viewport (false). Full page may take longer and use more memory.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses headless Chromium, optional Chrome-profile use, and SSRF protections including blocked IP ranges and DNS-rebinding defense. It does not fully describe the return value or post-capture behavior, such as whether a file path is returned, so a 5 is not justified.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, each carrying distinct information: core action, authentication/profile behavior, SSRF safeguards, and capture modes. The most important facts are front-loaded with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 5-parameter tool with no annotations and no output schema, the description plus schema is nearly sufficient: it covers purpose, security behavior, profile behavior, and all parameters. The main gap is that the result format is not described, and there is no explicit guidance distinguishing this tool from its many capture_* siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already thoroughly documents url, width, height, output, and fullPage. The description adds useful environment-variable context (SNAPMCP_CHROME_PROFILE, SNAPMCP_SSRF_PROTECTION) but no additional parameter-level meaning, matching the high-coverage baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Take a screenshot of a URL using headless Chromium.' This immediately distinguishes capture_browser from siblings like capture_pdf or capture_html by anchoring on URL and screenshot behavior. The full-page/viewport detail further clarifies scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear usage context: it is for URL screenshots and explicitly mentions when the Chrome profile is relevant for authenticated sessions, cookies, and extensions. It does not explicitly name alternative tools or state when not to use this tool, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

capture_codeA

Generate a syntax-highlighted code screenshot using Shiki (50+ languages, 27 themes). Renders code with line numbers, theme-aware colors, and optional window chrome. Ideal for code documentation, tutorials, and sharing snippets with authentic IDE-like appearance.

ParametersJSON Schema
NameRequiredDescriptionDefault
codeYesSource code to render. Maximum 200KB.
titleNoWindow title shown in the title bar (e.g., 'src/main.ts', 'example.py')code
outputNoOutput filename (default: auto-generated as 'code-<timestamp>.png' or '.jpeg' based on SNAPMCP_FORMAT). Include extension to override format.
endLineNoLast line number to show in the gutter (1-indexed, inclusive). Must be >= startLine if both provided.
languageNoProgramming language for highlighting. Supports 50+ languages: typescript, javascript, python, rust, go, java, c, cpp, csharp, ruby, php, swift, kotlin, sql, json, yaml, markdown, html, css, bash, dockerfile, toml, xml, graphql, and many more. Use 'text' for plain text.text
startLineNoFirst line number to show in the gutter (1-indexed). Use with endLine to show a code range.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses rendering behavior such as line numbers, theme-aware colors, and optional window chrome, but it does not mention side effects like creating an output file, where it is written, or how themes and window chrome are controlled given the schema has no parameters for them. This leaves some ambiguity about the actual tool behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with a clear hierarchy: action, features, use cases. It is appropriately sized, though the closing phrase 'authentic IDE-like appearance' is slightly promotional and the mention of 27 themes is not reflected in the input schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is adequate for invoking the tool: it explains what is rendered and for what use cases, and the schema covers all parameters. However, with no output schema, the tool description does not state what the tool returns, such as a file path or confirmation, and it does not clarify output-side behavior. This is a gap for a tool with no annotations and no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 sufficiently. The tool description adds high-level context about languages and themes but does not explain individual parameters beyond what the schema provides, so it meets the baseline for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening clause, 'Generate a syntax-highlighted code screenshot using Shiki,' names a specific action and resource. It clearly distinguishes this tool from siblings like capture_terminal or capture_markdown by focusing on code rendering with line numbers and IDE-like styling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context: 'Ideal for code documentation, tutorials, and sharing snippets.' It does not explicitly list exclusions or alternatives, but the use cases are concrete enough for an agent to select this tool for code-screenshot needs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

capture_diffA

Render a git diff with color-coded additions (green) and deletions (red). Parses unified diff format (output of git diff, diff -u). Shows file headers, line numbers, and context lines. Ideal for PR reviews, migration guides, and change documentation. Maximum input 500KB.

ParametersJSON Schema
NameRequiredDescriptionDefault
diffYesDiff content in unified diff format (e.g., output of 'git diff' or 'diff -u'). Must include file headers (---/+++) and hunks (@@ -... +... @@). Maximum 500KB.
outputNoOutput filename (default: auto-generated as 'diff-<timestamp>.png' or '.jpeg' based on SNAPMCP_FORMAT). Include extension to override format.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses parsing behavior, displayed elements, and a 500KB size limit, which is useful. But it does not state whether the tool writes an image file, what the output artifact is, or any side effects — details only partially covered by the schema's output parameter.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded with the primary action: 'Render a git diff with color-coded additions and deletions.' Each sentence adds relevant context — parsing, display elements, use cases, and size limit — without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with two parameters and no annotations, the description covers input format, size limit, rendering features, and ideal use cases. It omits explicit output format or mechanics, but the schema's output parameter fills that gap. This is adequate for a straightforward capture tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description reinforces the diff format requirement and size cap, but these are already present in the schema's diff parameter. The output parameter is adequately described in the schema, so the description adds minimal parameter-level value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource — 'Render a git diff with color-coded additions and deletions' — and distinguishes itself from sibling capture_* tools by specifying unified diff input and rendering features. It clearly identifies the tool's unique function within the capture family.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description states 'Ideal for PR reviews, migration guides, and change documentation,' which signals appropriate contexts. It also defines the accepted input format (unified diff), implying it should be used only when data is in that format. However, it does not explicitly name alternative sibling tools or state when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

capture_fileA

Read a file and generate a syntax-highlighted screenshot with automatic language detection from file extension. Supports 50+ languages via Shiki. Requires SNAPMCP_ALLOWED_PATHS to be set for security (deny-all by default). Maximum file size 5MB.

ParametersJSON Schema
NameRequiredDescriptionDefault
outputNoOutput filename (default: auto-generated as 'file-<timestamp>.png' or '.jpeg' based on SNAPMCP_FORMAT). Include extension to override format.
endLineNoLast line number to capture (1-indexed, inclusive). Must be >= startLine if both provided. Defaults to end of file.
filePathYesAbsolute path to the file to capture. Must be within SNAPMCP_ALLOWED_PATHS allowlist. Symlinks are resolved to prevent traversal.
startLineNoFirst line number to capture (1-indexed, inclusive). Use with endLine to capture a specific range.

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals that the tool reads a file, is security-config dependent with deny-all default, has a maximum file size, and supports automatic language detection. It does not explicitly mention all failure modes or whether it writes output to disk, but the read-only implication is clear.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three concise sentences with no filler: the first states the core action, the second highlights language support, and the third covers security and size limits. Information is appropriately front-loaded and every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema and no annotations, the description covers key operational details but omits the return value/format and any error behavior. It also does not situate the tool among its many siblings, leaving some ambiguity for an agent deciding whether capture_file is the right choice.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds useful behavioral constraints such as file extension-based language detection and the 5MB maximum, but these are not essential to understanding individual parameters beyond what the schema already documents.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's specific function: reading a file and generating a syntax-highlighted screenshot with automatic language detection. This distinguishes it from siblings like capture_terminal or capture_browser, though it doesn't explicitly differentiate it from the similarly-named capture_code.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use capture_file versus its alternatives. It only notes prerequisites and constraints (SNAPMCP_ALLOWED_PATHS, 5MB limit), but does not explain selection criteria or exclusions relative to the many sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

capture_gifA

Create an animated GIF from sequential captures. Each frame is captured with full type-specific parameters, then compiled into a GIF. Use for animated tutorials, before/after comparisons, step-by-step demonstrations. Maximum 60 frames, maximum canvas 8192x8192.

ParametersJSON Schema
NameRequiredDescriptionDefault
loopNoWhether the GIF loops infinitely (true) or plays once (false)
titleNoName for the GIF (used in default filename)animation
outputNoOutput filename (default: auto-generated as '<title>-<timestamp>.gif'). Must end in .gif
capturesYesArray of frames to capture. Each frame specifies its capture type and type-specific parameters. Minimum 2, maximum 60 frames.
frameDelayNoFrame delay in milliseconds (10-5000). Default 800ms.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description must carry the full burden of behavioral disclosure. It mentions constraints like 'Maximum 60 frames, maximum canvas 8192x8192', which is good. However, it does not disclose other behaviors such as how output is returned (file path?), whether it is synchronous, or potential side effects (e.g., temporary files). This is a moderate gap but not contradictory.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, with the primary purpose in the first sentence and key constraints (max frames, canvas) early. Sentences are efficient and avoid redundancy. The mention of use cases adds a little length but is valuable for guidance, so it earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complex input schema with seven capture types, the description provides a high-level overview but omits details like the specific frame types (terminal, code, etc.) and that each has its own parameters. However, the schema itself documents these thoroughly, so the description doesn't need to repeat. It does not explain the return value, but with no output schema, a note on what to expect (e.g., a file path) would improve completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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, including nested types. The description adds minimal value beyond the schema, but it does clarify the overall flow (frames are captured sequentially) and reinforces the min/max frames. The schema covers parameter meaning well, so this is adequate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool creates an animated GIF from sequential captures, and explains that frames are captured with full type-specific parameters. It distinguishes itself from siblings (which likely capture single frames) by focusing on animated GIF output. The use cases (animated tutorials, before/after comparisons, step-by-step demonstrations) provide clear context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains when to use this tool (for animated content) and implies that it is the right choice over single-capture siblings. However, it does not explicitly mention when NOT to use it (e.g., for a single frame, where a sibling would be more appropriate). The example use cases give good context, but explicit alternatives are not named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

capture_htmlA

Render arbitrary HTML as a screenshot with full CSS support. Use for custom UI previews, email templates, dashboard widgets, or any HTML/CSS content. Renders in a clean viewport with optional window chrome. Security: input is sanitized, external resources (scripts, iframes, external CSS) are blocked. Maximum input 200KB.

ParametersJSON Schema
NameRequiredDescriptionDefault
htmlYesHTML content to render. External scripts, iframes, and external stylesheets are blocked for security. Inline styles and <style> tags work. Maximum 200KB.
titleNoDescription for logging and window title (if window chrome enabled).html
outputNoOutput filename (default: auto-generated as 'html-<timestamp>.png' or '.jpeg' based on SNAPMCP_FORMAT). Include extension to override format.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden for behavior disclosure dispusa. It clearly states sanitization, blocking of external resources, the 200KB maximum, and viewport/chrome rendering behavior. It does not describe the return value or failure modes, but it does cover the most important constraints for safe invocation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is four sentences with no wasted words: purpose, use cases, rendering context, and security constraints are each given one tight sentence. The most important information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple 3-parameter tool with no output schema and no annotations, the description covers what the tool does, when to use it, and the key constraints needed to use it correctly. It could improve by pointing to alternatives like capture_browser for live pages, which is the only notable gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description repeats the 200KB limit and external-resource blocking already present in the schema but does not add meaningfully new parameter semantics. The 'optional window chrome' note is minor supporting context, not a substantive parameter clarification.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and object ('Render arbitrary HTML as a screenshot') and immediately clarifies the special value ('with full CSS support'). It also lists concrete use cases, distinguishing this from sibling capture_* tools that target Markdown, browser pages, or files.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

An explicit 'Use for' clause gives clear selection context: custom UI previews, email templates, dashboard widgets, and general HTML/CSS content. It does not name alternatives or state when not to use this tool, so it falls just short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

capture_markdownA

Render Markdown as a styled document screenshot using GitHub-flavored Markdown. Supports tables, task lists, code blocks with syntax highlighting, mermaid diagrams (as text), and HTML. Renders with the configured Shiki theme and document styling. Maximum input 200KB.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleNoDocument title shown in the window title bar and as H1 if not present in markdown.document
outputNoOutput filename (default: auto-generated as 'markdown-<timestamp>.png' or '.jpeg' based on SNAPMCP_FORMAT). Include extension to override format.
markdownYesMarkdown content to render. Supports GFM: tables, task lists, fenced code blocks, strikethrough, autolinks. Maximum 200KB.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the behavioral disclosure burden. It discloses significant traits: rendering with a configured Shiki theme, support for HTML, the specific limitation that mermaid diagrams are rendered as text, and a maximum input size of 200KB. It does not mention output-file side effects or return values, which keeps it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences and front-loads the core purpose before adding supporting details. Every sentence contributes either a capability, a rendering behavior, or a constraint, with no fluff or redundant restatement of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a rendering tool with no output schema and no annotations, the description covers input constraints and rendering features well but omits what the tool returns or where the output screenshot is written. It is useable but not fully self-sufficient for an agent that needs to consume the produced artifact.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaningful semantics beyond the schema. It reveals mermaid-as-text behavior, HTML support, and Shiki theme rendering, which directly affect how the markdown parameter's content will be interpreted and displayed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence, 'Render Markdown as a styled document screenshot using GitHub-flavored Markdown,' names a specific action, resource, and output artifact. It further differentiates itself from siblings by listing supported features (tables, task lists, code blocks, mermaid as text, HTML) that are unique to Markdown rendering.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when Markdown content needs to become a styled screenshot, but it never explicitly states when to prefer this over alternatives like capture_html or capture_code, nor does it explain when not to use it. The context is clear but exclusions and sibling routing are left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

capture_pdfA

Convert a URL to a PDF document using headless Chromium. Renders the full page (including lazy-loaded content) or viewport to a print-quality PDF. Uses system Chrome profile when available for authenticated pages. SSRF protection enabled by default (blocks private IPs, localhost). Supports custom viewport for responsive PDFs.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesURL to convert to PDF (http/https). Must pass SSRF validation: no private IPs, localhost, or DNS-rebinding. Redirects are validated.
widthNoViewport width in pixels (320-3840) for responsive rendering.
heightNoViewport height in pixels (240-4096) for responsive rendering.
outputNoOutput filename (default: auto-generated as 'pdf-<timestamp>.pdf'). Must end in .pdf.
fullPageNoInclude all page content (true) or only viewport (false). Full page prints the entire scrollable document.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden and does well: it discloses headless Chromium usage, lazy-loaded content handling, full-page vs viewport behavior, Chrome profile authentication, and SSRF protections. This goes substantially beyond what the schema alone conveys.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is four compact sentences with no filler. It front-loads the core purpose, then adds behavioral details that matter for invocation, such as SSRF restrictions and authenticated-page support. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 5-parameter tool with no output schema and no annotations, the description covers the key invocation-relevant aspects: conversion mechanism, rendering mode, authentication, and network restrictions. The main gap is that it does not describe the return value or output location, which is more impactful because no output schema exists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameters are already well documented in the schema. The description reinforces concepts like full-page vs viewport and custom viewport, but adds no new parameter-level meaning that the schema does not already provide.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Convert a URL to a PDF document using headless Chromium.' It clearly identifies the output format and distinguishes itself from sibling capture tools like capture_markdown or capture_html by focusing on PDF generation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool's use case—producing print-quality PDFs from URLs—and mentions useful contexts like authenticated pages via the system Chrome profile. However, it does not explicitly state when to choose this over alternatives like capture_html or capture_to_document, nor does it mention exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

capture_sequenceA

Capture each step of a process as individual image files + optional compiled GIF. Each step has full type-specific parameters plus stepNumber and label for documentation. Use for CI/CD pipeline visualization, deployment steps, tutorial sequences. Maximum 60 steps.

ParametersJSON Schema
NameRequiredDescriptionDefault
loopNoWhether the GIF loops infinitely
stepsYesArray of steps to capture. Each step specifies its capture type, type-specific parameters, plus optional stepNumber and label.
outputNoOutput directory (default: SNAPMCP_DIR). Steps saved as individual files, GIF as sequence-<timestamp>.gif
compileGifNoCompile frames into an animated GIF (requires at least 2 steps)
frameDelayNoFrame delay in milliseconds for GIF (10-5000). Default 800ms.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses the 60-step limit and optional GIF generation, adding useful behavioral context. However, it does not mention file system effects, output directory behavior, overwriting, or execution time, which are important for a multi-file creation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core purpose, then use cases, then the key 60-step constraint. Every sentence earns its place; no waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description gives the essentials for a complex tool with many nested parameters Gang, but does not enumerate supported step types (terminal, code, file, etc.) nor mention output directory defaults. Given the extremely rich schema, this is a minor gap; the agent can rely on schema details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with detailed descriptions for all top-level parameters and each nested step object. The description only generically references 'type-specific parameters' without adding semantics beyond the schema; the baseline 3 applies because the schema carries the load.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states a specific verb ('Capture'), resource ('each step of a process as individual image files + optional compiled GIF'), and scope ('sequence'). The mention of stepNumber/label and 'Maximum 60 steps' distinguishes it from the single-step sibling capture tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit use cases ('CI/CD pipeline visualization, deployment steps, tutorial sequences'), which makes the intended context clear. It does not explicitly name alternative single-step tools or say when not to use this tool, but that is implied by the contrast with sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

capture_terminalA

Generate a styled terminal screenshot from text lines with real terminal theme colors. Automatically detects your terminal theme (Kitty, GNOME, Alacritty, WezTerm, etc.) for authentic prompt colors. Use for CLI tutorials, command output documentation, and terminal-based guides.

ParametersJSON Schema
NameRequiredDescriptionDefault
linesYesLines to render. Prefix command prompts with '$ ' (or '# ' for root) for syntax-colored prompts. Other lines are rendered as output. Maximum 1000 lines.
titleYesWindow title shown in the terminal title bar (e.g., 'bash', 'zsh', 'git log')
outputNoOutput filename (default: auto-generated as 'terminal-<timestamp>.png' or '.jpeg' based on SNAPMCP_FORMAT). Include extension to override format.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure, and it delivers a genuinely non-obvious trait: automatic theme detection (Kitty, GNOME, Alacritty, WezTerm, etc.) that determines prompt colors. It doesn't disclose the return value or file-write side effects in the description, but the core generation behavior is transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each earning its place: core function, behavioral nuance, and use cases. The purpose is front-loaded in sentence one with no filler or redundant restatement of schema content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a modest-complexity tool with fully documented parameters, the description covers purpose, usage, and the key behavioral quirk. The main gap is that there is no output schema and the description never states what the tool returns (e.g., a file path or URL), though the output parameter's filename semantics imply a saved artifact.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% — lines, title, and output each have inline documentation including the '$ '/ '# ' prompt-prefix rule and filename defaults, so the schema already carries the parameter semantics. The description adds theme-detection context that influences rendering but no per-parameter meaning, matching the baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource — "Generate a styled terminal screenshot from text lines" — and the terminal focus clearly differentiates it from capture_markdown, capture_code, and capture_html siblings. The phrase "with real terminal theme colors" further pins down the artifact type and rendering behavior.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The closing sentence gives explicit use cases: "Use for CLI tutorials, command output documentation, and terminal-based guides." It provides clear context for when to select this tool, but it doesn't name alternatives or state when not to use it, so it stops short of full exclusion guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

capture_to_documentB

Create a document (Markdown/HTML/PDF) with embedded step-by-step captures. Each capture is rendered as an image and embedded in the document with optional captions. Output formats: markdown (with image references), HTML (self-contained with base64 images), or PDF (print-quality). Maximum 30 captures per document.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYesDocument title
formatNoOutput document format: markdown (image refs), html (self-contained), pdf (print-quality)markdown
outputNoOutput filename (default: auto-generated as 'document-<timestamp>.md/.html/.pdf'). Extension should match format.
capturesYesArray of captures to embed. Each specifies capture type, type-specific parameters, and optional caption.
includeTimestampsNoInclude capture timestamps in the document

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure, and it does add value: it distinguishes output-format semantics (markdown uses image references, HTML is self-contained base64, PDF is print-quality) and states the 30-capture limit. However, it omits that the tool writes a file to disk and gives no hint of path/permission constraints (SNAPMCP_ALLOWED_PATHS appears only inside the captures schema) or SSRF protections for browser captures.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized and front-loaded with the primary purpose in the first sentence. However, the third and fourth sentences ('Output formats: ...' and 'Maximum 30 captures per document.') duplicate information already present in the input schema's format enum descriptions and captures maxItems, so they do not fully earn their place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a complex tool with 5 top-level parameters and 7 capture variants inside the captures array. Although the schema is rich and carries most of the load, the description provides no usage guidance versus siblings, no indication of whether the result is returned or written to disk, and no mention of file-output constraints. It is minimally viable but has clear gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds marginal value beyond the schema: 'rendered as an image' clarifies the rendering behavior for captures, but the format descriptions and 30-capture maximum simply restate what the format enum and captures maxItems already declare. No parameter meaning is lost, but nothing substantial is gained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('Create') and resource ('a document') and clarifies that each capture is rendered as an image and embedded, with optional captions. This differentiates it from the sibling capture_* tools, which produce single captures rather than composite documents, though it never names a sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not state when to choose this tool over capture_markdown, capture_browser, capture_pdf, or the other siblings. The 'step-by-step captures' wording implies an assembly/batching scenario and the 30-capture ceiling hints at scale, but there is no explicit when-to-use, when-not-to-use, or named alternative, leaving the agent to infer the use case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

snapmcp-hintA

Return a helpful hint about configuring and using snapmcp. Provides contextual guidance for setup, troubleshooting, and feature discovery.

ParametersJSON Schema
NameRequiredDescriptionDefault
topicNoTopic for targeted help: init (interactive setup), doctor (diagnostics), browser (Chrome profile), themes (27 syntax themes), output (capture directory), security (SSRF/path config), gif (animations), document (multi-capture docs), batch (multi-capture calls)

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states the tool returns a hint, implying a read-only operation, but doesn't explicitly mention that it creates no side effects or external calls. For this simple tool, the omission is not misleading, but it adds little beyond the obvious.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise at two sentences, but there is slight redundancy: 'Return a helpful hint' and 'Provides contextual guidance' communicate essentially the same function. Still, it is front-loaded with the core purpose and avoids unnecessary detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with one optional enum parameter and no output schema, the description is mostly complete. It explains the tool's purpose and scope, and the schema covers the parameter. It doesn't specify the return format, but for a hint tool, a text string is naturally implied.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage, with a single optional `topic` parameter fully enumerated and explained. The description adds no additional parameter semantics, so the baseline score of 3 is appropriate given the schema already handles the documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns a helpful hint about configuring and using snapmcp, using a specific verb ('Return') and resource. It distinguishes itself from sibling capture_* tools, which are all about capturing content, making the tool's purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use the tool: when needing guidance for setup, troubleshooting, or feature discovery. It doesn't explicitly mention alternatives, but the sibling tools are so different in purpose that no exclusion is necessary.

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.

  1. 13 tool updatesv2.3.4
    • Changedcapture_batch6 fields changed
      • addedInput schema / properties / captures / description
        Added value: +"Array of captures to process. Each capture specifies its type and type-specific parameters."
      • addedInput schema / properties / captures / items / oneOf
        Added value: +[
        +  {
        +    "properties": {
        +      "lines": {
        +        "description": "Lines to render. Prefix with '$ ' for prompts.",
        +        "items": {
        +          "type": "string"
        +        },
        +        "maxItems": 1000,
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "title": {
        +        "description": "Window title (default: 'terminal')",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "terminal",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "lines",
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "code": {
        +        "description": "Source code to render",
        +        "maxLength": 200000,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "endLine": {
        +        "description": "Last line number (1-indexed, inclusive)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "language": {
        +        "default": "text",
        +        "description": "Programming language (typescript, python, rust, go, etc.)",
        +        "type": "string"
        +      },
        +      "startLine": {
        +        "description": "First line number (1-indexed)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "title": {
        +        "description": "Window title (default: 'code')",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "code",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "code",
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "endLine": {
        +        "description": "Last line number (1-indexed, inclusive)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "filePath": {
        +        "description": "Absolute path to file (must be in SNAPMCP_ALLOWED_PATHS)",
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "startLine": {
        +        "description": "First line number (1-indexed)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "type": {
        +        "const": "file",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "filePath",
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "fullPage": {
        +        "default": false,
        +        "description": "Capture full scrollable page",
        +        "type": "boolean"
        +      },
        +      "height": {
        +        "default": 800,
        +        "description": "Viewport height (px)",
        +        "maximum": 4096,
        +        "minimum": 240,
        +        "type": "integer"
        +      },
        +      "type": {
        +        "const": "browser",
        +        "type": "string"
        +      },
        +      "url": {
        +        "description": "URL to capture (http/https, SSRF protected)",
        +        "format": "uri",
        +        "type": "string"
        +      },
        +      "width": {
        +        "default": 1280,
        +        "description": "Viewport width (px)",
        +        "maximum": 3840,
        +        "minimum": 320,
        +        "type": "integer"
        +      }
        +    },
        +    "required": [
        +      "url",
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "markdown": {
        +        "description": "Markdown content (GFM supported)",
        +        "maxLength": 200000,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "title": {
        +        "description": "Document title (default: 'document')",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "markdown",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "markdown",
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "html": {
        +        "description": "HTML content (external resources blocked)",
        +        "maxLength": 200000,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "title": {
        +        "description": "Description for logging (default: 'html')",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "html",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "html",
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "diff": {
        +        "description": "Unified diff content (git diff format)",
        +        "maxLength": 500000,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "diff",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "diff",
        +      "type"
        +    ],
        +    "type": "object"
        +  }
        +]
      • removedInput schema / properties / captures / items / properties
        Removed value: -{
        -  "caption": {
        -    "description": "Optional caption/label for the capture",
        -    "type": "string"
        -  },
        -  "params": {
        -    "additionalProperties": {},
        -    "description": "Parameters for the capture type",
        -    "propertyNames": {
        -      "type": "string"
        -    },
        -    "type": "object"
        -  },
        -  "type": {
        -    "enum": [
        -      "terminal",
        -      "code",
        -      "file",
        -      "browser",
        -      "markdown",
        -      "html",
        -      "diff"
        -    ],
        -    "type": "string"
        -  }
        -}
      • removedInput schema / properties / captures / items / required
        Removed value: -[
        -  "type",
        -  "params"
        -]
      • removedInput schema / properties / captures / items / type
        Removed value: -"object"
      • changedInput schema / properties / output / description
        Previous value: -"Output directory (default: SNAPMCP_DIR)"New value: +"Output directory (default: SNAPMCP_DIR). Captures saved as individual files."
    • Changedcapture_browser5 fields changed
      • changedInput schema / properties / fullPage / description
        Previous value: -"Capture full scrollable page"New value: +"Capture full scrollable page (true) or just the viewport (false). Full page may take longer and use more memory."
      • changedInput schema / properties / height / description
        Previous value: -"Viewport height (px)"New value: +"Viewport height in pixels (240-4096). Ignored if fullPage=true."
      • changedInput schema / properties / output / description
        Previous value: -"Output filename (default: auto-generated)"New value: +"Output filename (default: auto-generated as 'browser-<timestamp>.png' or '.jpeg' based on SNAPMCP_FORMAT). Include extension to override format."
      • changedInput schema / properties / url / description
        Previous value: -"URL to capture"New value: +"URL to capture (http/https). Must pass SSRF validation: no private IPs (10/8, 172.16/12, 192.168/16, fc00::/7), no localhost variants, no DNS-rebinding. Redirects are also validated."
      • changedInput schema / properties / width / description
        Previous value: -"Viewport width (px)"New value: +"Viewport width in pixels (320-3840). Ignored if fullPage=true."
    • Changedcapture_code8 fields changed
      • changedInput schema / properties / code / description
        Previous value: -"Source code to render"New value: +"Source code to render. Maximum 200KB."
      • addedInput schema / properties / code / maxLength
        Added value: +200000
      • changedInput schema / properties / endLine / description
        Previous value: -"Last line number to show in the gutter"New value: +"Last line number to show in the gutter (1-indexed, inclusive). Must be >= startLine if both provided."
      • changedInput schema / properties / language / description
        Previous value: -"Programming language for highlighting"New value: +"Programming language for highlighting. Supports 50+ languages: typescript, javascript, python, rust, go, java, c, cpp, csharp, ruby, php, swift, kotlin, sql, json, yaml, markdown, html, css, bash, dockerfile, toml, xml, graphql, and many more. Use 'text' for plain text."
      • changedInput schema / properties / output / description
        Previous value: -"Output filename (default: auto-generated)"New value: +"Output filename (default: auto-generated as 'code-<timestamp>.png' or '.jpeg' based on SNAPMCP_FORMAT). Include extension to override format."
      • changedInput schema / properties / startLine / description
        Previous value: -"First line number to show in the gutter"New value: +"First line number to show in the gutter (1-indexed). Use with endLine to show a code range."
      • changedInput schema / properties / title / description
        Previous value: -"Window title"New value: +"Window title shown in the title bar (e.g., 'src/main.ts', 'example.py')"
      • addedInput schema / properties / title / maxLength
        Added value: +100
    • Changedcapture_diff3 fields changed
      • changedInput schema / properties / diff / description
        Previous value: -"Diff content (git diff / unified diff format)"New value: +"Diff content in unified diff format (e.g., output of 'git diff' or 'diff -u'). Must include file headers (---/+++) and hunks (@@ -... +... @@). Maximum 500KB."
      • addedInput schema / properties / diff / maxLength
        Added value: +500000
      • changedInput schema / properties / output / description
        Previous value: -"Output filename (default: auto-generated)"New value: +"Output filename (default: auto-generated as 'diff-<timestamp>.png' or '.jpeg' based on SNAPMCP_FORMAT). Include extension to override format."
    • Changedcapture_file4 fields changed
      • changedInput schema / properties / endLine / description
        Previous value: -"Last line number to capture (1-indexed, inclusive)"New value: +"Last line number to capture (1-indexed, inclusive). Must be >= startLine if both provided. Defaults to end of file."
      • changedInput schema / properties / filePath / description
        Previous value: -"Absolute path to the file to capture"New value: +"Absolute path to the file to capture. Must be within SNAPMCP_ALLOWED_PATHS allowlist. Symlinks are resolved to prevent traversal."
      • changedInput schema / properties / output / description
        Previous value: -"Output filename (default: auto-generated)"New value: +"Output filename (default: auto-generated as 'file-<timestamp>.png' or '.jpeg' based on SNAPMCP_FORMAT). Include extension to override format."
      • changedInput schema / properties / startLine / description
        Previous value: -"First line number to capture (1-indexed, inclusive)"New value: +"First line number to capture (1-indexed, inclusive). Use with endLine to capture a specific range."
    • Changedcapture_gif10 fields changed
      • addedInput schema / properties / captures / description
        Added value: +"Array of frames to capture. Each frame specifies its capture type and type-specific parameters. Minimum 2, maximum 60 frames."
      • addedInput schema / properties / captures / items / oneOf
        Added value: +[
        +  {
        +    "properties": {
        +      "lines": {
        +        "description": "Lines to render. Prefix with '$ ' for prompts.",
        +        "items": {
        +          "type": "string"
        +        },
        +        "maxItems": 1000,
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "title": {
        +        "description": "Window title (default: 'frame')",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "terminal",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "lines",
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "code": {
        +        "description": "Source code to render",
        +        "maxLength": 200000,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "endLine": {
        +        "description": "Last line number (1-indexed, inclusive)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "language": {
        +        "default": "text",
        +        "description": "Programming language (typescript, python, rust, go, etc.)",
        +        "type": "string"
        +      },
        +      "startLine": {
        +        "description": "First line number (1-indexed)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "title": {
        +        "description": "Window title (default: 'frame')",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "code",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "code",
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "endLine": {
        +        "description": "Last line number (1-indexed, inclusive)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "filePath": {
        +        "description": "Absolute path to file (must be in SNAPMCP_ALLOWED_PATHS)",
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "startLine": {
        +        "description": "First line number (1-indexed)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "type": {
        +        "const": "file",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "filePath",
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "fullPage": {
        +        "default": false,
        +        "description": "Capture full scrollable page",
        +        "type": "boolean"
        +      },
        +      "height": {
        +        "default": 800,
        +        "description": "Viewport height (px)",
        +        "maximum": 4096,
        +        "minimum": 240,
        +        "type": "integer"
        +      },
        +      "type": {
        +        "const": "browser",
        +        "type": "string"
        +      },
        +      "url": {
        +        "description": "URL to capture (http/https, SSRF protected)",
        +        "format": "uri",
        +        "type": "string"
        +      },
        +      "width": {
        +        "default": 1280,
        +        "description": "Viewport width (px)",
        +        "maximum": 3840,
        +        "minimum": 320,
        +        "type": "integer"
        +      }
        +    },
        +    "required": [
        +      "url",
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "markdown": {
        +        "description": "Markdown content (GFM supported)",
        +        "maxLength": 200000,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "title": {
        +        "description": "Document title (default: 'frame')",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "markdown",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "markdown",
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "html": {
        +        "description": "HTML content (external resources blocked)",
        +        "maxLength": 200000,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "title": {
        +        "description": "Description for logging (default: 'frame')",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "html",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "html",
        +      "type"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "diff": {
        +        "description": "Unified diff content (git diff format)",
        +        "maxLength": 500000,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "diff",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "diff",
        +      "type"
        +    ],
        +    "type": "object"
        +  }
        +]
      • removedInput schema / properties / captures / items / properties
        Removed value: -{
        -  "label": {
        -    "description": "Optional label for the capture",
        -    "type": "string"
        -  },
        -  "params": {
        -    "additionalProperties": {},
        -    "description": "Parameters for the capture type",
        -    "propertyNames": {
        -      "type": "string"
        -    },
        -    "type": "object"
        -  },
        -  "type": {
        -    "enum": [
        -      "terminal",
        -      "code",
        -      "file",
        -      "browser",
        -      "markdown",
        -      "diff",
        -      "html"
        -    ],
        -    "type": "string"
        -  }
        -}
      • removedInput schema / properties / captures / items / required
        Removed value: -[
        -  "type",
        -  "params"
        -]
      • removedInput schema / properties / captures / items / type
        Removed value: -"object"
      • changedInput schema / properties / frameDelay / description
        Previous value: -"Frame delay in ms"New value: +"Frame delay in milliseconds (10-5000). Default 800ms."
      • changedInput schema / properties / loop / description
        Previous value: -"Whether the GIF loops"New value: +"Whether the GIF loops infinitely (true) or plays once (false)"
      • changedInput schema / properties / output / description
        Previous value: -"Output filename for the GIF"New value: +"Output filename (default: auto-generated as '<title>-<timestamp>.gif'). Must end in .gif"
      • changedInput schema / properties / title / description
        Previous value: -"Name for the GIF"New value: +"Name for the GIF (used in default filename)"
      • addedInput schema / properties / title / maxLength
        Added value: +100
    • Changedcapture_html5 fields changed
      • changedInput schema / properties / html / description
        Previous value: -"HTML content to render"New value: +"HTML content to render. External scripts, iframes, and external stylesheets are blocked for security. Inline styles and <style> tags work. Maximum 200KB."
      • addedInput schema / properties / html / maxLength
        Added value: +200000
      • changedInput schema / properties / output / description
        Previous value: -"Output filename (default: auto-generated)"New value: +"Output filename (default: auto-generated as 'html-<timestamp>.png' or '.jpeg' based on SNAPMCP_FORMAT). Include extension to override format."
      • changedInput schema / properties / title / description
        Previous value: -"Description (for logging)"New value: +"Description for logging and window title (if window chrome enabled)."
      • addedInput schema / properties / title / maxLength
        Added value: +100
    • Changedcapture_markdown5 fields changed
      • changedInput schema / properties / markdown / description
        Previous value: -"Markdown content to render"New value: +"Markdown content to render. Supports GFM: tables, task lists, fenced code blocks, strikethrough, autolinks. Maximum 200KB."
      • addedInput schema / properties / markdown / maxLength
        Added value: +200000
      • changedInput schema / properties / output / description
        Previous value: -"Output filename (default: auto-generated)"New value: +"Output filename (default: auto-generated as 'markdown-<timestamp>.png' or '.jpeg' based on SNAPMCP_FORMAT). Include extension to override format."
      • changedInput schema / properties / title / description
        Previous value: -"Document title"New value: +"Document title shown in the window title bar and as H1 if not present in markdown."
      • addedInput schema / properties / title / maxLength
        Added value: +100
    • Changedcapture_pdf5 fields changed
      • changedInput schema / properties / fullPage / description
        Previous value: -"Include all content"New value: +"Include all page content (true) or only viewport (false). Full page prints the entire scrollable document."
      • changedInput schema / properties / height / description
        Previous value: -"Viewport height"New value: +"Viewport height in pixels (240-4096) for responsive rendering."
      • changedInput schema / properties / output / description
        Previous value: -"Output filename (default: auto-generated)"New value: +"Output filename (default: auto-generated as 'pdf-<timestamp>.pdf'). Must end in .pdf."
      • changedInput schema / properties / url / description
        Previous value: -"URL to convert to PDF"New value: +"URL to convert to PDF (http/https). Must pass SSRF validation: no private IPs, localhost, or DNS-rebinding. Redirects are validated."
      • changedInput schema / properties / width / description
        Previous value: -"Viewport width"New value: +"Viewport width in pixels (320-3840) for responsive rendering."
    • Changedcapture_sequence9 fields changed
      • changedInput schema / properties / compileGif / description
        Previous value: -"Compile frames into an animated GIF"New value: +"Compile frames into an animated GIF (requires at least 2 steps)"
      • changedInput schema / properties / frameDelay / description
        Previous value: -"Frame delay in ms"New value: +"Frame delay in milliseconds for GIF (10-5000). Default 800ms."
      • changedInput schema / properties / loop / description
        Previous value: -"Whether the GIF loops"New value: +"Whether the GIF loops infinitely"
      • changedInput schema / properties / output / description
        Previous value: -"Output directory (default: SNAPMCP_DIR)"New value: +"Output directory (default: SNAPMCP_DIR). Steps saved as individual files, GIF as sequence-<timestamp>.gif"
      • addedInput schema / properties / steps / description
        Added value: +"Array of steps to capture. Each step specifies its capture type, type-specific parameters, plus optional stepNumber and label."
      • addedInput schema / properties / steps / items / oneOf
        Added value: +[
        +  {
        +    "properties": {
        +      "label": {
        +        "description": "Optional label for this step",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "lines": {
        +        "description": "Lines to render. Prefix with '$ ' for prompts.",
        +        "items": {
        +          "type": "string"
        +        },
        +        "maxItems": 1000,
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "stepNumber": {
        +        "description": "Step number label (auto-assigned if omitted)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "title": {
        +        "description": "Window title (default: 'step')",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "terminal",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "lines"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "code": {
        +        "description": "Source code to render",
        +        "maxLength": 200000,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "endLine": {
        +        "description": "Last line number (1-indexed, inclusive)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "label": {
        +        "description": "Optional label for this step",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "language": {
        +        "default": "text",
        +        "description": "Programming language (typescript, python, rust, go, etc.)",
        +        "type": "string"
        +      },
        +      "startLine": {
        +        "description": "First line number (1-indexed)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "stepNumber": {
        +        "description": "Step number label (auto-assigned if omitted)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "title": {
        +        "description": "Window title (default: 'step')",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "code",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "code"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "endLine": {
        +        "description": "Last line number (1-indexed, inclusive)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "filePath": {
        +        "description": "Absolute path to file (must be in SNAPMCP_ALLOWED_PATHS)",
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "label": {
        +        "description": "Optional label for this step",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "startLine": {
        +        "description": "First line number (1-indexed)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "stepNumber": {
        +        "description": "Step number label (auto-assigned if omitted)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "type": {
        +        "const": "file",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "filePath"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "fullPage": {
        +        "default": false,
        +        "description": "Capture full scrollable page",
        +        "type": "boolean"
        +      },
        +      "height": {
        +        "default": 800,
        +        "description": "Viewport height (px)",
        +        "maximum": 4096,
        +        "minimum": 240,
        +        "type": "integer"
        +      },
        +      "label": {
        +        "description": "Optional label for this step",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "stepNumber": {
        +        "description": "Step number label (auto-assigned if omitted)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "type": {
        +        "const": "browser",
        +        "type": "string"
        +      },
        +      "url": {
        +        "description": "URL to capture (http/https, SSRF protected)",
        +        "format": "uri",
        +        "type": "string"
        +      },
        +      "width": {
        +        "default": 1280,
        +        "description": "Viewport width (px)",
        +        "maximum": 3840,
        +        "minimum": 320,
        +        "type": "integer"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "url"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "label": {
        +        "description": "Optional label for this step",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "markdown": {
        +        "description": "Markdown content (GFM supported)",
        +        "maxLength": 200000,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "stepNumber": {
        +        "description": "Step number label (auto-assigned if omitted)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "title": {
        +        "description": "Document title (default: 'step')",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "markdown",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "markdown"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "html": {
        +        "description": "HTML content (external resources blocked)",
        +        "maxLength": 200000,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "label": {
        +        "description": "Optional label for this step",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "stepNumber": {
        +        "description": "Step number label (auto-assigned if omitted)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "title": {
        +        "description": "Description for logging (default: 'step')",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "html",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "html"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "diff": {
        +        "description": "Unified diff content (git diff format)",
        +        "maxLength": 500000,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "label": {
        +        "description": "Optional label for this step",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "stepNumber": {
        +        "description": "Step number label (auto-assigned if omitted)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "type": {
        +        "const": "diff",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "diff"
        +    ],
        +    "type": "object"
        +  }
        +]
      • removedInput schema / properties / steps / items / properties
        Removed value: -{
        -  "label": {
        -    "description": "Label for this step",
        -    "type": "string"
        -  },
        -  "params": {
        -    "additionalProperties": {},
        -    "description": "Parameters for the capture type",
        -    "propertyNames": {
        -      "type": "string"
        -    },
        -    "type": "object"
        -  },
        -  "stepNumber": {
        -    "description": "Step number label",
        -    "maximum": 9007199254740991,
        -    "minimum": 1,
        -    "type": "integer"
        -  },
        -  "type": {
        -    "enum": [
        -      "terminal",
        -      "code",
        -      "file",
        -      "browser",
        -      "markdown",
        -      "diff",
        -      "html"
        -    ],
        -    "type": "string"
        -  }
        -}
      • removedInput schema / properties / steps / items / required
        Removed value: -[
        -  "type",
        -  "params"
        -]
      • removedInput schema / properties / steps / items / type
        Removed value: -"object"
    • Changedcapture_terminal5 fields changed
      • changedInput schema / properties / lines / description
        Previous value: -"Lines to render. '$ ' prefix = command prompt, others = output"New value: +"Lines to render. Prefix command prompts with '$ ' (or '# ' for root) for syntax-colored prompts. Other lines are rendered as output. Maximum 1000 lines."
      • addedInput schema / properties / lines / maxItems
        Added value: +1000
      • changedInput schema / properties / output / description
        Previous value: -"Output filename (default: auto-generated)"New value: +"Output filename (default: auto-generated as 'terminal-<timestamp>.png' or '.jpeg' based on SNAPMCP_FORMAT). Include extension to override format."
      • changedInput schema / properties / title / description
        Previous value: -"Window title shown in the terminal title bar"New value: +"Window title shown in the terminal title bar (e.g., 'bash', 'zsh', 'git log')"
      • addedInput schema / properties / title / maxLength
        Added value: +100
    • Changedcapture_to_document9 fields changed
      • addedInput schema / properties / captures / description
        Added value: +"Array of captures to embed. Each specifies capture type, type-specific parameters, and optional caption."
      • addedInput schema / properties / captures / items / oneOf
        Added value: +[
        +  {
        +    "properties": {
        +      "caption": {
        +        "description": "Caption for this capture in the document",
        +        "maxLength": 200,
        +        "type": "string"
        +      },
        +      "lines": {
        +        "description": "Lines to render. Prefix with '$ ' for prompts.",
        +        "items": {
        +          "type": "string"
        +        },
        +        "maxItems": 1000,
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "title": {
        +        "description": "Window title (default: 'step')",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "terminal",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "lines"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "caption": {
        +        "description": "Caption for this capture in the document",
        +        "maxLength": 200,
        +        "type": "string"
        +      },
        +      "code": {
        +        "description": "Source code to render",
        +        "maxLength": 200000,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "endLine": {
        +        "description": "Last line number (1-indexed, inclusive)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "language": {
        +        "default": "text",
        +        "description": "Programming language (typescript, python, rust, go, etc.)",
        +        "type": "string"
        +      },
        +      "startLine": {
        +        "description": "First line number (1-indexed)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "title": {
        +        "description": "Window title (default: 'step')",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "code",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "code"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "caption": {
        +        "description": "Caption for this capture in the document",
        +        "maxLength": 200,
        +        "type": "string"
        +      },
        +      "endLine": {
        +        "description": "Last line number (1-indexed, inclusive)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "filePath": {
        +        "description": "Absolute path to file (must be in SNAPMCP_ALLOWED_PATHS)",
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "startLine": {
        +        "description": "First line number (1-indexed)",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "type": {
        +        "const": "file",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "filePath"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "caption": {
        +        "description": "Caption for this capture in the document",
        +        "maxLength": 200,
        +        "type": "string"
        +      },
        +      "fullPage": {
        +        "default": false,
        +        "description": "Capture full scrollable page",
        +        "type": "boolean"
        +      },
        +      "height": {
        +        "default": 800,
        +        "description": "Viewport height (px)",
        +        "maximum": 4096,
        +        "minimum": 240,
        +        "type": "integer"
        +      },
        +      "type": {
        +        "const": "browser",
        +        "type": "string"
        +      },
        +      "url": {
        +        "description": "URL to capture (http/https, SSRF protected)",
        +        "format": "uri",
        +        "type": "string"
        +      },
        +      "width": {
        +        "default": 1280,
        +        "description": "Viewport width (px)",
        +        "maximum": 3840,
        +        "minimum": 320,
        +        "type": "integer"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "url"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "caption": {
        +        "description": "Caption for this capture in the document",
        +        "maxLength": 200,
        +        "type": "string"
        +      },
        +      "markdown": {
        +        "description": "Markdown content (GFM supported)",
        +        "maxLength": 200000,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "title": {
        +        "description": "Document title (default: 'step')",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "markdown",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "markdown"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "caption": {
        +        "description": "Caption for this capture in the document",
        +        "maxLength": 200,
        +        "type": "string"
        +      },
        +      "html": {
        +        "description": "HTML content (external resources blocked)",
        +        "maxLength": 200000,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "title": {
        +        "description": "Description for logging (default: 'step')",
        +        "maxLength": 100,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "html",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "html"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "caption": {
        +        "description": "Caption for this capture in the document",
        +        "maxLength": 200,
        +        "type": "string"
        +      },
        +      "diff": {
        +        "description": "Unified diff content (git diff format)",
        +        "maxLength": 500000,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "type": {
        +        "const": "diff",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "diff"
        +    ],
        +    "type": "object"
        +  }
        +]
      • removedInput schema / properties / captures / items / properties
        Removed value: -{
        -  "caption": {
        -    "description": "Caption for this capture",
        -    "type": "string"
        -  },
        -  "params": {
        -    "additionalProperties": {},
        -    "description": "Parameters for the capture type",
        -    "propertyNames": {
        -      "type": "string"
        -    },
        -    "type": "object"
        -  },
        -  "type": {
        -    "enum": [
        -      "terminal",
        -      "code",
        -      "file",
        -      "browser",
        -      "markdown",
        -      "html",
        -      "diff"
        -    ],
        -    "type": "string"
        -  }
        -}
      • removedInput schema / properties / captures / items / required
        Removed value: -[
        -  "type",
        -  "params"
        -]
      • removedInput schema / properties / captures / items / type
        Removed value: -"object"
      • changedInput schema / properties / format / description
        Previous value: -"Output document format"New value: +"Output document format: markdown (image refs), html (self-contained), pdf (print-quality)"
      • changedInput schema / properties / includeTimestamps / description
        Previous value: -"Include timestamps in document"New value: +"Include capture timestamps in the document"
      • changedInput schema / properties / output / description
        Previous value: -"Output filename (default: auto-generated)"New value: +"Output filename (default: auto-generated as 'document-<timestamp>.md/.html/.pdf'). Extension should match format."
      • addedInput schema / properties / title / maxLength
        Added value: +200
    • Changedsnapmcp-hint2 fields changed
      • changedInput schema / properties / topic / description
        Previous value: -"Optional topic: init, doctor, browser, themes, output"New value: +"Topic for targeted help: init (interactive setup), doctor (diagnostics), browser (Chrome profile), themes (27 syntax themes), output (capture directory), security (SSRF/path config), gif (animations), document (multi-capture docs), batch (multi-capture calls)"
      • addedInput schema / properties / topic / enum
        Added value: +[
        +  "init",
        +  "doctor",
        +  "browser",
        +  "themes",
        +  "output",
        +  "security",
        +  "gif",
        +  "document",
        +  "batch"
        +]
  2. 13 tool updatesv2.3.2
    • First observedcapture_batch
    • First observedcapture_browser
    • First observedcapture_code
    • First observedcapture_diff
    • First observedcapture_file
    • First observedcapture_gif
    • First observedcapture_html
    • First observedcapture_markdown
    • First observedcapture_pdf
    • First observedcapture_sequence
    • First observedcapture_terminal
    • First observedcapture_to_document
    • First observedsnapmcp-hint

TDQS

A3.9/5.0

Scored across 13 tools

Disambiguation4/5

Most tools are clearly distinguished by input type and output format: markdown, code, terminal, URL, HTML, file, diff, and PDF each have distinct purposes. Minor overlap exists between capture_sequence and capture_gif (both involve sequential frame capture) and capture_markdown versus capture_html, but the descriptions generally provide enough context to avoid serious misselection.

Naming Consistency4/5

The dominant capture_<target> pattern is consistent and predictable across the majority of tools. The outlier snapmcp-hint breaks the convention, and capture_batch and capture_to_document use phrase-style names rather than simple noun targets, so the pattern is not perfectly uniform.

Tool Count5/5

With 13 tools, the server is well-scoped for a screenshot/capture domain: it covers individual capture formats plus sequence, batch, GIF, and document composition. Each tool has a reasonable place in the set, and the count is not bloated or thin.

Completeness5/5

The tool surface covers the full range of expected capture workflows: code, Markdown, HTML, terminal output, files, URLs, diffs, PDFs, and multi-step compositions. There are no obvious dead ends or major missing operations for the server's stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers