~/ docs
Buy from your terminal. Or your AI.
Two thin clients over the same store: the bt CLI for your shell, and an MCP server for your AI agent. Browse, stage, and check out heavyweight pieces without leaving where you build. Cards never touch the terminal — payment opens in your browser, on Stripe.
Connect your app
Paste it into Claude, Cursor, or any MCP-capable agent. It wires up the store and teaches the buy flow, so your agent can browse, read a piece's specs + lore, and take you to checkout. You approve the payment in your browser — the card never touches the chat.
show prompt
Binary & Thread is a terminal-native clothing & lifestyle store you can shop from inside this session — browse, read a piece in full, and drive a purchase to the payment page.
SETUP — add the MCP server (zero config; public production defaults are baked in). In .mcp.json:
{
"mcpServers": {
"binary-and-thread": { "command": "npx", "args": ["-y", "@binaryandthread/mcp"], "env": { "BT_REGION": "se" } }
}
}
BT_REGION is an ISO-2 country code that sets pricing + currency (omit for the default region).
TOOLS
- list_products — the catalog (text-only, keeps your context lean).
- get_product(handle) — a piece in full: readme, spec sheet, lore + sources, price, colours, image. Returns structuredContent {readme, specs, lore, price, currency, colours} — chain on the fields, don't parse prose.
- add_to_cart / get_cart — build + read the cart; returns a cart_id handle and a VAT-inclusive total.
- checkout(cart_id) — mints {checkout_url, session_id} instantly. It does NOT charge, open a browser, or set an address.
- check_payment(session_id) — poll for completion at your own cadence.
- get_order_status(display_id, email) — track a placed order.
- report_issue — file a bug. teapot / fortune — flavour.
BUY FLOW (the path that matters)
1) get_product(handle) to confirm specs + price.
2) add_to_cart, then note the cart_id + total (incl. VAT).
3) checkout(cart_id), then hand the human the checkout_url. They enter the card + address on Stripe. You cannot complete a payment on their behalf — by design.
4) poll check_payment(session_id) until paid, then get_order_status to track.
Example — "buy the bezier in L": get_product("bezier"), add_to_cart(the L variant), checkout, then reply with the checkout_url.
SAFETY — mutations are idempotent (retrying a failed call won't double-charge or duplicate a cart); requests time out and fail closed; no card or address ever passes through this chat.
Prefer the terminal? Run npx @binaryandthread/cli <command> (browse, view <n|slug>, stage <n|slug>, checkout, blame <slug>), or npm i -g @binaryandthread/cli for the bt shortcut.Install
Run it with npx — no global install, always the latest:
$ npx @binaryandthread/cli browse $ npx @binaryandthread/cli brew coffee # 418 i'm a teapot. (RFC 2324)
// the ONLY package is the scoped @binaryandthread/cli (signed, 2FA-published). npx bnt, npx bt, npx btn, and npx binaryandthread are DIFFERENT, unscoped packages owned by strangers — never run them. Always install the full scoped name.
Throughout these docs we write bt <command> as shorthand. Two ways to run it: install once with npm i -g @binaryandthread/cli so bt is on your PATH, or run any example as npx @binaryandthread/cli <command>. We lead with npx because a bare bt can collide with another binary already on your PATH.
Updating. A global install nudges you (one dim line) when a newer version ships; update with npm i -g @binaryandthread/cli@latest. npx caches the version it resolved, so pin @latest (or the exact version) to pull a new one. Tab-completion is available via bt completion bash|zsh|fish.
The bt CLI
Purchasing is a two-step, like git: stage reserves stock, commit (an alias for checkout) is the order. A full run:
$ bt stage the-terminal-piece --size=L ✓ staged the-terminal-piece@main#L · inventory lock acquired (held 10m) $ bt checkout > resolving … ok > opening checkout in browser … ✓ committed 48f3c1a — "the terminal piece @ main · size L" poll: bt order 1042
Global flags
These work on every command. A terminal brand that ignores NO_COLOR is a fraud — so it doesn't.
--jsonmachine-readable output (for scripting / piping)--no-colordisable ANSI colour + inline images (also honours NO_COLOR)-v, --versionprint the version (the codename is the egg)-h, --helpthe dry, useful help for any command
Command reference
Grouped by what you're doing. There's also bt brew coffee — it returns a 418. It's a teapot.
browse
Find a piece. Read-only — no account needed.
bt browsealias: bt lslist what's in stock on a branch — a numbered table (use the number with bt view/stage).
--branch <branch>main (live) or next (terminal-only drops)--pickopt into the arrow-key picker (the numbered table is the default)
bt search <query>filter the catalog by a query.
bt regionshow your ship-to country + currency, or set it. prices, VAT and shipping follow it. set an unshippable country and it's refused, not priced wrong.
<cc>set your ship-to country, ISO-2 (e.g. se / us / de)--listevery country we ship to + its currency--region <cc>(global) override the ship-to for a single command
bt view <n|slug>alias: bt showrender a piece: specs + image (always with the link as the floor). accepts a browse number, an exact slug, or a fuzzy hint.
--colour <colour>render a specific colour's mockup (e.g. black)
bt blame <n|slug>who's responsible for a design — its lore + sources (git blame, for motifs).
cart
Stage stock, inspect the cart, unstage. Like git add / reset.
bt stage <n|slug>alias: bt addreserve stock — acquires an inventory lock, reserves nothing permanent. accepts a browse number, an exact slug, or a fuzzy hint.
--size <size>garment size (default: your last commit's size)--colour <colour>garment colour, e.g. white / black (default: first colour)
bt cartshow your current cart — the authoritative server state.
bt unstage <ref>alias: bt resetremove a staged item from the cart (git reset). ref = its # (from bt cart), its line-item id, or its name.
checkout
Turn staged items into an order. Payment opens in your browser — cards never touch the terminal.
bt checkoutalias: bt committurn your staged items into an order. opens browser checkout, polls, never touches cards.
--resumeresume an in-progress checkout from your existing cart
bt order <id>track one order: staged → committed → printed → shipped → delivered.
bt logyour order history as a git log.
--onelinecompact one-line-per-order format--graphgraph format
bt statusworking-tree state: what's staged, what's in flight.
account
Passwordless auth: a one-time token by email that you paste in the terminal. It lives in the OS keychain — never in a file, never in the chat.
bt loginconnect your wardrobe — we email a one-time token, you paste it (no clickable link, no password).
--email <email>your email (skips the prompt)
bt logoutclear your local session (wipes the keychain token).
bt whoamiyour contribution profile + standing.
bt connectthe contributor on-ramp — what connecting unlocks.
bt forgetwipe your local session + config (keychain token, cart, email, defaults).
drops
What's on next before it hits the web main. First dibs is a contributor thing.
bt dropswhat's on next before it hits the web.
bt drop <sub>operator: manage a drop's lifecycle. sub = create | verify | promote | retire.
--motif <slug>motif slug (create)--drop-id <id>the drop id--stage <stage>expected stage for verify (next|main)
MCP setup
Buy from inside your AI agent. A small, deterministic MCP server (stdio) exposing 7 read-mostly tools over the same store the CLI uses. The agent can never complete a purchase or set a shipping address — it hands you a link; you pay on Stripe, in your own browser.
Config (Claude Desktop / Claude Code)
Add the server to claude_desktop_config.json or .mcp.json. Config is environment-only:
{
"mcpServers": {
"binary-and-thread": {
"command": "npx",
"args": ["-y", "@binaryandthread/mcp"],
"env": {
"BT_STORE_URL": "https://store.binaryandthread.com",
"BT_PUBLISHABLE_KEY": "pk_...",
"BT_REGION": "se"
}
}
}
}Environment
BT_STORE_URL(required)the Medusa Store API base URLBT_PUBLISHABLE_KEY(required)the publishable key — public by design (a secret sk_ key is rejected)BT_REGION(optional)ISO-2 country code to resolve pricing (e.g. se); never a hardcoded currencyBT_TOKEN(optional)the customer JWT (own data only) — from your keychain, never the chat
The 10 tools
list_productsthe catalog, text-only (no per-item images — keeps the agent's context lean)get_productone piece's specs + its image (rendered and the Blob URL as a text floor)add_to_cartcreate-or-reuse a cart; returns the cart_id as the durable handleget_cartthe authoritative server cart + total (incl. VAT)checkoutmints {checkout_url, session_id} instantly — never polls, never opens a browser, never sets an addresscheck_paymentpolls the session once; the agent re-calls at its own cadenceget_order_statusstatus/timeline by display id + exact email (no address; not-found on a mismatch)report_issuefile a bug report or feedback to the maintainers, server-redacted; returns a reference (no payment details, can't touch an order)teapot418. always. it's a teapot (RFC 2324) — a deadpan egg, no inputfortunea coding fortune — a real dev aphorism (optional seed)
Auth
Passwordless. Run bt login and we email you a one-time token — you paste it back in the terminal. There's no clickable link (a token in a URL would leak to browser and proxy logs) and no password, ever.
$ bt login --email you@example.com ⚙ token sent. check your inbox. paste the token from the email: •••••••• ✓ authenticated. token stored in your OS keychain.
The customer token lives in your OS keychain — never written to a config file, never read from the chat. Wipe everything local with bt logout (token) or bt forget (token + cart + email + defaults).
How images work in your environment
A piece's image renders as well as your surface allows — and always falls back to a plain URL. Image rendering is two problems, because the two clients control different things: in the CLI we render the pixels (depends on your terminal's graphics protocol); over MCP the host AI tool renders, so we just emit the blocks and keep the text floor bulletproof.
// the one rule: every product image is also a Blob URL text block, on every surface. A purchase never depends on an image rendering.
CLI (bt) — capability ladder
| Tier | Terminals | Image output |
|---|---|---|
| Graphics protocol | Kitty, WezTerm, Ghostty, iTerm2, VS Code integrated terminal | true inline image |
| Sixel | xterm -ti vt340, foot, mlterm | Sixel inline image |
| Color cells | Terminal.app, gnome-terminal, most modern | Unicode half-block (chunky colour render) |
| Dumb / piped / --json / CI / NO_COLOR | logs, | cat, redirected | plain text + Blob URL (the floor) |
MCP — host capability
| Host | Inline image? | Reliable floor |
|---|---|---|
| Claude Desktop / claude.ai | ✓ native | URL text also emitted |
| Claude Code (terminal + VS Code chat) | ⚠ base64 token-bloat bug | lean on the URL |
| Codex (OpenAI Codex CLI) | ✗ no reliable inline | URL text |
| Cursor / Copilot Chat / Windsurf / Zed | varies, mostly absent | URL text |
Rather click than type? The web store is right here.
Browse the collection →