Skip to content

feat(mcp,cdp): lint_page_html tool with static HTML parser (#79) - #222

Merged
aram-devdocs merged 4 commits into
mainfrom
claude/issue-79-lint-page-html
May 6, 2026
Merged

feat(mcp,cdp): lint_page_html tool with static HTML parser (#79)#222
aram-devdocs merged 4 commits into
mainfrom
claude/issue-79-lint-page-html

Conversation

@aram-devdocs

Copy link
Copy Markdown
Owner

Closes #79.

Summary

  • Add plumb_cdp::snapshot_from_html(html, base_url) — a pure parser pass over scraper::Html that materializes a PlumbSnapshot without launching Chromium. Capped at 1 MiB of input and 10 000 elements; oversized inputs return typed CdpError::HtmlInputTooLarge / HtmlElementLimitExceeded.
  • Add the lint_page_html MCP tool ({ html, base_url } in, MCP-compact response shape out). Empty arguments and oversized inputs surface as JSON-RPC invalid_params (-32602).
  • Bump docs/src/mcp.md tool table to list the new tool.

The static-HTML path has no rendering, so computed_styles is empty and rect is None; the tool catches structural rules but not rendering-dependent ones — documented in the tool description and in docs/src/mcp.md.

Test plan

  • cargo test -p plumb-cdp --lib snapshot_from_html — 4 unit tests (canonical shape, byte-deterministic, byte-cap refusal, element-cap refusal).
  • cargo test -p plumb-mcp --test mcp_protocol lint_page_html — 3 protocol tests (happy path, empty html, byte-cap).
  • cargo test -p plumb-cli --test mcp_stdio mcp_initialize_and_tools_list — stdio test asserts lint_page_html in tools/list with the expected inputSchema.
  • cargo clippy --workspace --all-targets — zero warnings.
  • cargo deny check — advisories / bans / licenses / sources all OK.

🤖 Generated with Claude Code

aram-devdocs and others added 4 commits May 6, 2026 02:32
Adds `plumb_cdp::snapshot_from_html(html, base_url)` and the matching
caps `SNAPSHOT_FROM_HTML_INPUT_BYTE_CAP` (1 MiB) and
`SNAPSHOT_FROM_HTML_ELEMENT_CAP` (10 000), plus two new `CdpError`
variants (`HtmlInputTooLarge`, `HtmlElementLimitExceeded`).

The function builds a `PlumbSnapshot` from a static HTML string with
no Chromium launch, no JavaScript execution, and no resource fetching
— a pure parser pass over `scraper::Html`. `computed_styles` is empty
and `rect` is `None` because there is no rendering pipeline available
from a static document; the rest of the snapshot mirrors what
`PlumbSnapshot::canned` produces.

Unit tests cover the canonical html/head/body shape, byte-deterministic
output across two calls, the byte-cap refusal, and the element-cap
refusal.

Refs #79.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the `lint_page_html` MCP tool — `{html, base_url}` in, the same
MCP-compact response shape as `lint_url` out, no Chromium launch. The
handler delegates to `plumb_cdp::snapshot_from_html`, runs the rule
engine, and returns through `build_lint_url_result` so token-budget
guarantees match `lint_url` (compact-only; the static-HTML path has no
rendered styles or geometry that the full envelope could enrich).

Empty `html`, empty `base_url`, and oversized inputs (above the 1 MiB
byte cap or 10 000 element cap enforced by `snapshot_from_html`) all
surface as JSON-RPC `invalid_params` (-32602) so a chatty agent can
react without parsing the underlying `CdpError`.

Protocol tests cover the happy path (compact payload shape), the
empty-`html` invalid-params case, and the byte-cap invalid-params case.

Refs #79.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extends the existing `mcp_initialize_and_tools_list` end-to-end stdio
test to assert that `lint_page_html` shows up in `tools/list`, that
its `inputSchema` declares `html` and `base_url` as string properties,
and that both fields are listed under `required`. Also adds the tool
to the user-facing tool table in `docs/src/mcp.md`.

Refs #79.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…page-html

# Conflicts:
#	crates/plumb-cdp/Cargo.toml
#	crates/plumb-mcp/src/lib.rs
#	crates/plumb-mcp/tests/mcp_protocol.rs
@aram-devdocs
aram-devdocs merged commit 9a2efe9 into main May 6, 2026
12 of 14 checks passed
@aram-devdocs aram-devdocs mentioned this pull request May 6, 2026
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(mcp): lint_page_html tool

1 participant