Skip to content

firecrawl_search.limit has been unconstrained since the search tool was introduced #376

Description

@lokicik

Describe the Bug

The firecrawl_search MCP tool advertises limit as an unconstrained JSON
number, but the Search API accepts only an integer from 1 through 100. MCP
clients therefore accept values that the runtime rejects downstream.

I found this while testing Firecrawl's MCP surface with an internal agent
compatibility system at Bottomless. The reproduction is model-free and
read-only.

To Reproduce

The current tools/list schema contains:

{"limit":{"type":"number"}}

Call firecrawl_search with any of these argument objects:

{"query":"site:example.com Example Domain","limit":0}
{"query":"site:example.com Example Domain","limit":1.5}
{"query":"site:example.com Example Domain","limit":101}

All three pass the advertised MCP schema and then fail with Invalid request body. The same search with limit: 1 succeeds.

Expected behavior

The MCP schema should expose the Search API's integer range so clients can
reject or correct these values before making the remote request.

Suggested Fix

The current field is defined here:

src/index.ts, line 822

limit: z.number().optional()

It could use:

limit: z.number().int().min(1).max(100).optional()

I traced the behavior through Main history. It has been present since
PR #4,
Feature/v1.2.0 search, merged on January 3, 2025 at commit
81605925f364dd21df139ae0b0f5623f0fbe61f8.

The PR's search implementation commit
82777b81cc23142777e475c1da3f7eea99fd4d3f
added fire_crawl_search with limit defined only as type: number. The PR's
base commit did not contain the search tool. This means the behavior was
present from the feature's introduction rather than being a later
passing-to-failing regression.

The same unconstrained field remained on Main when I rechecked it on August
20, 2026 at f16c1bcd7378efd5515c178e1e73238fb3c5e2de. I found no matching open or
closed issue or pull request.

A valid limit: 1 search and a separate scrape control both passed. If useful,
I can prepare a focused test and fix, then rerun the same contract check.

Screenshots

Not applicable.

Environment

  • Package: firecrawl-mcp@3.24.0
  • Source commit: f16c1bcd7378efd5515c178e1e73238fb3c5e2de
  • Transport: local stdio
  • Access mode: documented keyless local mode

Logs

Each invalid value returned the same MCP tool error:

Invalid request body

Additional Context

This was found with a model-free interface-contract check. The check compared
the advertised MCP schema with the live runtime response and used a valid
search plus a separate scrape as positive controls. All five cases completed,
the two controls passed, and cleanup was verified.

We are testing a system at Bottomless that runs repeatable MCP contract and
workflow checks, verifies the observed behavior directly, and can replay the
same checks when an MCP changes. We are trying to learn whether MCP teams would
want checks like this on future pull requests or releases. Would that be useful
to your team?

This is a schema-accuracy issue, not a security report.

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