For AI agents: the complete documentation index is available at https://scriptedalchemy.github.io/agent-bundle/llms.txt, the full documentation bundle is available at https://scriptedalchemy.github.io/agent-bundle/llms-full.txt, and this page is available as Markdown at https://scriptedalchemy.github.io/agent-bundle/reference/cli.md.
Skip to main content
  • English
  • CLI

    npx agent-bundle --help
    npx agent-bundle --version

    Commands

    CommandPurpose
    agent-bundle devServe the packaged development workbench on loopback.
    agent-bundle dev proxyBridge host stdio MCP traffic to a running development server.
    agent-bundle serve-app <app>Serve one built MCP App standalone in a browser, bound to its packed MCP server.
    agent-bundle buildBuild a validated Agent Bundle artifact.
    agent-bundle prepackBuild and validate the npm pack inventory.
    agent-bundle install <host>Install a built bundle into a supported host.
    agent-bundle uninstall <host>Remove a receipt-owned host install of a built bundle, and nothing else.
    agent-bundle doctorInspect host installs and runtime endpoints without changing them.
    agent-bundle validateValidate project source or one artifact.
    agent-bundle evalRun deterministic or native eval suites against a built artifact.
    agent-bundle eval compareCompare two persisted eval runs.
    agent-bundle inspectInspect normalized targets and adapter plans.
    agent-bundle mcp list / invoke / runOperate an MCP server from an artifact.
    agent-bundle hooks list / simulateInspect and simulate generated hooks.

    Shared option groups

    Source commands (build, prepack, validate, eval):

    OptionDefaultMeaning
    --root <root>process.cwd()Project root.
    --config <path>noneConfiguration file relative to --root.
    --mode <mode>productionConfiguration mode.
    --target <target>config targets, else portableHost projection to select: amp, claude, codex, cursor, or portable. Repeatable; the selection replaces the configured targets for this run, and every selected host lands in the one composite root whatever the order. Any other name, plugin included, is AB4100.
    --jsonoffWrite one machine-readable JSON document.

    Artifact commands (mcp list, mcp invoke, mcp run, serve-app, hooks list, hooks simulate): the same --root, --config, --mode, and --json, plus --artifact <path> to use exactly one built artifact and --target <target> to select the host projection. For mcp list, mcp invoke, mcp run, and serve-app, --target is optional: when omitted, the artifact's agent-bundle.manifest.json projections[] supplies the one MCP-capable host that runs the server, and a root whose projections leave the choice ambiguous fails with an error that names the candidates. hooks simulate still requires it, because a hook wrapper is compiled per host. serve-app takes no --json.

    dev

    OptionDefaultMeaning
    --root <root>process.cwd()Project root.
    --port <port>ephemeralLoopback TCP port.
    --agent-api / --no-agent-apiconfig dev.agentApiEnable or disable the authenticated Agent API on /mcp.
    --install-host <host>noneInstall and re-sync a development host. Repeatable; claude, codex, or cursor.
    --open / --no-open--no-openOpen the workbench after the foreground server starts.
    --workbench-dev-origin <origin>noneAccept Workbench UI requests from this loopback contributor HMR origin (the Rsbuild dev server, for example http://localhost:3000). Repeatable; a non-loopback or non-origin value makes agent-bundle dev exit before serving anything. See Contributor UI HMR.

    dev runs in the foreground and closes the session on a termination signal. See Developer Workbench.

    dev proxy

    OptionDefaultMeaning
    --server <server>requiredGenerated MCP server name.
    --target <target>portableGenerated target containing the MCP server.
    --url <url>discoveredExplicit loopback development server origin.

    The proxy inherits --root from the parent dev command and writes diagnostics to stderr.

    serve-app

    agent-bundle serve-app <server>/<app> [--artifact <path>] [--tool <tool>] \
      [--input <json>] [--port <port>] [--open]

    Serves one built MCP App in a plain browser tab, outside any MCP host and without the Workbench: the command launches the plugin's packed MCP server exactly as mcp run does, binds the App to it through the same host stack the Workbench App workspace uses (sandbox proxy, consent authority, bridge), calls the App's tool once so it opens populated, and prints the loopback URL. Its output is a contract: once the host is listening, stdout carries exactly one line, MCP App <app> at <url> (tool <tool>; Ctrl-C stops the server), <app> as given on the command line, <tool> the tool that opened the App, and every diagnostic goes to stderr. The command then runs in the foreground: SIGINT or SIGTERM closes the host and its server and exits 0; when the bound MCP server exits on its own, one AB5000 diagnostic is written to stderr and the command exits 1. The same ready-line contract is printed by <plugin> web.

    OptionDefaultMeaning
    <app>required<server>/<app>, the generated MCP server name and the App name (the last segment of its ui:// URI without .html, for example status/status), or <server>/ui://... to select an exact resource URI.
    --root, --config, --modeas for artifact commandsProject options.
    --artifact <path>throwaway buildUse exactly this built artifact. Without it the project is built into a staging directory beside the root and removed when the host closes.
    --target <target>the manifest's one MCP-capable hostThe host projection whose MCP server runs the App. Optional: without it, the artifact manifest's projections[] must name exactly one MCP-capable host; when several qualify the command fails and names them.
    --tool <tool>the App's only toolThe tool whose result opens the App: one that declares the App's _meta.ui.resourceUri. Required when several do.
    --input <json> / --input-file <path>{}JSON object input for that opening tool call; at most one of the two.
    --port <port>ephemeralLoopback TCP port for the host page.
    --profile <profile>portableSimulated MCP Apps host profile: portable, claude, or chatgpt.
    --allow <capability>noneApprove one consent capability on your behalf as the App requests it: call-tool, download-file, open-external-link, or request-display-mode. Repeatable. Everything else waits for an Allow/Deny decision in the host page, as in the Workbench.
    --open / --no-open--no-openOpen the default browser once the host is listening.
    --env-file, --no-env, --plugin-rootas for mcp runThe server's .env layering and plugin-root anchor, unchanged from mcp run.

    The host binds to 127.0.0.1 only, serves one document and the authenticated /api/mcp/... routes (a per-launch token plus same-origin checks; AB8003 / AB8004 on refusal), and exposes only the selected server through the bridge. The App document itself runs on a second loopback origin inside the framework's sandbox. It is a local preview host, not a deployment target. The programmatic form for scripts and tests is serveApp in agent-bundle/api. From an installed artifact the supported command is <plugin> web, which runs the same host stack from bin/<plugin>.mjs without the framework on the machine, see Exposing an App in the browser.

    <plugin> web

    node <root>/bin/<plugin>.mjs web [<server>/<app>] [--port N] [--open|--no-open] \
      [--tool T] [--input JSON] [--allow <cap>]... [--profile portable|claude|chatgpt] [--json]

    The framework-owned web command on the composite artifact's bin/<plugin>.mjs. It is emitted when the project configures web, even if src/cli/** compiled no commands, and is listed in that bin's --help. Run it from the built artifact or the installed plugin root, agent-bundle.manifest.json must sit beside bin/ (exit 1 otherwise).

    OptionDefaultMeaning
    <server>/<app>the only exposed AppSelects among Apps listed in the manifest web section. Required when several are exposed; omitting it then is a usage error (exit 2) that lists them.
    --port <port>ephemeralLoopback TCP port for the host page.
    --open / --no-openconfig web.openOpen the default browser once the host is listening. Config default is never.
    --tool <tool>the App's configured or only toolThe tool whose result opens the App.
    --input <json>configured input, else {}JSON object input for that opening tool call.
    --allow <capability>configured allowApprove one consent capability: call-tool, download-file, open-external-link, or request-display-mode. Repeatable.
    --profile <profile>portableSimulated MCP Apps host profile: portable, claude, or chatgpt.
    --jsonoffPrint one JSON line { app, server, tool, url, port, resourceUri, sandboxOrigin } instead of the human ready line, then keep running.

    The command launches the plugin's own MCP server (node <root>/mcp/<entry>.mjs, AGENT_BUNDLE_PLUGIN_ROOT=<root>, declared static env with path tokens expanded, the plugin-data token resolves outside the artifact, under ~/.agent-bundle/web-data/<plugin>-<digest>/<server>, so a read-only install still launches). The spawned server's own durable framework state likewise lives outside the artifact under ~/.agent-bundle/state/<plugin>-<digest> (or AGENT_BUNDLE_STATE_ROOT). It calls the opening tool once and serves the App at http://127.0.0.1:<port>/ on a loopback origin with a second loopback sandbox origin for the App document, the same host stack and consent behavior as agent-bundle serve-app and the Workbench. Human mode prints MCP App <server>/<app> at <url> (tool <tool>; Ctrl-C stops the server) and runs until Ctrl-C / SIGTERM. An authored src/cli/web.ts (or any generated-mode command or top-level alias spelled web) is refused as AB4341 when web is configured.

    build and prepack

    Both take the source option group plus:

    OptionDefaultMeaning
    --output <path>config output.distPath, else artifactThe composite plugin root, relative to --root: one directory every selected host reads, with no per-host subdirectory beneath it. dist belongs to the package build.

    Both build package outputs when the project declares bin or lib. The layout of the root is in Targets and artifacts.

    Generated wrappers import project modules by project-relative specifiers, so when every compiled module lies inside the project root (its own node_modules included), one source built from two checkout paths emits byte-identical files and an identical manifest. A module resolved outside the root keeps a path relative to it.

    build alone also takes:

    OptionDefaultMeaning
    --host-validation / --no-host-validationonAfter the root is written, run the installed Claude Code developer validator and load check over it when claude is among the selected projections, the same pair validate --artifact runs (AB6019–AB6022, AB7311, AB7325). Without claude on PATH the build spawns once and reports one informational AB6019 skip.
    --strictoffPromote host-tool warnings to errors.

    The JSON document carries the reports under hostValidation, one per validated projection, each with a load verdict (loaded, refused, unregistered, or failed) when the load check ran. Programmatic build() calls never run host validation unless hostValidation: true is passed. If project source changes while compilation is running, build and build() reject the result with AB7101 after compilation and validation, before the staged tree replaces live artifact or package output. Compiler metadata and compiled bytes from different snapshots are never published; any previous artifact or package output stays in place. Retry the build; the racing change is already on disk.

    install

    agent-bundle install <host> [--from <root>] [--scope <scope>] [--mode <mode>] \
      [--replace] [--no-sideload] [--sideload-repo <owner/repo>] [--sideload-slug <slug>] [--json]
    OptionDefaultMeaning
    <host>requiredamp, claude, codex, cursor, or grokbot. grokbot installs the Cursor projection: it stages a committed marketplace repository under ~/.grokbot/agent-bundle/marketplaces/<name> ($GROK_BOT_HOME overrides ~/.grokbot), writes a receipt, and prints the remaining Grok Bot steps. A clean, receipt-owned staging repository is restaged on same-version content drift, or for a new version with --replace. Grok Bot registers plugins server-side from hosted Git marketplaces, so nothing is registered locally.
    --from <root>process.cwd()The composite root holding agent-bundle.manifest.json. Identity comes from application and projections[host]; other hosts use documents.plugin, while Amp copies only the directory containing documents.entry. AB7001 covers a missing/invalid manifest, projection, required host file, unsafe local name, or missing Claude/Codex marketplace identity.
    --scope <scope>useruser, project, or local. Claude accepts all three; Amp accepts project and user (its system root); Codex, Cursor, and Grok Bot are user-scoped. Run Amp project-scope installation from the destination project root.
    --mode <mode>localCursor only. local copies the bundle into ~/.cursor/plugins/local/<name>; marketplace stages a committed local marketplace repository under ~/.cursor/agent-bundle/marketplaces/<name> and prints the Customize → Plugins → "Add Plugins from Local Repository" step that makes Cursor manage the plugin as a marketplace install.
    --replaceoffReplace an existing agent-bundle install of this plugin even when its version differs. Without it, an identical copy is an already-installed no-op, a same-version copy whose content hash differs is replaced automatically, and a different version is AB7005. Foreign directories are always refused (AB7005).
    --no-sideloadsideload ongrokbot only. On a computer with Grok Bot agent-data (GROK_BOT_AGENT_DATA_DIR, then /home/box/agent-data, ~/.grokbot/agent-data, the macOS application-support root), install grokbot also writes the plugin into Grok Bot's own clone of the marketplace, <agent-data>/plugins/marketplaces/github.com/<owner>/<repo>/<sha>/<name>, adds it to that clone's .cursor-plugin/marketplace.json (or .claude-plugin/marketplace.json), and writes the cache copy <agent-data>/plugins/cache/<slug>/<name>/<sha> with .cache-complete. <sha> is the clone folder Grok Bot already has. Each folder carries .agent-bundle-sideload.json and the receipt records the exact manifest entry written: a folder without the marker, an entry that differs from the recorded one, or a path reached through a symbolic link is never touched, and such a conflict, a missing clone, or missing agent-data skips the sideload instead of failing. Folders land by rename from a fully written sibling, and the manifest is re-read immediately before its atomic rename so entries Grok Bot added meanwhile are kept. If the manifest or the receipt cannot be written, the sideload is rolled back, so nothing unrecorded stays behind. The receipt records every path, reruns are idempotent, and uninstall grokbot removes exactly them. Grok Bot loads only plugins its account plugin listing returns: until that lists the plugin, its next plugin sync removes the cache copy, and a new marketplace commit replaces the clone folder. --no-sideload or GROK_BOT_SIDELOAD=0 turns it off.
    --sideload-repo <owner/repo>scriptedalchemy/pluginsgrokbot only. GitHub marketplace whose Grok Bot clone receives the sideload; GROK_BOT_SIDELOAD_REPO sets it from the environment (GROK_BOT_SIDELOAD_MARKETPLACE, the earlier name, is still read and must name one repository). Install and uninstall retire a record the first sideload release left at ~/.grokbot/agent-bundle/sideload/<name>.json (under $GROK_BOT_HOME when set), removing only the folders and entry it names.
    --sideload-slug <slug><owner>-<repo>grokbot only. Grok Bot's plugin-cache partition for that marketplace (scriptedalchemy-plugins by default); GROK_BOT_SIDELOAD_SLUG sets it from the environment.

    The emitted standalone install.mjs accepts the same --replace. Cursor copies carry an install receipt (.agent-bundle-install.json), replacement touches owned files only, and a directory without a receipt naming this plugin (a copy placed before receipts existed included) is foreign, refused with or without --replace; Claude replacement runs claude plugin uninstall --keep-data before reinstalling. Codex replacement is add-only (codex plugin add) so plugin settings and nested MCP overrides survive. Disabled or unknown-enablement Codex replacements are refused (AB7004) because the native plugin CLI has no qualified settings-preserving update API. Every install writes a lifecycle receipt (format agent-bundle-install-receipt/2: version, content hash, mode, scope, owned paths, host registrations, timestamps), in-tree for Cursor and Amp local copies, under <host root>/agent-bundle/receipts/ for Claude, Codex, and Cursor marketplace mode, that uninstall and doctor consume. During install, an explicit state root that does not yet exist is created and receives .agent-bundle-state-owner.json, which records the installation identity. Parent directories may be created to reach it but are never claimed or recursively removed.

    uninstall

    agent-bundle uninstall <host> [--from <root>] [--scope <scope>] [--mode <mode>] \
      [--keep-data | --purge-data --confirm-purge] [--force] [--plan] [--json]
    OptionDefaultMeaning
    <host>requiredamp, claude, codex, cursor, or grokbot (removes the staged repository and receipt, plus the receipted sideload folders, cache copy, and manifest entry that still carry this plugin's marker, and names the Grok Bot plugin id to uninstall in Grok Bot).
    --from <root>process.cwd()The composite root whose agent-bundle.manifest.json identifies the plugin (name, version, marketplace), read exactly as install reads it (AB7001 on the same conditions).
    --scope <scope>userThe scope the plugin was installed at (Claude or Amp).
    --mode <mode>localCursor only: uninstall the local copy or the staged marketplace repository.
    --keep-dataonKeep every recorded framework state root, derived web-data, and a recorded Cursor PLUGIN_DATA directory. This is the default; the flag makes it explicit and preserves the ownership receipt for a later purge.
    --purge-dataoffRemove only receipt-recorded, installation-owned durable-data roots. Refused (AB7008) without --confirm-purge; shared, externally managed, marker-less, foreign-marker, and otherwise unproven roots are retained and listed.
    --forceoffProceed without a store receipt for a host-registered install (Claude/Codex, staged Cursor marketplace) or when owned content, version, or staged HEAD no longer matches the receipt. A Claude/Codex copy without a store receipt keeps its data: --force --purge-data --confirm-purge is refused (AB7009). A Cursor local directory without a receipt, or a receipt or manifest naming another plugin, is foreign and refused regardless (AB7007).
    --planoffPrint the exact paths and host registrations that would be removed and change nothing.

    Uninstall removes exactly what the receipt owns: the recorded files and installer-created directories (Cursor local, including the ~/.cursor/plugins[/local] directories the install created; Amp project/system, inside only .amp/plugins/<name>), the staged repository (Cursor marketplace, after its HEAD matches the recorded commit), or the host registrations (claude plugin uninstall <id> --scope <scope> --keep-data + claude plugin marketplace remove, codex plugin remove + codex plugin marketplace remove, the marketplace is retained while another installed plugin still uses it, including a Claude install at another scope or in another project known only to Claude's plugins/installed_plugins.json registry). Unowned entries are retained and listed, a state/ directory beside the plugin included; a missing store receipt is AB7009 and a mismatch is AB7007 unless --force; a Cursor local directory without a receipt is foreign (AB7007) even with --force; a second run is a not-installed no-op. The typed data.outcome says what happened to durable state per host: Cursor kept / purged / absent; Claude retained-by-host (the cached copy is orphaned for Claude's ~14-day grace period; a purge removes the owned framework state roots, derived web-data, and plugins/data/<id>/); Codex keeps external state by default and removes it on a confirmed purge while codex plugin remove deletes the cached tree. The emitted install.mjs accepts --uninstall with --mode, --keep-data, --purge-data --confirm-purge, --force, and --plan.

    State receipts keep three facts separate. The installed MCP documents determine each server's runtime location (including relative overrides resolved from that server's execution directory); the receipt records the locations observed for this installation; and only independent ownership evidence authorizes deletion. The default ~/.agent-bundle/state/<plugin>-<digest> (or $XDG_STATE_HOME/agent-bundle/<plugin>-<digest>) namespace is owned by construction. An explicit AGENT_BUNDLE_STATE_ROOT is owned only when installation created the previously absent directory and wrote its install-identity marker. A pre-existing directory is never recursively removed merely because a server or the current uninstall environment names it. Multiple servers and roots are recorded and judged independently. A receipt with no state block cannot make the current environment or home a source of purge authority: Doctor and uninstall report the observed root as unrecorded / unproven and retain it, including after --keep-data. Only agent-bundle-install-receipt/2 is read; a copy carrying an older receipt is foreign.

    doctor

    OptionDefaultMeaning
    --host <host>all supportedHost to inspect. Repeatable; claude, codex, cursor, or the opt-in grokbot (reports receipts plus the plugin id, version, and installed commit from the Grok Bot computer's plugin cache, AB7334, and which parts of a receipted sideload remain and whether Grok Bot loaded it, AB7335).
    --from <root>noneThe composite root to compare against, read through its agent-bundle.manifest.json as install reads it: identity from application, each inspected host from its projections[] row (AB7001 when the manifest does not describe the host).
    --jsonoffWrite one machine-readable JSON document.

    Doctor exits 1 when it reports any error diagnostic, and never modifies anything. With --from, it reports the installed copy per host as current, stale (same version, different content, AB7308), version-mismatch (AB7309), foreign (AB7321), load-failed (AB7325, Claude Code lists the copy with errors in claude plugin list --json and refused to load it; the message carries the host's text verbatim), or not-installed (AB7307). For Claude it also reads each row's enabled flag: a copy listed with enabled: false is disabled in the inventory and carries enabled: false next to its content verdict, with an AB7327 warning naming the claude plugin enable command; and it runs the Claude Code developer validator (claude plugin validate --strict against plugin.json, then marketplace.json) over the --from bundle and every installed copy, reporting findings as AB6020–AB6022 prefixed with Bundle at … or Installed copy at …. For Cursor it also proves plugin-scoped hook registration from the installed manifest (AB7322), warns when ~/.cursor/hooks.json would deliver a plugin hook a second time (AB7323), and tracks a staged marketplace from unregistered to registered once Cursor imports it (AB7324). For an Agent Plugins install it proves the emitted installer's placeholder expansion, expanded, unexpanded (spec forms Cursor 3.18.25 cannot launch), or drifted (AB7326). With --from it also reports the lifecycle stage per host, placed → registered → enabled → active, each observed (Claude and Codex plugin list --json rows and enabled flags, the Cursor local directory, the Cursor marketplace import cache) or typed unavailable with the reason no read-only surface exposes it (AB7330). It inventories the Agent Bundle receipt store under each host root and warns about receipts the host no longer honours (AB7328). A Cursor directory uninstall --keep-data left behind with its remnant receipt is reported missing with an AB7307 info, not corrupt or foreign; without that receipt, a directory holding only state/ is corrupt (AB7304) and foreign (AB7321). For every installed copy Doctor reports every per-server framework state root, its native or derived source, receipt ownership (derived, marker, unowned, or unrecorded), whether its evidence is currently purgeable, the servers using it, whether it exists, and whether it is writable. A state/ directory beside the plugin is an ordinary unowned entry, not durable state.

    validate

    OptionDefaultMeaning
    --artifact <path>noneValidate exactly this built artifact instead of project source.
    --host-validation / --no-host-validationonRun installed host developer tools over the root for the selected projections that have one. When claude is selected this is the two claude plugin validate --strict runs followed by the claude --plugin-dir <root> plugin list --json load check (AB7325 when the row carries errors, AB7311 when there is no row).
    --strictoffPromote host-tool warnings to errors.

    eval

    OptionDefaultMeaning
    --artifact <path>built from sourceEvaluate exactly this built artifact.
    --case <case>allEval case id to run. Repeatable.
    --suite <suite>allEval suite name to run. Repeatable.
    --harness <harness>deterministicdeterministic, claude, or codex.
    --trials <count>suite-declaredRun this many trials of every selected case. A positive integer, at most 100.

    eval compare <baseline> <candidate> takes two persisted run ids and inherits the source options from eval.

    inspect

    inspect takes --root, --config, --mode, --json, and a single --target <target> filter (not repeatable), plus at most one focus flag. --artifact <path> inspects a copied built composite root through its agent-bundle.manifest.json instead of a project source tree; it is mutually exclusive with --root and --config (a usage error). A missing or non-canonical manifest fails with AB7001.

    FlagFocus
    --bundlerThe lowered Rspack configuration of every compiled output, what Rslib (executables) or Rsbuild (MCP App views) hands the compiler after the tools hatch and the framework invariants, lowered in production mode regardless of NODE_ENV. Resolved aliases, externals, plugins ([object <ClassName>]), and functions ([function <name>]) are rendered in place; output.path is the artifact output, <output>, because every selected projection compiles into the one composite root. A tools value the build would refuse makes the inspection invalid with AB7001.
    --hooksHooks.
    --routesThe compiled route graph.
    --skillsSkills.
    --stateState lifetimes.

    Passing more than one focus is an error. inspect exits 1 when the normalized model is invalid.

    With --json, the document gains an output.manifest summary, the built projections[] and executables, whenever a built agent-bundle.manifest.json exists at the artifact output, so a JSON consumer sees what the last build emitted without probing the root itself. The source-side model and plan view is unchanged.

    inspect --artifact <path> does not load project config. --json prints { manifest, application }: the same InspectManifestSummary as output.manifest, and the same application projection the Workbench renders (applicationExplorerFor), including distribution.payloads[], each prebuilt payload's name, hosts, and runtimeDependencies (the row artifact-only consumers read for packages that must exist at consumer runtime; see definePrebuilt). Without --json, the human output is the application id/name/version, projections with builtInHost, servers with tool counts, hooks by host, bins, scripts, and payload rows.

    Every inspection plan reports each component with its canonical kind, agent, cli, command, event-route, hook, lsp, mcp-app, mcp-server, native-diagnostics, native-extension, rule, script, skill (AgentComponentKind from agent-bundle/api), as selected or skipped with its cause, plus a kinds matrix: one entry per kind with the target's own four-state capability judgment and selected/omitted counts. The human output prints one line per target, each omission and its reason, then kinds this host cannot emit:. Filesystem src/events routes report as event-route, judged by the host's event:<canonical event> row, not as hook.

    mcp

    mcp list requires --server <server>. mcp invoke requires --server and --tool <tool>, and takes exactly one of --input <json> or --input-file <path>; the parsed value must be a JSON object, not an array or scalar.

    All three resolve the server from the artifact's agent-bundle.manifest.json: the compiled entry (and its Flight worker) from executables.mcpServers[].entry, the Apps from executables.mcpServers[].apps[], and, when --target is omitted, the host from the one MCP-capable projections[] row; an ambiguous selection is an error that names the candidates.

    mcp run requires --server and runs one stdio server in the foreground with inherited stdio:

    OptionDefaultMeaning
    --env-file <path>conventional setLoad exactly this .env file, replacing the project-root set. Repeatable.
    --no-envoffLaunch without loading any .env files. Mutually exclusive with --env-file.
    --plugin-root <path>project rootExpand env plugin-root anchors against this root.

    Because the server owns the JSON-RPC channel for the whole foreground run, mcp run writes nothing of its own to stdout. See Runtime environment for the .env precedence rules and what the plugin-root anchor changes.

    hooks

    hooks list reports the hooks in an artifact, the executables.hooks[] rows of its agent-bundle.manifest.json. hooks simulate requires --hook <hook> (an id or a name) and the same --input / --input-file pair as mcp invoke.

    Exit codes

    CodeMeaning
    0Success, including --help and --version.
    1A reported failure: an error diagnostic, an invalid model from inspect, a failing or inconclusive eval run, or an uncaught error written to stderr as one AB5000 diagnostic. A malformed --input / --input-file document is a runtime input failure and lands here.
    2A parser-level failure from the command-line parser: an unknown command or option, a missing required argument or option, or an invalid value for --port, eval --trials, dev --install-host, install / uninstall <host>, --scope, or --mode, serve-app --profile, serve-app --allow, or doctor --host.

    An eval run exits 1 when any trial fails or is inconclusive, an inconclusive trial produced no evidence, so it cannot report success either.