Skip to content

firecrawl_scrape: published inputSchema declares jsonOptions.schema as an object that admits no keys, breaking JSON extraction for schema-validating MCP clients #373

Description

@hunu-the-brain

Summary

The inputSchema that firecrawl-mcp publishes via tools/list declares
firecrawl_scrape's jsonOptions.schema field as:

{
  "type": "object",
  "propertyNames": { "type": "string" },
  "additionalProperties": false
}

There is no properties declaration, so under JSON Schema semantics this
accepts only the empty object. But this field is where callers pass an
arbitrary JSON Schema describing the extraction output — any legitimate value
necessarily contains keys like type, properties, required, all of which
this declaration rejects.

Any MCP client that validates call arguments against the published
inputSchema before forwarding (a common pattern for gateway/proxy-style
clients) therefore rejects every JSON-extraction call with:

Additional properties are not allowed ('properties', 'required', 'type' were unexpected)

The server itself accepts these calls fine (its internal zod validation treats
the field as a record), so the bug only surfaces in clients that trust the
published schema — which makes it look like a client-side failure. In our
deployment (an MCP gateway serving ~400 workspaces) this rejected 100% of
formats: ["json"] + jsonOptions.schema calls, ~250 failures across 19
users before we traced it back here.

The same signature (propertyNames + additionalProperties: false, no
properties) appears on several other free-form object fields in the
published schemas as well (we count 10 occurrences across the tool list);
firecrawl_scrape.jsonOptions.schema is just the most user-visible one.

Reproduction

export FIRECRAWL_API_KEY=fc-anything   # not needed for tools/list
npx -y firecrawl-mcp

Then over stdio:

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"0.0.1"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}

Inspect result.tools[] → name == "firecrawl_scrape" → inputSchema.properties.jsonOptions.properties.schema — it is the unsatisfiable
declaration above.

Validating a perfectly normal call against the published schema fails:

from jsonschema import Draft202012Validator

published_json_options = {
    "type": "object",
    "properties": {
        "prompt": {"type": "string"},
        "schema": {"type": "object", "propertyNames": {"type": "string"},
                   "additionalProperties": False},
    },
    "additionalProperties": False,
}
valid_call = {
    "prompt": "Extract the product title.",
    "schema": {"type": "object", "required": ["title"],
               "properties": {"title": {"type": "string"}}},
}
Draft202012Validator(published_json_options).validate(valid_call)
# jsonschema.exceptions.ValidationError:
# Additional properties are not allowed ('properties', 'required', 'type' were unexpected)

Expected

jsonOptions.schema should be published as a free-form object, e.g.
{"type": "object"} (or {"type": "object", "additionalProperties": true}),
matching what the server actually accepts.

Likely cause

The shape {"type":"object","propertyNames":{"type":"string"}, "additionalProperties":false} looks like a zod z.record(z.string(), ...)
whose value schema was lost during the zod → JSON Schema conversion, leaving
additionalProperties collapsed to false instead of the value schema (or
true).

Environment

  • firecrawl-mcp 3.24.0 (serverInfo.name: "firecrawl-fastmcp"), via npx -y firecrawl-mcp, stdio transport
  • Observed identically in registry snapshots taken since at least 2026-07-19

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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