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:
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.
-
mcp.registration.claude/mcp.registration.cursor— does the client's registration file nameflydocs mcp?- Missing file or missing entry: the client has nothing to spawn. Run
flydocs doctor --tools --fix(orflydocs update). Only theflydocskey 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
flydocsentry 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.
- Missing file or missing entry: the client has nothing to spawn. Run
-
mcp.command— isflydocson PATH, and new enough to servemcp? 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. -
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 captureflydocs mcp --verboseoutput and send it to support@flydocs.ai. -
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.
-
permissions.settingsfirst. If.claude/settings.jsondoes 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. -
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 withflydocs doctor --tools --fix, or by runningflydocs 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.blockas failing. An install predating the ownership record gains it on its firstflydocs update— run that (orflydocs 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:
-
flydocsis 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, ornpm 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: runflydocs updateto restore them. A warning means a skill'soperations.jsonwas 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 setFLYDOCS_PYTHONto 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 --listshows 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 --fixre-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
flydocsMCP entry that is not ours (it may be deliberate); - a registration file that does not parse (it may hold other servers);
- a
.claude/settings.jsonthat does not parse (it is the only copy of whatever you were editing); - anything outside the
flydocskey 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:
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
- Tool Surface Setup: what gets written and how to verify it
- Managed Permissions: modes, policy fields, ownership
- Skill Operations: contributing operations from a skill