Troubleshooting

Every part of the FlyDocs tool surface fails quietly. flydocs doctor --tools makes each failure visible, keyed by stable check IDs.

Every part of the FlyDocs tool surface fails quietly. A registration with the wrong command is a server your editor never spawns. A missing permission block is an approval prompt on every operation, usually blamed on the agent being annoying. A stale interpreter record is a bridge falling back to a bare python3, which is wrong on Windows. None of that prints an error anywhere.

So the first move is always the same:

Terminal
flydocs doctor --tools

Every check has a stable ID — mcp.registration.claude, permissions.block, run.interpreter. This guide is organised by those IDs, because they are what the report gives you and what a CI log can be grepped for. --json emits the same results as one document; --fix repairs what FlyDocs owns and re-runs every check.


Symptom → Check

What you see Check first
No FlyDocs tools in the editor at all mcp.registration.*, mcp.command, mcp.server
Tools listed but every call fails mcp.command, runtime.python
An approval prompt on every FlyDocs action permissions.block, permissions.settings
Your hooks stopped firing too permissions.settings
A tool call opened interactive onboarding (old CLI) mcp.command
flydocs run says it does not know an operation run.registry, run.dry-run
flydocs run cannot start anything run.interpreter
A skill's operations are missing from --list run.registry
Everything is checked against the wrong directory surface.scope

Tools Not Showing Up

The single most common cause is that the editor has not been restarted. MCP registrations are read at startup. If a flydocs update just ran, restart the editor before anything else. In Cursor, also confirm the server is toggled on under Settings → Cursor Settings → MCP — a newly registered project server needs a one-time enable.

After that, walk the chain in this order — each check answers a different question, and fixing them out of order wastes time.

  1. mcp.registration.claude / mcp.registration.cursor — does the client's registration file name flydocs mcp?
    • Missing file or missing entry: the client has nothing to spawn. Run flydocs doctor --tools --fix (or flydocs update). Only the flydocs key is touched.
    • Stale: the entry exists but points somewhere else — an older command spelling, or an absolute path from a previous install. The same fix replaces it.
    • Foreign entry (a warning, not a failure): there is a flydocs entry that FlyDocs did not write. It is left alone, deliberately, because it may be yours. Remove it yourself, or re-run with the entry deleted.
    • Unparseable: the file has a syntax error. FlyDocs will not overwrite it — it may hold the rest of your team's servers. Fix the JSON and re-run.
  2. mcp.command — is flydocs on PATH, and new enough to serve mcp? Your editor spawns the command by name; a registration is worthless if the command resolves to something that cannot serve it. See Stale global CLI below.
  3. mcp.server — does this build's server actually answer? The check drives the shipped server over a real transport and completes the handshake your editor performs. A failure here is not a configuration problem: re-install the CLI (npm i -g @flydocs/cli@latest), and if it persists capture flydocs mcp --verbose output and send it to support@flydocs.ai.
  4. surface.scope — which directory was examined? In a multi-repo workspace, registrations live in each repo and at the root; the report names the directory it checked, so a green report against the wrong directory is visible rather than misleading.

If all four pass and the editor still shows nothing, check that the client is reading project-scoped servers at all — some clients require you to approve a newly-registered project server once, in their own UI.

A related warning: mcp.tools-budget

This never blocks anything. It reports the size of the tool listing a deferring client carries before any tool is used, against the budget. Over budget is a warning about context cost, not about function.


Permissions Still Prompting

If the agent asks for approval every time it calls a FlyDocs tool or runs flydocs run, the standing rules are not in effect.

  1. permissions.settings first. If .claude/settings.json does not parse, Claude Code silently ignores the whole file — permissions and hooks. That is almost always the real story when several unrelated things stop working at once. FlyDocs never overwrites this file; fix the syntax error yourself and re-run.
  2. permissions.block. A failure means the managed block is absent or out of date. The check attaches a preview: the exact lines that would move, computed without writing anything. Apply it with flydocs doctor --tools --fix, or by running flydocs update. The previous file is backed up under .claude/.flydocs-backup/ first.

