Skip to main content
Glama

실제 터미널 색상, Shiki로 하이라이트된 코드, 시각적 diff, PDF 및 GIF — 하나의 MCP 서버, 13개의 도구, 무거운 의존성 제로. SSRF 보호는 기본적으로 켜져 있습니다. 브라우저를 조종하는 것만이 아니라 문서를 작성하는 에이전트를 위해 만들어졌습니다.

빠른 시작

세 단계, 2분 이내:

1. 설치

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

2. Claude Code에 추가 (~/.claude/claude.json)

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

3. 캡처

에이전트에게 자연어로 요청하세요:

"git log --oneline -5의 터미널 스크린샷과 src/index.ts의 구문 하이라이트 PNG를 캡처해 줘."

에이전트가 capture_terminal과 capture_file을 호출합니다 — 이미지는 ./captures/에 저장되며, 실제 터미널 테마와 선택한 구문 테마가 적용됩니다.

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

실제 모습

snapmcp로 생성된 실제 스크린샷:

캡처

미리보기

터미널 (실제 감지된 색상)

코드 (Shiki 구문)

Diff (녹색/빨간색)

마크다운 렌더링

snapmcp vs Playwright MCP

각자 다른 작업을 위한 다른 도구입니다. Playwright MCP는 토큰 효율적인 접근성 스냅샷을 통해 브라우저를 조종하고, snapmcp는 사람이 읽을 수 있도록 픽셀을 충실히 반영한 이미지를 렌더링합니다. 에이전트가 클릭해야 한다면 Playwright를 사용하세요. 보여줘야 한다면 snapmcp를 사용하세요.

사용 사례

snapmcp

Playwright MCP

실제 색상의 터미널 캡처

✅ Kitty, Gnome, Alacritty, WezTerm 테마 자동 감지

❌ 터미널 지원 없음

코드 → 구문 하이라이트 이미지

✅ Shiki, 50개 이상 언어, 27개 테마

❌ 그 목적이 아님

Git diff → 시각적 빨강/초록 이미지

✅ capture_diff

❌

URL → PDF 문서

✅ capture_pdf

❌

캡처에서 애니메이션 GIF 생성

✅ capture_gif (제로 의존성 gifenc)

❌

마크다운 → 스타일링된 문서

✅ capture_markdown, capture_to_document

❌

브라우저 페이지 스크린샷

✅ capture_browser (전체 페이지 또는 뷰포트)

✅

브라우저 자동화 (클릭, 입력, 이동)

❌ 스크린샷만 가능

✅ 접근성 트리 기반, 토큰 효율적 — 이 작업에 적합한 도구

대부분의 문서화 파이프라인은 둘을 함께 사용합니다: 상호작용은 Playwright MCP, 문서화는 snapmcp.

도구

도구

설명

capture_terminal

구문 색상 프롬프트가 있는 터미널 출력 (실제 터미널 테마 자동 감지)

capture_code

Shiki를 통한 구문 하이라이트 코드 (50개 이상 언어, 27개 테마)

capture_browser

전체 페이지 또는 뷰포트 스크린샷 (가능한 경우 시스템 Chrome 프로필 사용)

capture_file

파일 → 언어 자동 감지 → 하이라이트 스크린샷

capture_markdown

스타일링된 문서로 렌더링된 마크다운

capture_html

이미지로 렌더링된 임의의 HTML 스니펫

capture_diff

녹색 추가 / 빨간색 삭제가 있는 Git diff

capture_pdf

URL → PDF 문서

capture_batch

한 번의 호출로 여러 항목 일괄 캡처

capture_gif

여러 스크린샷에서 만든 애니메이션 GIF

capture_sequence

나란히 보여주는 애니메이션 시퀀스

capture_to_document

여러 섹션 마크다운 문서 렌더링

snapmcp-hint

MCP 클라이언트를 위한 서버 기능 힌트

사용 사례

자동화된 문서화 — 에이전트가 설정 가이드를 작성하고 실제 캡처를 삽입합니다: 설치 명령의 터미널 출력(실제 테마 적용), 구문 하이라이트된 설정 파일, 마이그레이션의 diff. 하나의 프롬프트, 세 번의 capture_* 호출, 마크다운 옆에 저장된 이미지.

