Skip to content

firecrawl_search declares readOnlyHint: true but accepts scrapeOptions.actions (click/write/executeJavascript) #311

Description

@dilansri

Hello, I maintain actlint, a static linter that checks MCP tool annotations against what their input schemas allow.

The observation

On firecrawl-mcp@3.22.3, firecrawl_search declares readOnlyHint: true, but its input schema includes scrapeOptions.actions with action types click, write, press, and executeJavascript. As declared, the tool can fill and submit forms and run arbitrary JS on the pages it visits, while carrying the hint that lets a spec-conformant client skip its confirmation prompt (MCP spec on annotations).

The other tools with the same actions parameter (firecrawl_scrape, firecrawl_crawl, firecrawl_interact) all declare readOnlyHint: false. Search is the only one that says true, so most likely the annotation predates search gaining scrapeOptions.actions. It is accurate for the plain search path, and the README's search section doesn't document actions either.

Possible fixes

Roughly in order of thoroughness: split the action-driving path into a separate non-read-only tool, constrain or remove actions on the search tool's schema, or set readOnlyHint: false to match firecrawl_scrape.

To verify

Without taking my word for it: list the server's tools and compare firecrawl_search's annotations.readOnlyHint against its inputSchema (the scrapeOptions.actions[].type enum is ["wait","screenshot","scroll","scrape","click","write","press","executeJavascript","generatePDF"]).

Or run actlint, which reads tools/list only and never invokes a tool.

npx actlint npx firecrawl-mcp
npx actlint explain write-as-readonly

Expected result: one HIGH write-as-readonly finding on firecrawl_search, the other 25 tools clean.

Notes

I'm putting together a blog post on MCP annotation accuracy that mentions this, planned for 19 July 2026, and didn't want it to reach the repo second-hand. If it gets fixed or clarified before then, the post will say so. And if I've misread the tool, that's a bug in actlint and I'd genuinely like to know.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions