Add server info, idempotent hints and input descriptions

Closed
JU
4d ago
+1644-650

Hey, I'm Juampi from the Firecrawl team. MCP directories and quality scanners (Manufact's catalog score is the one that prompted this) read the server's handshake metadata and each tool's input documentation, and ours was thin. Our hosted server scored 84/100 there, mostly because of three gaps: the server sends no title, description, website or icon; only find_tools declares idempotentHint; and most inputs of firecrawl_scrape, firecrawl_search and firecrawl_parse have no description.

This PR fills those in. It changes no tool, input name, default, output or behaviour.

Changes

  • patches/fastmcp@4.3.2.patch: fastmcp builds the initialize result with only name and version, so the existing patch now also accepts title, description, websiteUrl and icons server options. title, websiteUrl and icons use the same names as upstream fastmcp, so the hunks drop out on upgrade. description is not upstream. pnpm-lock.yaml only gets the new patch hash.
  • src/server.ts: sets those four fields next to name (name stays firecrawl-fastmcp, origin attribution keys on it).
  • idempotentHint on every tool (src/server.ts, monitor.ts, research.ts, developer.ts, gov.ts, usage.ts, service/search-surface.ts). true for lookups, search, map, parse, status checks and the monitor/interact operations that are safe to repeat; false for tools that start a crawl, agent, monitor run or interact session or record feedback. firecrawl_scrape follows safe mode: true on the hosted surface, false outside it because browser actions exist there.
  • Input descriptions for firecrawl_scrape, firecrawl_parse and firecrawl_search (src/server.ts, src/tool-helpers.ts, src/alexandria.ts). Defaults were checked against the API source and docs. Where an input does nothing on a tool (parse storeInCache, parse proxy, search scrapeOptions.maxAge), the description says so. Search reuses the scrape option descriptions through scrapeOptions; crawl and interact say "Same fields as firecrawl_scrape." instead of repeating them, to keep tools/list small.
  • Contract snapshots regenerated, CHANGELOG.md entry, version bump to 3.30.2 in package.json, server.json and gemini-extension.json.
  • tests/server-info-and-schema-docs.test.mjs: pins the four server fields, idempotentHint on every tool, and description coverage for every input of the three tools.

Heads up

  • tools/list grows by about 12 KB on the full surface (94.5 to 107 KB, 28 tools) and about 10 KB on the hosted surface, all of it descriptions.
  • Merging bumps package.json, so publish.yml releases 3.30.2 to npm.
  • mcp.firecrawl.dev runs from firecrawl-mcp-service, which vendors a tarball of this package. The hosted score only moves once that is re-vendored and redeployed. The service's own src/service/search-surface.ts also needs idempotentHint: true on the hosted search tool, as a separate change there.
  • Open PRs #535, #536, #537 and #518 also regenerate the contract snapshots, so whichever merges second needs to regenerate them.

How I tested it

  • pnpm install --frozen-lockfile, pnpm run build, pnpm test: 171/171 pass (168 on main plus the 3 new tests), on a fresh clone as well.
  • Compared tools/list and initialize between main and this branch on all 8 contract surfaces. With descriptions and idempotentHint removed, the input and output schemas are identical, and tool descriptions, names, order and counts are unchanged.
  • Live runs with a real Firecrawl key over stdio and streamable HTTP, and with CLOUD_SERVICE=true: scrape (markdown, JSON, screenshot, waitFor, location, maxAge: 0), search (limit, tbs, location), parse against a mock API. Results match main. A request without a credential on the hosted setup still gets a 401.
  • About 50 invalid-input calls per build (bad URL, negative waitFor, limit 0 and 1000, unknown format and proxy, url plus alexandria) return identical errors, and the requests sent upstream are byte-identical.
  • The official MCP SDK client connects and parses the new server fields on stdio and HTTP.
  • Re-ran Manufact's published checks against the built hosted surface: 100% of scrape, search and parse inputs are documented, idempotentHint is on every tool, and the metadata fields are all present. I expect the hosted score to land in the mid-nineties after the redeploy; I have not seen the real number yet.