시각적 QA — UI 변경 후 에이전트가 capture_browser로 영향을 받은 페이지를 캡처하고, capture_batch로 전후를 일괄 캡처한 다음, capture_gif로 애니메이션 비교를 만들어 PR 설명에 넣습니다.

터미널 가이드 — 스크린샷이 독자가 실제로 보게 될 화면과 일치해야 하는 CLI 튜토리얼: capture_terminal은 일반적인 어두운 사각형 대신 실제 프롬프트 색상을 재현합니다.

보안

SSRF 보호는 기본적으로 켜져 있습니다 — 별도로 설정할 필요가 없습니다.

기능

설명

SSRF 보호

기본적으로 켜짐 (SNAPMCP_SSRF_PROTECTION=false로 비활성화). IP 리터럴(v4 + v6), localhost 변형, 그리고 사설 대역으로 해석되는 DNS 이름을 차단합니다 (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7, fe80::/10 등); 모든 페이지 요청(리다이렉트 포함)은 다시 검사됩니다

파일 허용 목록

SNAPMCP_ALLOWED_PATHS는 설정되지 않으면 기본적으로 모두 거부; 명시적으로 허용된 경로만 캡처할 수 있습니다

경로 탐색 방지

../ 이스케이프, 심볼릭 링크 탐색(realpath 통해), 널 바이트 주입을 방지합니다

입력 제한

터미널 1000줄; 코드/마크다운/HTML 200KB; diff 500KB; 파일 읽기 5MB; 최대 GIF 프레임 60; 최대 GIF 캔버스 8192×8192

감사 로그

타임스탬프가 있는 이벤트를 기록하는 선택적 구조화된 JSON 로그 파일

Chromium 샌드박스

시작 시 샌드박스 사용 가능 여부 확인

구성

MCP 서버용 환경 변수:

Variable

기본값

설명

SNAPMCP_DIR

./captures

캡처 출력 디렉터리

SNAPMCP_THEME

자동 감지

구문 테마 (27개 내장 테마 + 자동 감지 터미널)

SNAPMCP_FORMAT

png

출력 형식 (png, jpeg)

SNAPMCP_QUALITY

90

JPEG 품질 (1-100)

SNAPMCP_PADDING

32

콘텐츠 패딩(픽셀)

SNAPMCP_SHADOW

none

드롭 섀도우 (none, soft, medium, strong; 별칭 sm/md/lg)

SNAPMCP_WINDOW_CHROME

false

macOS 스타일 제목 표시줄 프레임

SNAPMCP_BORDER_RADIUS

0

창 모서리 반경

SNAPMCP_BADGE

false

바닥글 배지

SNAPMCP_LOG_FILE

—

감사 로그 파일 경로

SNAPMCP_CHROME_EXECUTABLE

—

Chrome/Chromium 바이너리 경로

SNAPMCP_CHROME_CHANNEL

—

Chrome 채널 (stable, beta, dev, canary)

SNAPMCP_CHROME_PROFILE

—

Chrome 프로필 디렉터리 이름

SNAPMCP_ALLOWED_PATHS

(모두 거부)

capture_file에 허용되는 파일 경로(쉼표 또는 세미콜론으로 구분)

27개 내장 Shiki 테마: 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는 MCP 서버 외에도 완전한 CLI를 제공합니다:

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

문서

페이지

내용

Getting Started

설치, 빠른 시작, MCP 클라이언트 설정

Tools Reference

13개 도구와 매개변수 및 예시

Configuration

모든 SNAPMCP_* 환경 변수, 테마, 기본값

CLI Reference

Init, doctor, test 명령

Guides

터미널 캡처, 브라우저 캡처, GIF 애니메이션

ARCHITECTURE.md

모듈 맵, 데이터 흐름, 보안 아키텍처

CONTRIBUTING.md

개발 워크플로우, 테스트 가이드라인, PR 체크리스트

개발

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

요구 사항: Node.js ≥ 20 또는 Bun ≥ 1.2. CI는 GitHub Actions를 통해 ubuntu / macOS / windows에서 실행됩니다.

라이선스

MIT — 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