Commit Graph

4 Commits

Author SHA1 Message Date
SGavrl
24306be4f3 ci: harden pull request validation 2026-08-14 00:00:39 +00:00
SGavrl
084789a2d7 feat(render): ship capture surfaces
Enable rendering in release archives and Docker builds. Expose bounded PNG screenshots and raster PDF resources through render-enabled MCP servers.
2026-08-07 18:33:38 +00:00
SGavrl
171dba23e7 Feat/mcp agent skill tier1 (#215)
* feat(mcp): 10 new agent tools + element refs (12 -> 22 tools)

Brings obscura-mcp from a Playwright-style core (navigate/click/fill/
type/snapshot/wait_for/evaluate/select/press_key/network_requests/
console_messages/close) up to a full agent surface.

New tools:
- browser_markdown: render the page as Markdown (reuses the
  HTML_TO_MARKDOWN_JS converter behind `fetch --dump markdown`).
  Token-dense alternative to browser_snapshot.
- browser_links: every <a href> with anchor text, JSON-per-line.
  Optional internal_only and limit args.
- browser_interactive_elements: list every clickable / typeable
  element with a stable ref (e1, e2, ...) and a one-line label.
- browser_back / browser_forward / browser_reload: history nav,
  uses the Page history stack from the engine-tier1 commits.
- browser_get_cookies / browser_set_cookie / browser_clear_cookies:
  full cookie jar ops so an agent can skip a login flow when it
  already has a session token.
- browser_wait_for_text: wait for a substring to appear anywhere
  in the visible page text. Complements browser_wait_for which
  only checks for selectors.

Element refs (the playwright-mcp pattern, agent UX win):
- BrowserState now keeps an interactive_refs HashMap built on each
  browser_snapshot / browser_interactive_elements call.
- Each interactive element gets a data-obscura-ref="eN" attribute
  written into the DOM so refs survive across calls.
- browser_click / browser_fill / browser_type accept `ref` (preferred)
  or `selector` (fallback). Removes the agent's 'guess a CSS
  selector then retry' loop.
- Refs are cleared on every navigation / reload / back / forward / close.

Output size limits:
- browser_snapshot, browser_markdown accept max_chars (default 4000).
- browser_links, browser_interactive_elements accept limit (default 100).
- Truncated responses say '...(truncated, N more chars)' so the agent
  can ask for more if needed.

Verified end-to-end via /tmp/mcp-test.sh: tools/list returns 22 tools,
ref-based click on a real element works, markdown converts H1+P+UL
correctly, cookies round-trip. 28/28 integration tests pass.

* feat(mcp): 10 more agent tools, multi-tab, structured extract (22 -> 32 tools)

Tier 2: closes the gaps in agentic flows the Tier 1 surface still
needed multi-call workarounds for (login forms, paginated lists,
multi-step research across multiple destinations).

Multi-tab:
- BrowserState now holds a BTreeMap of tabs (Page per tab) with an
  active_tab cursor. page_mut() auto-creates a default tab so every
  legacy single-tab tool keeps working.
- browser_tab_new: open and optionally navigate.
- browser_tab_list: list all open tabs with active marker.
- browser_tab_switch: change which tab subsequent tools operate on.
- browser_tab_close: close (default: active tab), promotes another.

Form ergonomics:
- browser_detect_forms: returns each <form> with action, method, and
  every field's tag, type, name, current value, label (from <label for>
  or aria-label or placeholder), and option list for selects. Agents
  call this once to see the whole form shape instead of guessing
  selectors field by field.
- browser_fill_form: fill N inputs in one call. Each entry chooses
  type='text' (default value-set), 'check'/'uncheck', or 'select'
  (matches by value OR visible text). Optional submit_ref clicks
  after filling.

Structured extraction:
- browser_extract: pass {field: 'selector'} and get a JSON object back.
  Selector suffix '@attr' reads attribute (e.g. 'a@href'). Field
  suffix '[]' returns an array (queries all matches). One call returns
  the whole structured object instead of an evaluate per field.
- browser_count: existence / pagination probe.
- browser_get_attribute: read href / src / value / data-* etc.

Page control:
- browser_scroll: 'top'|'bottom'|'up'|'down'|'left'|'right' with
  optional amount, or scroll an element into view. Dispatches a real
  'scroll' event on window AND document so infinite-scroll handlers
  fire even though our viewport isn't a real layout.

Other:
- Bumped #![recursion_limit = "512"] because the tools/list JSON
  literal is now too big for the default macro recursion limit.
- browser_count: coerce f64 -> u64 since V8 numbers come back as floats.

Verified end-to-end: 32 tools registered, multi-tab open/list/switch/
close all work, detect_forms returns proper JSON, fill_form fills
text/check/select in one call, extract returns the structured object
with arrays and attribute reads. 28/28 integration tests pass.

* feat(mcp): search + storage state export/restore (32 -> 35 tools)

Three additions that close the long-tail agentic flows:

- browser_search: substring search in visible page text, returns each
  match with N chars of surrounding context (default 80). Lets an
  agent confirm content exists before scraping and locate a section
  without pulling the full page into its window. case_sensitive +
  limit + context_chars args.

- browser_storage_state: export the full auth surface (cookies +
  localStorage + sessionStorage for the current origin) as one JSON
  object. Agents stash this between runs to skip a login flow.

- browser_set_storage_state: apply a previously-exported state. Sets
  cookies via the cookie jar; writes localStorage / sessionStorage
  via evaluate on the current page (so a navigate to the right origin
  must come first).

Tool count: 35. 28/28 integration tests pass.
2026-05-31 23:21:07 +02:00
Jordi Llonch
bce055fd2a MCP support (#65)
* add mcp support

* add MCP docs to README

* wire up mcp subcommand in cli

* fix(stealth): propagate stealth feature to obscura-mcp
2026-05-13 21:38:10 +00:00