CLI command reference
The build plugin is the primary MFDoctor experience. Use the CLI for a local check, a cross-project federation gate, baseline maintenance, runtime trace correlation, or a deliberate deployed-manifest probe. MFDoctor is not a CLI-only source scanner and does not inject an agent into the browser. The build plugin remains the primary integration; use the CLI for tasks outside a bundler emit.
Agents: mfdoctor check is tier 1 (config/static). Do not claim green from
check alone — finish plugin emit plus the workspace gate, and never ignore
doctor/partial-analysis. See the agent loop.
After installing @tonoizer/mfdoctor as a development dependency, run the
binary through your package manager or a package script:
The examples below use the shorter mfdoctor form.
Choose a command
MFDoctor loads an optional mfdoctor.config.ts; command-line flags override its
values. Use extends for named presets and shareable policy packs.
Discover CLI capabilities
This command prints a versioned JSON contract without loading project
configuration or accessing the network. Agents and wrappers can use it to
discover supported commands, output formats, public schema paths, exit-code
meanings, noninteractive handoff commands, explicit non-goals, analysis
completeness boundaries, GitHub Action identity, network policy, and the
bundler matrix derived from
fixtures/compatibility-matrix.json.
Validate the payload with the shipped
capabilities.schema.json
when integrating across package versions.
Check one project
Analyzes the current working directory. Use a positional path to analyze a different project:
--ci applies CI policy even when MFDoctor does not detect a CI environment. It
defaults failOn to error and output to terminal, JSON, and SARIF. Local
development defaults failOn to never, so findings print without breaking
the build.
Select report formats
Accepted formats are terminal, json, and sarif. JSON and SARIF artifacts
are written below .mf/doctor/. A format list containing only json or sarif
does not add human-readable terminal output.
Apply accepted debt
Matching findings remain visible but are marked as suppressed and do not fail policy by default. Treat the file as tracked debt and shrink it as issues are fixed. See Fingerprint baselines.
Control terminal output
- MFDoctor is quiet when a check has no findings.
--verboserestores the green success line. --no-scorehides the terminal health score. Report JSON still containssummary.scoreandsummary.scoreLabel.--no-prompthides the copy-paste fix prompts printed after findings.--promptforce-enables those prompts, including when config disables them or CI would hide them.- In CI (standard
CI/ provider env vars, ormode: "ci"), prompts are hidden by default. Local runs still show them. Opt in with--prompt, or dump prompts to disk with--diagnostics-dirwithout printing them.
You can also set MFDOCTOR_QUIET=0 to show successful checks or
MFDOCTOR_QUIET=1 to force quiet success. Environment configuration wins over
the file configuration.
Write a diagnostic bundle
Writes report.json, summary.md, and prompts/*.md to a directory inside the
project root. MFDoctor rejects a diagnostics path that escapes the project.
By default the dump includes the same top-3 prompts as the terminal. Pass
--diagnostics-prompts <n> (integer 1–25) or set
MFDOCTOR_DIAGNOSTICS_PROMPTS to dump more for agent/CI handoff. Values above
25 are rejected so the dump stays bounded. Terminal output stays at top-3
regardless of this flag. You can also set diagnosticsPromptLimit in
DoctorOptions / config; CLI and that option win over the env var.
Print agent fix prompts
prompt reads .mf/doctor/report.json by default. Without --finding, it
prints up to three prompts for the highest-priority non-suppressed findings.
Pass a rule ID or exact finding fingerprint to print one prompt. This command
does not re-run analysis.
Check a workspace
Build each app with its MFDoctor adapter first so it emits
.mf/doctor/project.json, then run one cross-project gate:
- With no roots,
workspacesearches below the current directory. - Positional values such as
apps packagesare discovery roots. - Discovery looks for
**/.mf/doctor/project.jsonbeneath each root. --group checkoutincludes only projects assigned to that explicitfederationGroup, which keeps independent federation graphs separate.
Override the discovery layout only when the defaults do not fit:
Quote globs so the CLI—not the shell—expands them consistently.
Check a federation
Use federation --workspace when you want to spell out that workspace
discovery feeds federation analysis. It runs the same discovery and analysis
path as workspace:
For a hand-tuned CI layout, pass one or more quoted project.json patterns
without --workspace:
Use workspace for normal monorepo discovery. Use explicit federation globs
when the reports live in a custom location or CI has already selected an exact
set of project files.
Manage a baseline
All three commands read .mf/doctor/report.json and write
mfdoctor.baseline.json by default. The explicit forms are:
Review baseline changes like code. Do not automatically update the baseline on every CI run, because that would silently accept new debt.
Correlate a runtime trace
runtime reads a user-supplied Module Federation Observability export and
correlates it with local MFDoctor project facts. Project files default to
.mf/doctor/**/project.json. You may instead set runtimeTrace in
mfdoctor.config and omit the trace path.
MFDoctor never fetches URLs found in a trace and never executes remote JavaScript. It collapses trace URLs to origin plus basename and redacts token, cookie, authorization, password, and secret fields before emitting findings.
Inspect the rule catalog
With no rule ID, rules prints the machine-readable built-in catalog as JSON.
With one ID, it prints that rule's default severity, category, impact, fix,
supported bundlers, docs path, and official sources. An unknown rule exits 2.
Probe a deployed manifest
probe and compare are the only commands that make a network request. It downloads the
manifest, validates that it looks like a federation manifest, and prints a
small JSON summary. Query strings are removed from output so signed URLs do not
leak into logs.
--remote-entry sends a HEAD request to the entry named by the manifest and
reports its status, content type, and size. MFDoctor does not download or execute
that JavaScript.
Safety defaults:
- HTTPS is required, except for an initial localhost or loopback URL.
- The timeout is 10 seconds; override it with
--timeout 5000. - The manifest limit is 2 MiB; override it with
--max-bytes 1000000. - Redirects are revalidated at every hop and limited to five.
- Private, link-local, loopback, and cloud-metadata targets are blocked by the public CLI probe.
- URLs containing user names or passwords are rejected.
An unreachable or invalid target exits 2. A valid manifest whose requested
remote entry returns an HTTP error exits 1.
Compare deployed manifests
compare reuses the same network policy as probe:
HTTPS (loopback HTTP only for the initial URL), SSRF blocking, redirect
revalidation, timeout, and size limits. It never downloads or executes remote
JavaScript. --remote-entry adds a HEAD check so remote entry HTTP status is
part of the diff.
The first URL is the baseline. Each remaining URL is a candidate. Diffs cover
name, exposes, shared (name and version), publicPath, remoteEntry, and
optional remoteEntryStatus.
Exit codes: 0 no material diff, 1 diffs found, 2 usage or fetch error.
With --format, JSON lands at .mf/doctor/compare.json and SARIF at
.mf/doctor/compare.sarif. Without --format, a human summary prints to
stdout.
Exit codes
GitHub Actions
Host teams copy this consumer workflow — ordinary Node + your package manager.
It does not use Vite Plus, vp, or this repository's setup-vp action.
Run the workspace gate only after every federated app that registers an
MFDoctor adapter has built (so .mf/doctor/project.json facts exist). Pin the
Action to a release tag (not @main) so CI stays reproducible:
npm or Yarn work the same way: install with npm ci / yarn install --frozen-lockfile,
build with your usual script, then set cli: npx mfdoctor or cli: yarn mfdoctor.
The Action requires a runnable mfdoctor / @tonoizer/mfdoctor CLI (via the
cli input). Missing CLI is a hard failure. If the job has not installed the
package yet, set install: true (optionally with package-spec: @tonoizer/mfdoctor@1.1.0).
upload-sarif defaults to true and needs permissions.security-events: write.
If that permission is missing, the Action fails with an actionable error instead
of a quiet upload miss. Set upload-sarif: "false" when you do not want code
scanning upload.
A ready-to-copy file lives at
examples/ci/github-actions-mfdoctor.yml.
Optional action inputs are build-command, globs, install, package-spec,
upload-sarif, and upload-artifact. You can also skip the Action and run the
CLI directly:
Upload .mf/doctor/results.sarif with github/codeql-action/upload-sarif when
code scanning is enabled.