Skip to content

CLI

Two packages, two jobs.

PackageJob
extensionCreate, run, debug and build an extension on your machine
@extension.dev/mcpGive a coding agent the platform verbs (MCP server)

extension

The Extension.js framework CLI. It has no login and never needs an account. Full documentation lives at extension.js.org.

bash
npx extension@latest create my-extension --template=init
cd my-extension
npm install
npm run dev

The command surface is create, dev, start, preview, build, logs, doctor, capabilities, install, uninstall, eval, storage, reload, inspect, open, publish, and telemetry. Each is documented in the framework's commands reference; this site does not restate them. Only publish touches the platform.

A build often needs values that stay out of the source. To see how a build reads environment values, start from the Content Env template.

Where it touches the platform

One place, explicit: extension publish asks the platform for the project's build page URL. It uploads nothing: a public project answers with its public page, a private one with the same address plus a ?share= token that lives 1 to 168 hours (--ttl, default 24). The revocable preview link, which runs on a much longer clock set by your plan, is a different verb, an upload, and it is documented at Share an unpublished build for review.

publish reads its token from three places, in this order:

  1. The --token flag.
  2. EXTENSION_DEV_TOKEN in the environment.
  3. The login stored by npx @extension.dev/mcp login, kept in ~/.config/extension-dev/auth.json (under $XDG_CONFIG_HOME if you set one, %APPDATA%\extension-dev\auth.json on Windows).

The third path is why the command can succeed in a terminal where you set nothing, and it is worth knowing before you trust the URL.

The token decides which project answers, and the directory does not. A token is scoped to one project, and publish tells the platform nothing about where you ran it. The CLI guards the stored login: when the folder you stand in does not carry the name of the stored login's project, publish refuses and names both projects, and --project <slug> publishes the stored project on purpose. A token you pass with --token or EXTENSION_DEV_TOKEN gets no guard, so read the project slug in the URL before you send it to anyone. To answer for a different project, pass that project's --token, or move the stored login with npx @extension.dev/mcp login --project <workspace>/<project>. See Publish from the CLI.

Everything else runs on your machine and sends nothing to the platform.

The platform from an agent

@extension.dev/mcp serves the MCP tools to a coding agent and ships the extension-mcp headless commands. Store submission and release promotion are platform actions: run them from the console's Stores tab, from an agent with extension_submit and extension_release_promote, or over the HTTP API.

When it fails

  • A command asks for a token: only publish does. Every other extension command runs without an account.
  • The URL names a project you did not expect: publish answered for the project your token is scoped to, which can happen with a token you passed by flag or environment. Pass the right --token, or run npx @extension.dev/mcp login --project <workspace>/<project> and publish again.
  • publish refuses with "Publishing here would share X, not Y": the stored login is scoped to another project. Run it inside that project, pass --project <slug> on purpose, or pass --token for this one.
  • eval, storage, reload, inspect, open refuse: they act on a live dev session and are gated. Start extension dev, then re-run with --allow-control (or --allow-eval for eval).
  • You are looking for a submit command: store submission is a platform action, not a framework command. Use the console's Stores tab, an agent's extension_submit, or POST /api/cli/stores/submit. See Publishing.

Next