All docs

Score with the CLI

Score a tools/list file on your own machine with forecall lint, get it from your server with forecall dump, connect your AI clients to the Failure KB with forecall setup, and use them in CI.

On this page

forecall lint scores your tools with the same rules as the linter, on your own machine. It makes no network requests: no upload, no telemetry, no update check. To get the tools/list from your server, use forecall dump. The CLI needs Node.js 22 or later.

npx forecall lint tools.json

Input

Give one file, or - to read standard input:

cat tools.json | npx forecall lint -

The CLI reads the same shapes as the linter, with the same limits:

An array of tools
[{ "name": … }, …]
An object with a tools array
{ "tools": [ … ] }
A JSON-RPC response
{ "result": { "tools": [ … ] } }

Up to 1 MB (1,048,576 bytes) and 200 tools.

Keys must use the MCP wire format (camelCase). Keys in snake_case are reported with where they are and how to rename them, not converted. Get your tools/list shows how to get the file from your server.

Options

Option Meaning
--json Print the report as JSON, the same report the web app stores
--fail-under <n> Exit with 1 when the average score is below n (0 to 100)
--lang <en|ja> Language of the report (default: en)
-h, --help Show the help
-v, --version Show the version and the version of the scoring rules

The language is never taken from the environment (such as LANG), so a report reads the same on your machine and in CI.

Output

By default the CLI prints a report for people: the average score, the number of tools and of confusable pairs, and the version of the scoring rules; then the issues across the server; then each tool, lowest score first, with its six items and its issues. It uses colors only on a terminal, and never when NO_COLOR is set. Read your scores explains the items and the issue codes.

With --json, it prints the report the web app stores for a result, with lintVersion, the version of the scoring rules. When the input cannot be scored, it prints {"error": …} instead. Mistakes in the command line itself are printed as text on standard error.

Get the tools/list: forecall dump

forecall dump asks your MCP server for its tools/list and prints it as JSON that forecall lint and the linter accept. It is the only command that talks to the network: it starts the server you name, or connects to the URL you give.

# A stdio server: its command after --
npx forecall dump -o tools.json -- npx -y @modelcontextprotocol/server-filesystem .
# A Streamable HTTP server: its URL
npx forecall dump https://example.com/mcp --header "Authorization: Bearer $TOKEN" > tools.json
Option Meaning
-o, --output <file> Write the JSON to file instead of standard output
--header "Name: value" (URL) Send this request header, such as Authorization. Repeatable
--env NAME=value (command) Set this environment variable for the server, on top of your shell's environment. Repeatable
--cwd <dir> (command) Start the server in dir
--timeout <seconds> Give up after this many seconds (default: 60)

The JSON is {"tools": [...]} with server (the server's name and version), instructions when the server has them, and source: the command, or the URL without its query, and when it was taken. It never records headers or environment values. It reads every page of the list. When the result is over what Forecall scores (1 MiB, 200 tools), it says so on standard error.

Connect your AI clients: forecall setup

forecall setup connects the AI clients on your machine to the Failure KB, the MCP server at https://mcp.forecall.dev/mcp where agents look up known failures of MCP tools and the workarounds other agents verified. It needs an agent API key from the dashboard: it opens that page and asks you to paste the key, or takes --key fc_agent_.... The key is written into the clients' own configuration files only.

npx forecall setup
npx forecall setup --remove

For each client it finds, it adds the MCP server forecall to the client's configuration, puts the KB's instructions into the client's global instructions file between <!-- forecall:start --> and <!-- forecall:end -->, and, for Claude Code, offers a PostToolUse hook (forecall hook) that suggests a kb_lookup when an MCP tool of another server fails. The hook reads the event on standard input and sends nothing anywhere.

Client MCP server configuration Global instructions
claude-code ~/.claude.json; the hooks in ~/.claude/settings.json ~/.claude/CLAUDE.md
claude-desktop claude_desktop_config.json, through npx -y mcp-remote none
cursor ~/.cursor/mcp.json none: paste the printed block into Settings → Rules
codex ~/.codex/config.toml ~/.codex/AGENTS.md
gemini ~/.gemini/settings.json ~/.gemini/GEMINI.md
windsurf ~/.codeium/windsurf/mcp_config.json ~/.codeium/windsurf/memories/global_rules.md

With --sensor (never by default), setup also adds the sensor for Claude Code: a second PostToolUse hook (forecall hook --sensor) that Claude Code runs in the background after each MCP tool call of another server. It redacts the tool's result on your machine with the KB's own rules (secrets, addresses, paths, identifiers), cuts it to 2,000 characters, and sends it with the server's and the tool's names, the shape of the arguments (names, types and lengths, no values) and the client's name to https://mcp.forecall.dev/sensor, with the key in ~/.claude.json. The server redacts it again. It gives up after 2 seconds, prints nothing and does not count against your monthly units. Failures it sees that the KB does not know are reviewed by Forecall before they become records. setup --remove --sensor takes out only the sensor.

Running it again changes nothing; --remove takes everything out of every client. Without a terminal (CI, a pipe) and without --key, it prints what to do and exits with 0.

Option Meaning
--key <fc_agent_...> The agent key; otherwise asked for at the terminal
--client <name> Configure this client even if it is not found; repeatable
--hook / --no-hook Add, or do not add, the Claude Code hook; asked when omitted
--sensor Also add the sensor (above); with --remove, take out only the sensor
--remove Take everything setup added out of every client
--dry-run Show what would change and change nothing

Exit codes

Code Meaning
0 Scored (and, with --fail-under, the average is at least n); for dump, wrote the JSON
1 The average score is below --fail-under
2 Could not score: a wrong option, a missing or unreadable file, or invalid input; for dump, could not get the tools

Issues alone do not fail the command: short tools whose names already say what they do score low (see what static scoring cannot tell), so you decide where to draw the line.

In CI

To stop a CI job when the average drops, set --fail-under. Pin the minor version: every new version of the scoring rules comes with a new minor version of the CLI, so a pinned job keeps scoring by the same rules until you update it.

npx forecall@0.2 lint tools.json --fail-under 60

forecall --version prints the version of the CLI and of its scoring rules.

To keep each build's scores in the dashboard, send the tools/list to the REST API: see API keys and the REST API.