Skip to content

fix(mcp): load hosted scrape and search profiles without saving - #494

Merged
erikengervall merged 2 commits into
mainfrom
noaa/hosted-read-only-profiles
Oct 6, 2026
Merged

erikengervall merged 2 commits into
mainfrom
noaa/hosted-read-only-profiles

Conversation

@erikengervall

@erikengervall erikengervall commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Why

Hosted firecrawl_scrape and firecrawl_search are annotated readOnlyHint: true, but they can still write state. A named browser profile saves its changes, because the API defaults profile.saveChanges to true and both tools forward saveChanges as given. The main scrape description also still says "Browser actions can change the live page when interactive actions are enabled", though the hosted schema has no actions.

The ChatGPT plugin scan flags both tools for this: "This tool is marked readOnlyHint: true, but its behavior appears to have a user-visible side effect."

This reinstates the profile guard from the first revision of #472, which was later narrowed to provider terms only. The README already says a hosted profile "loads saved browser state without saving changes to it", so this makes the code match the docs.

Summary

  • In safe mode, the scrape profile and the search scrapeOptions.profile take only a name, and the server always sends saveChanges: false.
  • A call shaped by an older tool definition that still sends saveChanges: true loads the profile and saves nothing. It doesn't error.
  • The full-surface and search-surface scrape descriptions say a profile loads without saving. The browser-actions sentence stays in local mode only.
  • Local mode, firecrawl_crawl and firecrawl_interact keep their existing profile contract. The README again points to firecrawl_interact for saving browser state.
  • storeInCache is unchanged, because setting it to false is the caller's way to opt out of caching.

Test Plan

  • pnpm test: 171/171 pass.
  • tests/mcp-read-only-scrape.test.mjs fails on main and passes here. It checks that the hosted scrape and search profile schemas take only name, that saveChanges: false is forwarded even when the caller sends true, the descriptions on both surfaces, and that local scrape keeps saveChanges.
  • pnpm exec tsc --noEmit, pnpm exec eslint src/index.ts and git diff --check pass.

Summary by cubic

Fixes hosted firecrawl_scrape and firecrawl_search so named browser profiles on the read-only hosted surface load saved state without writing changes back. The API defaults saveChanges to true, so the server now forces saveChanges: false for these profiles.

Behavior

  • The hosted profile schema accepts only name; calls shaped by older tool definitions that still send saveChanges load the profile but save nothing.
  • Local mode, firecrawl_crawl, and firecrawl_interact keep their existing profile contract; firecrawl_interact remains the way to save browser state.
  • Descriptions, README, and search-profile docs now say hosted profiles load without saving; the README scopes the firecrawl_search note to the full endpoint.

Written for commit c61b02c. Summary will update on new commits.

Review in cubic

Hosted firecrawl_scrape and firecrawl_search are annotated readOnlyHint: true,
but a named browser profile still saved its changes: the API defaults
profile.saveChanges to true, and both tools forwarded saveChanges as given.
The scrape description also still said browser actions can change the live
page, though the hosted schema has no actions.

In safe mode, the scrape profile and the search scrapeOptions profile now take
only a name, and the server always sends saveChanges: false. A call shaped by
an older tool definition that still sends saveChanges loads the profile and
saves nothing. Both scrape descriptions say a profile loads without saving.
Local mode, crawl and interact keep their existing profile contract, and
interact remains the way to save browser state.

Co-Authored-By: Claude <noreply@anthropic.com>
@erikengervall
erikengervall requested review from Max17190 and rakshith48 and removed request for Max17190 October 6, 2026 00:47

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 4 files

Auto-approved with 1 open P3 issue: Fixes hosted read-only scrape/search so named profiles load without saving by restricting profile to name and forcing saveChanges:false; updates docs/descriptions and adds tests. Bounded bug fix aligning code with documented read-only behavior.

Fix all with cubic | Re-trigger cubic

Comment thread README.md Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auto-approved with 1 open P3 issue.

Co-Authored-By: Claude <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 1 file (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Auto-approved: Fixes hosted scrape/search to load named profiles without saving by forcing saveChanges:false in safe mode, while keeping local mode and firecrawl_interact unchanged. The change is bounded, backward-compatible, and covered by updated tests and docs.

Re-trigger cubic

@erikengervall
erikengervall merged commit 6a58e3b into main Oct 6, 2026
2 checks passed
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.

2 participants