@farthershore/cli
v0.21.1
Published
FartherShore CLI — bootstrap and operate software businesses
Maintainers
Readme
@farthershore/cli
Create and operate FartherShore software businesses from the terminal.
Status: 0.20.0. Pre-1.0 — the command surface is stable but may still
change between minor versions. Pin an exact version in CI.
FartherShore lets you define a software business as code, then sells, meters,
and bills access to it at the edge. Product behavior — plans, pricing, limits,
routes, meters, and origins — is authored in your GitHub repo with
@farthershore/business
and applied automatically when you push. This CLI is the tool layer around that
repo: scaffold a new business, validate it locally before you push, connect
billing, publish it live, and run day-to-day operations (consumers, secrets,
backends, webhooks, promo codes, usage). It is designed to be safe for both
humans and agents — every command takes --format json for non-interactive
scripting, and the same surface is exposed as an MCP server.
Install
npm install -g @farthershore/cliOr run it directly with npx:
npx @farthershore/cli --helpThe package also ships an MCP stdio server for agents:
FARTHERSHORE_TOKEN=mk_xxx npx -p @farthershore/cli farthershore-mcpAuthentication
Create a maker token at farthershore.com/settings/tokens, then store it locally:
# Interactive — prompts for the token
farthershore auth login
# Non-interactive — pass it directly
farthershore auth login --token mk_xxx
# Or skip the file entirely with an env var (CI / agents)
export FARTHERSHORE_TOKEN=mk_xxxTokens are stored in ~/.farthershore/credentials.json. A maker token is
exchanged for a short-lived CLI access token on the first authenticated request.
farthershore auth whoami # Show current org, role, and scopes
farthershore auth logout # Clear stored credentialsGitHub account linking and Stripe Connect/KYC are browser-hosted flows; the CLI
reports their status (see connect) so you — or an agent — can continue once the
flow is finished in the dashboard.
Quickstart
Scaffold a business, validate it, connect billing, and publish:
export FARTHERSHORE_TOKEN=mk_xxx
# 1. Create the managed repo (provisions GitHub repo + starter frontend)
farthershore business create --name weather-api --display-name "Weather API"
# 2. Edit business behavior in the repo
gh repo clone acme/weather-api
cd weather-api
# ...edit business/business.config.ts with @farthershore/business...
# 3. Validate the same way the PR check will, before pushing
farthershore preflight --business weather-api
# 4. Push — the GitHub bot compiles + applies your manifest
git push --set-upstream origin feature/pricing
farthershore change-set list weather-api # inspect checks + apply state
# 5. Connect billing, then go live
farthershore connect stripe weather-api
farthershore business publish weather-apiPlans, prices, limits, routes, meters, and origins are repo-controlled:
change them by editing business/business.config.ts and pushing. The CLI's
write commands cover operational state that lives outside the manifest
(consumers, secrets, backends, webhooks, promo codes, brand presentation).
Global flags
| Flag | Description |
| --------------------- | -------------------------------------------------------- |
| --token <token> | Override auth token for this command |
| --api-url <url> | Override platform Core API URL |
| --env <environment> | Environment scope (production/prod/main aliases) |
| --format <format> | json for machine-readable output (default for non-TTY) |
| --no-input | Never prompt; use non-interactive, agent-safe paths |
| --version | Show version |
| --help | Show help |
Environment variables
| Variable | Description |
| ---------------------- | --------------------------------------------------------------- |
| FARTHERSHORE_TOKEN | API token (overrides stored credentials) |
| FARTHERSHORE_API_URL | Platform Core API URL (default https://core.farthershore.com) |
| FARTHERSHORE_ENV | Default environment scope when --env is omitted |
Commands
Run farthershore <group> --help for the full flag set of any command.
farthershore init
Scaffold a starter business repo locally from a named plan preset. Each preset
fills in a single decorated business/business.config.ts (one @Business class
with @Meter/@Feature/@Plan members) and creates the matching customer
frontend/ project, repo-local business/package.json, business/tsconfig.json,
and .gitignore.
# Interactive walkthrough (TTY only) — pick a preset and a path
farthershore init
# Non-interactive — pass --template explicitly (required when not a TTY)
farthershore init --template free
farthershore init --template starter --force
farthershore init --template metered --format json
farthershore init --template starter --surface frontend --surface agent| Template | Shape |
| --------- | ------------------------------------------------------------ |
| free | $0 plan, hard-enforced 1k requests/month limit |
| starter | $20/mo + $20 included usage, $0.001/request overage |
| pro | $100/mo + $200 included usage, 14-day trial, $0.0005/request |
| prepaid | $50 one-time signup credit, then pay-as-you-go |
| metered | Pure pay-as-you-go at $0.001/request |
After init, edit the @Business({ name, origin }) decorator — origin is the
business-logic destination FartherShore calls for customer-facing actions — and
add @Meter/@Feature/@Plan members to grow the business. Pass repeatable
--surface <frontend|api|docs|widget|dashboard|webhook|worker|agent> to seed a
specific shape; omitting it keeps the default frontend + api starter. Run
npm install in business/, then farthershore build from the repo root to
confirm it compiles.
farthershore build
Compile business/business.config.ts to a Manifest IR envelope locally (default
output business-build.json). The CLI uses the Business SDK installed under
business/, falling back to a root install. This is local compilation only;
server-side validation and apply happen when you push business/** changes.
farthershore build
farthershore build --entry business/business.config.ts --out business-build.json
farthershore build --format jsonfarthershore preflight
Run the same verdict the GitHub farthershore/validate PR check produces, before
you push. It builds the manifest twice and compares the IR hash (the determinism
check the build runner enforces), then — when you pass --business — submits the
IR for a server dry-run that returns compile diagnostics, the semantic diff, and
an economic-change verdict.
farthershore preflight # local build + determinism only
farthershore preflight --business weather-api # + full server verdict
farthershore preflight --local-only --format jsonfarthershore business
Business lifecycle. Creation provisions a managed GitHub repo (the source of
truth for product behavior) under your connected GitHub account and returns the
clone URL plus bootstrap instructions. A new business starts as a DRAFT with a
generated frontend/ ready to customize.
farthershore business list --format json
farthershore business show weather-api --format json
farthershore business show weather-api --env preview --format json
farthershore business create \
--name weather-api \
--display-name "Weather API" \
--format json
# Seed a meter from the same templates the dashboard offers:
# requests (default) | ai-tokens | credits | spend | compute
farthershore business create --name llm-api --meters ai-tokens --format json
# Or a fully custom meter list (key[:display[:unit]], repeatable):
farthershore business create --name image-api \
--meter requests \
--meter images:Images:image \
--format json
# Seed initial Business SDK surfaces (repeatable; defaults to frontend + api):
farthershore business create \
--name support-agent \
--surface frontend \
--surface agent \
--format json
farthershore business publish weather-api --format json
farthershore business delete weather-api --yes --format jsonbusiness update is presentation-only — it changes display name, description,
icon, and logo (icon/logo accept PNG, JPEG, or WEBP). Plans, prices, limits,
routes, meters, and origins are repo-controlled and must be changed through the
Business SDK code path.
farthershore business update weather-api \
--display-name "Weather" \
--description "Weather API for agents" \
--icon-file ./brand/icon.png \
--logo-file ./brand/logo.webp \
--format json
farthershore business update weather-api \
--clear-icon --clear-logo --format jsonbusiness publish enforces the same go-live gates as the dashboard: at least one
plan, an origin, and a verified Stripe connection (clear remediation is printed
for STRIPE_NOT_CONNECTED / STRIPE_NOT_VERIFIED / BILLING_TAX_NOT_ENROLLED).
farthershore change-set
Inspect repo-backed change sets — PRs, pushes, releases, checks, semantic diffs, and apply state — for a business.
farthershore change-set list weather-api --format json
farthershore change-set inspect weather-api 42 --format json # by id, PR #, branch, or SHAfarthershore env
Manage preview/production environments. Production is the default scope when
--env is omitted (production, prod, and main are aliases).
farthershore env list weather-api --format json
farthershore env create weather-api --name preview --branch env/preview --format json
farthershore env delete weather-api preview --yes --format jsonfarthershore plan
Read code-managed plans and operate live subscriber migrations. The CLI does not create, update, or delete plan definitions — edit the Business SDK program for that.
farthershore plan list weather-api # table (default in TTY)
farthershore plan list weather-api --format json
# Migrate live subscribers after a repo-authored plan version is released
farthershore plan migrate weather-api pro --from 1 --to head --policy next_renewal --format jsonfarthershore frontend
Managed Frontend Hosting operations plus a local preview. deploy, status,
rollback, and env operate the hosted build; preview runs the generated
frontend/'s vite dev with an injected window.__FS_CONFIG__ shim so the
portal renders locally exactly as it serves in production.
farthershore frontend status weather-api --format json
farthershore frontend deploy weather-api --format json
farthershore frontend rollback weather-api --release-id <hash> --format json
farthershore frontend env list weather-api --format json
farthershore frontend env set weather-api VITE_PUBLIC_FOO bar --target BUILD --format json
# Local preview (shells out to vite; needs a frontend/ project)
farthershore frontend preview --core-url http://localhost:8787farthershore persona
Mint fresh fsk_test_* API keys in a test-strategy environment so you can
exercise the gateway end-to-end.
farthershore persona bootstrap weather-api --env preview --plan pro --format json
farthershore persona list weather-api --env preview --format json
farthershore persona revoke weather-api <personaId> --env preview --format jsonfarthershore usage
Read recent usage off the management API.
farthershore usage summary weather-api --format jsonfarthershore consumer
Manage live business users. These are operational actions, not repo-authored behavior.
farthershore consumer list weather-api --format json
farthershore consumer block weather-api <subscriberId> --yes --format json
farthershore consumer remove weather-api <subscriberId> --yes --format jsonUse consumer list first to find a subscriberId. block suspends a user and
revokes active API keys. remove is irreversible and tears down subscriber state
across billing, edge credentials, and subscriptions.
farthershore secret
Manage private business secrets. Values are encrypted at rest; list/read responses return metadata only.
farthershore secret list weather-api --format json
printf '%s' "$CLERK_SECRET_KEY" | farthershore secret set weather-api \
CLERK_SECRET_KEY --from-stdin --target RUNTIME --format json
farthershore secret delete weather-api CLERK_SECRET_KEY --yes --format jsonUse frontend env for public, browser-visible variables (VITE_PUBLIC_*,
analytics keys). Use secret for server runtime and private build values.
BUILD secrets are injected into managed frontend builds and require a redeploy;
RUNTIME secrets are for trusted server/backend code and are never exposed to
the browser.
farthershore backend
Create bring-your-own backends and provision runtime tokens for your upstream
services. Only token hashes are stored; the raw token is returned once and should
be deployed as FS_RUNTIME_TOKEN.
farthershore backend list weather-api --format json
farthershore backend create weather-api \
--name "Production API" \
--origin-url https://api.example.com \
--format json
farthershore backend tokens create weather-api --backend <backendId> --format json
farthershore backend tokens rotate weather-api <tokenId> --format json
farthershore backend tokens revoke weather-api <tokenId> --yes --format jsonPair the token with
@farthershore/backend in
your upstream:
import { fartherShore, withUsage } from "@farthershore/backend";
const fs = fartherShore.initFromEnv();
export async function POST(request: Request) {
const url = new URL(request.url);
const body = await request.clone().arrayBuffer();
await fs.verifyRequest({
method: request.method,
path: url.pathname,
query: url.search,
headers: request.headers,
body: new Uint8Array(body),
});
const result = await runWorkflow(await request.json());
return withUsage(request, Response.json(result), {
tokens_used: result.tokensUsed,
});
}farthershore webhook
Provision outbound webhook endpoints and inspect delivery health. If the business
declares webhooks in business/business.config.ts, writes return
409 MANAGED_BY_CODE so the repo stays canonical.
farthershore webhook list weather-api --format json
farthershore webhook create weather-api \
--url https://hooks.example.com/farthershore \
--events subscription.created,payment.failed \
--format json
farthershore webhook update weather-api <webhookId> --disable --format json
farthershore webhook test weather-api <webhookId> --format json
farthershore webhook deliveries weather-api <webhookId> --limit 20 --format json
farthershore webhook delete weather-api <webhookId> --yes --format jsonwebhook create returns the signing secret once; store it in the receiving app.
farthershore promo-code
Manage checkout promo codes (operational state, not part of the manifest).
farthershore promo-code list weather-api --format json
farthershore promo-code create weather-api \
--code LAUNCH25 --kind percent_off --percent 25 --duration-months 3 \
--plan <planId> --format json
farthershore promo-code create weather-api \
--code SAVE500 --kind amount_off --amount-cents 500 --duration-months 1 --format json
farthershore promo-code archive weather-api <promoCodeId> --format json
farthershore promo-code reactivate weather-api <promoCodeId> --format jsonBecause a Stripe coupon change requires a complete discount spec, promo-code
update requires --kind, --duration-months, and the amount flag for that kind
whenever you change the code, amount, dates, plan scope, or redemption limits.
Use --all-plans to clear plan scoping.
farthershore connect
GitHub OAuth and Stripe Connect are browser-only. These commands report status so you can poll until the flow is finished in the dashboard.
farthershore connect github --format json
farthershore connect stripe weather-api --format jsonfarthershore token
Manage maker tokens for the current org.
farthershore token list --format json
farthershore token create --name "ci-bot" --scope products:update products:publish --format json
farthershore token rotate <tokenId> --sync-to-github --format json
farthershore token revoke <tokenId> --yes --format jsonfarthershore skills
Inside a business repo, recommend agent skills matching the FartherShore SDK versions the repo actually uses. The Business SDK and Frontend SDK tracks are recommended independently, so updating one does not force a skill update for the other.
farthershore skills recommend --format json
SKILLS_CMD=$(farthershore skills recommend --format json | jq -r '.data.recommendation.command')
eval "$SKILLS_CMD"farthershore operations
Print the machine-readable action boundary: which operations are repo-authored
(contract), which are CLI/API operations (operate), which reconcile through
either path (dual), and which are browser-only prerequisites (GitHub linking,
Stripe Connect).
farthershore operations list --format jsonErrors and exit codes
In --format json mode, every command prints a single canonical envelope to
stdout — { ok, op, data } on success, or { ok: false, op, error } on failure,
where error carries a stable code, message, HTTP status, a retryable
flag, and a remediation hint when one is registered. Diagnostics go to stderr.
In table mode, failures print Error [CODE]: message plus a Hint: line:
Error [STRIPE_NOT_CONFIGURED]: connect Stripe before running billing operations
Hint: Stripe isn't connected on this product. Connect it in the dashboard before running billing operations.The bracketed code is stable across releases — quote it in support threads.
Exit codes are a branchable taxonomy so a script can tell failure classes apart without parsing text:
| Exit | Meaning |
| ---- | ------------------------------------------------------------ |
| 0 | Success |
| 2 | Validation error (HTTP 400/422) — fix your input |
| 3 | Auth / permission error (401/403) — re-authenticate |
| 4 | Conflict / managed-by-code (409) — change it in the repo |
| 5 | Server error (5xx) — retry |
| 1 | Any other failure (local error, 402/404, argument errors, …) |
CI and agent usage
The CLI is non-interactive whenever a token is available via --token or
FARTHERSHORE_TOKEN — auth login only prompts when stdin is a TTY and no token
was passed, so it is safe to script. farthershore build and farthershore
preflight --local-only need no network or auth and are safe to run in CI.
MCP server
The MCP server (farthershore-mcp) projects its tools from the same operation
registry that defines the CLI commands, so every MCP tool has a CLI sibling. Tool
names use the fs_* prefix and cover the agent-operable surface: businesses,
environments, plans, frontends, backends, runtime tokens, webhooks, promo codes,
consumers, secrets, personas, usage, and maker tokens.
FARTHERSHORE_TOKEN=mk_xxx farthershore-mcpLearn more
- Platform documentation: farthershore.com
- Author product behavior:
@farthershore/business - Report usage from your backend:
@farthershore/backend
License
MIT