Two cases that look like bugs and are not:

  • A repo installed by an older CLI reports permissions.block as failing. An install predating the ownership record gains it on its first flydocs update — run that (or flydocs doctor --tools --fix) and the check passes. The two standing rules were already present from the template, so tools worked meanwhile.
  • The policy is off. Then the check passes with "nothing is managed here", and any prompting is your own settings' business. See Managed Permissions.

If the block is present and current and you are still prompted, confirm which file the policy targets: target: userGlobal writes ~/.claude/settings.json, not the repo's. The check reports the path it evaluated.


Stale Global CLI

Symptom: tools appear and then fail, or mcp is reported as an unknown command. On a CLI old enough to predate the router fix, an unknown command fell through to interactive onboarding instead — so a tool call could hang waiting on a prompt with no terminal to answer it.

Cause: the flydocs your editor spawns is not the flydocs you think it is. The registration deliberately says flydocs, not an absolute path — so it follows PATH, the same way every other invocation does. mcp.command is the one place that question is asked:

  • flydocs is not on PATH (warning): install it globally, npm i -g @flydocs/cli, so the registered command resolves at all.
  • PATH resolves a version older than the one that introduced flydocs mcp (failure): update the global install — flydocs self-update, or npm i -g @flydocs/cli@latest (1.3.4 at the time of writing). Until then every registration on this machine spawns a CLI without the server command.
  • PATH resolves a different version than the build being diagnosed (warning): usually a linked development build alongside a global install. Your editor will spawn the PATH copy, not the one you just ran.

Note that mcp.command reads doctor's PATH. An editor spawns with its own environment, which on macOS in particular can differ from your shell's — if doctor is happy and the editor is not, compare the two.


flydocs run Problems

  • run.registry — the operation registry and the bundled entrypoints load. A failure means the workflow scripts are missing or unreadable: run flydocs update to restore them. A warning means a skill's operations.json was rejected; the message names the first problem. The affected operations are not registered until the manifest validates — see Skill Operations.
  • run.interpreter — no Python 3 interpreter on PATH. Install Python 3.10 or newer, or set FLYDOCS_PYTHON to the interpreter to use.
  • run.dry-run — an operation is resolved end to end, executing nothing. A failure here with the previous two passing means resolution itself is broken rather than any single operation; flydocs run --list shows what the registry can see.
  • runtime.python — the interpreter recorded in .flydocs/config.json. Gone is a failure: every bridge and MCP tool call spawns that command. Unrecorded or drifted is a warning — the record is a cache, not the answer. flydocs doctor --tools --fix re-probes and rewrites it.

An "unknown operation" from flydocs run with a green run.registry is usually a typo or a renamed ID — the refusal prints the accepted shape, and flydocs run --list prints every ID grouped by domain.


What --fix Will and Will Not Do

flydocs doctor --tools --fix re-runs the shipped writers — the registration reconciler, the permission writer, the interpreter probe — never a bespoke repair path. Each is idempotent, and every check runs again afterwards, so a repair that did not work still reports as a failure and a second --fix finds nothing to do.

It never touches:

  • a flydocs MCP entry that is not ours (it may be deliberate);
  • a registration file that does not parse (it may hold other servers);
  • a .claude/settings.json that does not parse (it is the only copy of whatever you were editing);
  • anything outside the flydocs key and the managed permission block.

A registration fix is scoped to the client that reported the problem, so repairing Cursor cannot rewrite a Claude Code entry a human wrote.


Reporting a Problem

Include the output of:

Terminal
flydocs doctor --json

It carries the CLI version, the directory examined, and every check with its status, detail, remediation and structured findings. A section that did not run is null rather than empty, so a skipped section cannot be misread as a clean one. Send it to support@flydocs.ai.


Next