Developers
fabplane CLI
fabplane-cli is the open-source command line, MCP server and TypeScript client for the
fabPlane API. Use it to keep shopping carts and team inventory in sync from a terminal, a CI job
or an AI coding agent.
Install
npm i -g fabplane-cli
fabplane --help
Node.js 20 or newer. npx fabplane-cli … works without a global install. Source:
github.com/fabPlane/fabplane-cli
(from a clone: npm ci && npm pack && npm i -g ./fabplane-cli-*.tgz).
Sign in
fabplane login
The CLI prints a code and opens the approval page; approve it while signed in to fabPlane. The token is saved to
~/.config/fabplane/credentials.json ($XDG_CONFIG_HOME/fabplane when set,
%APPDATA%\fabplane on Windows) with mode 0600.
For CI and servers, create a personal API token in the dashboard and use environment variables instead:
| Variable | Meaning |
|---|---|
FABPLANE_TOKEN | An fpk_… API token (or fpd_… device token) |
FABPLANE_API_ORIGIN | API server, default https://api.fabplane.com |
FABPLANE_ORG | Default organization id for commands and MCP tools |
Commands
Every command takes --json, --org <id|slug> and --origin <url>; run
fabplane help <command> for the rest. The organization comes from --org, then
FABPLANE_ORG, then fabplane orgs use, then your personal org.
| Command | What it does |
|---|---|
fabplane login [--token fpk_…] [--origin URL] [--no-browser] | Sign in with a device code, or save an API token. |
fabplane logout · whoami · dashboard [--open] | Forget the token, show the account, print or open the web dashboard URL. |
fabplane orgs list | create <name> [--slug] | use <id|slug> | List, create and pick the default organization. |
fabplane orgs members | role <userId> <role> | Members and role changes. |
fabplane orgs invite [--email] [--role member|admin] [--days] | invites | accept <token|url> | Invite links (no email is sent). |
fabplane orgs joinable | join <id> | Join an org through your verified email domain. |
fabplane tokens list | create <name> [--days] | revoke <id> | Personal API tokens. |
fabplane destinations list | add --name --url [--kind] [--base builtin:digikey] | Purchase destinations, e.g. a regional distributor. |
fabplane carts list [--repo URL] [--project ID] | show <id> | delete <id> | Carts, with items grouped by destination. |
fabplane carts create <name> [--repo …] [--project] [--notes] [--fab builtin:jlcpcb] | New cart; the fab house gets every line unless moved. |
fabplane carts add <cartId> --mpn --qty [--dest] [--refs R1,R2] [--sku] [--price --currency] [--kind] | Add a line. |
fabplane carts import <cartId> <file.json|.jsonl|.csv|-> [--replace] [--source] | Add lines from a BOM, or replace them all with --replace. |
fabplane carts export <cartId> [--dest ID] [-o file.csv] | CSV export, optionally one destination. |
fabplane inventory list [--q] [--category] [--location] [--tag] [--limit] [--all] | Search stock. |
fabplane inventory add --name … [--mpn --qty --location …] [--tag …] [--attr k=v …] [--image path …] | Add an item with photos. |
fabplane inventory import <file.jsonl> [--source] · adjust <id> <delta> [--reason] · show · delete | Bulk upsert by externalId, atomic stock changes. |
fabplane inventory photos queue [--all] · claim [--limit N] [--lease SECONDS] [--worker NAME] | Photo queue: items still missing a product photo, and leasing them. |
fabplane inventory photos attach <itemId> (--url IMAGE_URL | --file PATH) [--source-url PAGE_URL] [--source web] | Upload a found photo (URLs are downloaded on your machine). |
fabplane inventory photos skip <itemId> [--note] · retry <itemId> · requeue <itemId> | Release an item, or put a skipped one back (admin). |
fabplane bot connect --name NAME [--org SLUG] [--agent openclaw|hermes|…] [--no-browser] | Connect this machine's agent as a bot: prints a link and code, waits for an admin to approve, stores the bot token. |
fabplane bots list | create <name> [--role] [--agent] | rotate <botId> | remove <botId> | Manage the org's bots (admin). |
fabplane mcp [--desktop] | Stdio MCP server; --desktop adds tools for the local fabdesk app. |
fabplane desktop status | projects | tools | call <tool> [json] | Talk to the fabdesk desktop app on this machine. |
fabplane api <METHOD> <path> [json|-] | Raw API call, as an escape hatch. |
MCP server for Claude Code and Codex
fabplane mcp speaks MCP over stdio and uses the same credentials as the CLI. It exposes these tools:
org_list, destination_list, cart_list, cart_get, cart_create, cart_add_items, cart_update_item, cart_remove_item, inventory_search, inventory_add, inventory_adjust, inventory_photo_queue, inventory_photo_claim, inventory_photo_attach, inventory_photo_release.
Claude Code
claude mcp add fabplane -- fabplane mcp
# without a global install, or with a token for a headless machine:
claude mcp add fabplane -e FABPLANE_TOKEN=fpk_… -- npx -y fabplane-cli mcp Codex
Add to ~/.codex/config.toml:
[mcp_servers.fabplane]
command = "npx"
args = ["-y", "fabplane-cli", "mcp"]
# env = { FABPLANE_TOKEN = "fpk_…", FABPLANE_ORG = "my-team" } Other MCP clients
{
"mcpServers": {
"fabplane": { "command": "fabplane", "args": ["mcp"] }
}
} Bots for agents
Give an agent (openclaw, Hermes, a CI job) its own identity instead of your login. On the agent's machine:
npm i -g fabplane-cli
fabplane bot connect --name "openclaw on bench-pc" --agent openclaw
The CLI prints a link and a code. Open the link while signed in, pick the organization and role, and approve; the CLI
then stores the bot token (fpb_…) with that org as its default. fabplane whoami shows
kind: bot. A bot can work on carts, inventory and the photo queue of its own org only; it cannot create
orgs, invite people, make API tokens or manage other bots. For headless machines an admin can instead run
fabplane bots create <name> (or use the dashboard's Bots section) and set the printed token as
FABPLANE_TOKEN. Ready-made skills live in the fabplane-cli repository under integrations/openclaw/
and integrations/hermes/.
Library
Every API operation is a method on FabplaneClient, named after its operationId. Errors throw FabplaneApiError with status and code.
import { FabplaneClient } from "fabplane-cli";
const client = new FabplaneClient({ token: process.env.FABPLANE_TOKEN });
const { orgs } = await client.listOrgs();
const org = orgs[0].id;
const { cart } = await client.createCart(org, { name: "Rev B", repos: ["https://github.com/acme/board"] });
await client.replaceCartItems(org, cart.id, [
{ kind: "pcb", description: "Main board", quantity: 5 },
{ mpn: "LM1117-3.3", quantity: 5, destinationId: "builtin:digikey" },
], "my-script");
await client.createInventoryItem(org, { name: "ESP32-S3 module", quantity: 12, location: "drawer A3" });
The package also exports fabplaneTools (the MCP tool definitions, for embedding in your own agent),
dashboardUrlFor(apiOrigin) and FabdeskClient for talking to a local fabdesk desktop daemon.
Staying in sync with the API
The server publishes an OpenAPI 3.1 document at
/v1/public/openapi.json, generated from its
request schemas. The fabplane-cli repository's Sync API spec workflow runs every Monday at 03:00 UTC: it saves the
document to spec/openapi.json, regenerates the operation list and opens or updates a
chore/api-sync pull request naming any operationId that still lacks a FabplaneClient method.
Local AI, not server AI
fabPlane does not run AI on your photos or files yet: a request with serverAiProcessing: true gets 501
server_ai_unavailable. Let the agent on your machine (Claude Code or Codex through fabplane mcp, or
fabdesk) read the part photo or BOM, then call inventory_add or cart_add_items with the fields it
extracted.