Skip to content

fix(mcp): preserve viewport screenshot size by default - #2916

Merged
Nikhil (shadowfax92) merged 2 commits into
mainfrom
feat/fix-screenshot-size
Oct 13, 2026
Merged

Nikhil (shadowfax92) merged 2 commits into
mainfrom
feat/fix-screenshot-size

Conversation

@shadowfax92

@shadowfax92 Nikhil (shadowfax92) commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The screenshot tool no longer silently shrinks an omitted size into 1024x768. Rust and TypeScript now capture the current CSS layout viewport with clip.scale = 1; explicit bounds keep the aspect ratio and never upscale.

- omitted size -> implicit 1024x768 box
+ omitted size -> current viewport, scale 1
+ partial size -> constrain only the supplied axis

Sizing decisions:

  • CSS layout metrics define the captured region. Preserve CDP's native device pixel density rather than resampling Retina output: scale 1 returned 2880x1800 for a 1440x900 viewport at DPR 2. This retains rendered detail and the existing explicit-size behavior. A size box therefore caps CSS dimensions; encoded dimensions include device density. The tool descriptions and clip comments make that distinction explicit.
  • Width and height are independently optional. Width-only constrains width; height-only constrains height; {} is uncapped. Supplied dimensions retain the 1..4096 validation. Removed Rust Default, default_width/default_height, and the TS default-size constant.
  • fullPage retains its existing capture path and ignores size. The Rust SDK/run helper delegates to the same screenshot tool; its instructions now state the rule. The TS server agrees, and a repository search found no other documentation/skills advertising the old default.

The CDP viewport contract defines CSS/DIP geometry; the image dimensions below were measured from actual returned PNG bytes.

Evidence

Before: the existing screenshot-tool regression expected scale 1 for a 2048x1536 viewport and failed with scale 0.5. After: it passes with scale 1.

Built this worktree's browseros-claw-server-rs, connected it over MCP stdio to running BrowserOS neo (Chrome/155.0.8311.26), and called screenshot four ways in a task-owned background fixture tab. Explicit box: 1024x768; width-only: 1024; fullPage also passed width 1 to verify it is ignored. DPR 2 was emulated only on that target; the attached display was DPR 1.

Call CSS viewport DPR Image pixels
omitted 1440x1800 1 1440x1800
size 1440x1800 1 614x768
width-only 1440x1800 1 1024x1280
fullPage 1440x1800 1 1440x2421
omitted 1440x1800 2 2880x3600
size 1440x1800 2 1229x1536
width-only 1440x1800 2 2048x2560
fullPage 1440x1800 2 2880x4842

All captures left innerWidth, innerHeight, DPR and scroll offsets unchanged. fullPage used size.width=1 and matched the unchanged direct-CDP full-page baseline. DPR 2 is emulated on this task-owned target; the attached display is DPR 1.

  • cargo check -p browseros-mcp
  • cargo clippy -p browseros-mcp --all-targets -- -D warnings
  • cargo test -p browseros-mcp: 119 unit and 4 integration tests passed.
  • cargo build -p claw-server
  • bun run check: passed; existing non-fatal lint/Fallow warnings remain.
  • bun run test: initial complete suite passed (2144 tests), including the 18-case real-browser MCP smoke suite. After integrating current main, the only local failure was an unchanged model-picker test exceeding its five-second timeout. That test and both screenshot regression files passed with bun test --timeout 30000 (66 tests); no unrelated source was changed.
  • All CI test suites and quality checks passed on integrated head 76cb765639753cd582da0bfa2b8f630262ad473b. Rust checks, build, and all eight live captures were repeated after integration and passed.
  • git diff --check
  • One independent Codex review; vetted result recorded in the task artifacts.

Merge Danger

Door: two-way, reversible by reverting this change.
Blast Radius: Rust/TS MCP screenshots and the Rust SDK helper. Omitted/partial sizes can produce larger images; clients wanting the old cap can explicitly pass both dimensions. JPEG quality, formats, and full-page capture are unchanged.

@github-actions github-actions Bot added the fix label Oct 13, 2026
@greptile-apps

greptile-apps Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no actionable issues were found.

Summary

Rust and TypeScript screenshots now preserve the current CSS viewport by default.

  • Screenshots keep their current size unless a caller adds a cap.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Screenshot request] --> B{fullPage?}
  B -->|Yes| C[Existing full-page capture; no clip]
  B -->|No| D[Read CSS layout viewport]
  D --> E[Start with scale 1]
  E --> F[Reduce scale for supplied size axes]
  F --> G[Capture unchanged viewport region]
  C --> H[Return inline image]
  G --> H
Loading

Reviews (1) · Last reviewed commit: "fix(mcp): preserve viewport screenshot s..." · Reviewed by Greptile

@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

✅ Tests passed: 2474/2477

Ran 11 of 16 suites (5 not affected by this change).

Suite Passed Failed Skipped
✅ server-agent 216/216 0 0
✅ server-api 289/289 0 0
✅ server-tools 256/256 0 0
✅ server-browser 10/10 0 0
✅ server-integration 10/10 0 0
✅ server-lib 199/199 0 0
✅ server-root 38/41 0 3
✅ agent 372/372 0 0
⏩ claw-app n/a n/a not affected
⏩ claw-onboard n/a n/a not affected
⏩ app-onboard n/a n/a not affected
⏩ build n/a n/a not affected
⏩ release n/a n/a not affected
✅ claw-server 932/932 0 0
✅ claw-server-quality passed 0 0
✅ claw-mcp 152/152 0 0

passed = ran successfully but emits no JUnit counts (a lint/format gate).

View workflow run

@shadowfax92
Nikhil (shadowfax92) merged commit b1c9bb1 into main Oct 13, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant