Toolaby

Build with an agent

Set up a coding agent to build, price, test and ship an extension on Toolaby.

A coding agent, such as Claude Code, Codex, Cursor, VS Code with Copilot, Gemini CLI or Windsurf, can do most of the work of selling an extension on Toolaby. It reads the files the command line writes into your project, acts on your tools through Toolaby's MCP server, and checks its own work with check.

This page covers the setup, what an agent does and what you do, how it verifies its work, and the reference: every MCP tool and command, the docs for agents, safety and troubleshooting.

Before you begin

  • A workspace on Toolaby, and Node.js 20 or later.
  • A coding agent that connects to MCP servers.

1. Set up your agent

npx -y toolaby@latest agents

agents registers Toolaby's MCP server in each coding agent it finds on this machine: Claude Code, Codex, Cursor, VS Code and Gemini CLI. It registers it for your user, so it works in every project. Run again, it changes nothing.

OptionDoes
--client <name>Only that client: claude-code, codex, cursor, vscode, gemini, or all.
--projectIn this project instead: .mcp.json and .cursor/mcp.json, to commit for your team.
--jsonWhat was done and what failed, as JSON.

Restart the agent, or reload its MCP servers. Its tools now include toolaby_get_tool and the others below.

wire and create print this command when they finish.

2. Or add the server by hand

The server is the command npx -y toolaby@latest mcp, on stdio. It acts on Test. For Live, add a second server named toolaby-live that runs npx -y toolaby@latest mcp --live.

Claude Code

Toolaby's plugin brings the skills, five commands (/toolaby:sell, /toolaby:check, /toolaby:test-unlock, /toolaby:ship, /toolaby:move-from-extensionpay) and Toolaby's docs server, at https://toolaby.app/api/mcp. Its commands act with the command line, as shell commands you see, and approve unless you have allowed them. In Claude Code:

/plugin marketplace add toolaby/claude-plugin
/plugin install toolaby@toolaby

For the toolaby_* tools as well, add the server, with or without the plugin:

claude mcp add --scope user toolaby -- npx -y toolaby@latest mcp

The plugin starts nothing on your computer by itself: the server that acts is one you add.

Codex

codex mcp add toolaby -- npx -y toolaby@latest mcp

Or in ~/.codex/config.toml:

[mcp_servers.toolaby]
command = "npx"
args = ["-y", "toolaby@latest", "mcp"]

Cursor

Add to Cursor, or in ~/.cursor/mcp.json:

{
  "mcpServers": {
    "toolaby": { "command": "npx", "args": ["-y", "toolaby@latest", "mcp"] }
  }
}

VS Code

Install in VS Code, or in .vscode/mcp.json:

{
  "servers": {
    "toolaby": { "type": "stdio", "command": "npx", "args": ["-y", "toolaby@latest", "mcp"] }
  }
}

Gemini CLI

gemini mcp add toolaby npx -y toolaby@latest mcp

Windsurf

In ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "toolaby": { "command": "npx", "args": ["-y", "toolaby@latest", "mcp"] }
  }
}

Other clients

Any client that starts an MCP server from a command: npx with the arguments -y toolaby@latest mcp.

3. Sign in once

The server acts as you, with the command line's session, on the tools of your workspaces. Without a session, a call answers that you are not signed in.

  • In the agent: toolaby_sign_in answers a link and a code. Open the link, check the code and approve. The server waits for your approval; the agent's next call works.
  • From a terminal, or an agent without MCP: npx -y toolaby@latest login --no-wait --json answers { url, code, deviceCode, expiresIn } and exits at once. After you approve, npx -y toolaby@latest login --poll <deviceCode> ends with exit code 0.

Sessions are per side. Live needs its own: npx -y toolaby@latest login --live.

4. Ask for the work

  1. Make the tool: in the dashboard, or ask the agent (toolaby_create_tool).
  2. Wire the extension: npx -y toolaby@latest wire <tool-id> in its folder, or npx -y toolaby@latest create <tool-id> for a new one. Both write the files agents read.
  3. Ask in one sentence: "Make exporting the counts as CSV a Pro feature, $5 once."
  4. The agent reads TOOLABY.md, adds the plan (toolaby_add_plan), then the feature and the plan that unlocks it (toolaby_set_features), puts gate({ feature: 'export' }) before the export, and verifies.
  5. It ends with what changed and the steps left for you.

What an agent does, and what you do

An agent does aloneYou do, once
Create and change tools, plans, trials, seats, features, the Free plan and coupons, on TestApprove the command line's sign-in, on each side
Write the code behind gate(), and fix what check reportsConnect Stripe on Live, under Configure → Payments
Prove a paid feature unlocks on Test: test-unlock, then check --browser --as <plan>Make a purchase in the browser, when you want to see Checkout
Read customers, grant access, refund and cancel, with your confirmation on LiveUpload the zip to the Chrome Web Store, and submit it
Copy the tool to Live, write the Live key, pack the store zipMake the first real purchase on Live

The skills and TOOLABY.md tell the agent never to report your steps as done.

The files agents read

create, wire and upgrade write these at the project's root: the folder with package.json, above a folder a build copies, such as public/.

FileForWritten
TOOLABY.mdEvery agent. The files Toolaby owns, where toolaby.js is imported from in this kind of project (plain, a bundler, WXT, CRXJS, Plasmo), gate() and the paywall, subscription and trial states, this tool's features and plans, the commands, the verify checklist, what only you can do, and links to these docs as Markdown. With --from-extensionpay, the move's steps. On Live, every command carries --live.Every time.
.claude/skills/toolaby*/SKILL.mdClaude Code, Cursor and Copilot: the skills below.Every time.
.agents/skills/toolaby*/SKILL.mdCodex, Cursor and Copilot: the same skills.Every time.
AGENTS.mdEvery agent reads it first.Where the project has none.
CLAUDE.mdClaude Code. It reads AGENTS.md.Where the project has none.

Where the project has its own AGENTS.md or CLAUDE.md, the command adds a short block to it, between <!-- TOOLABY START --> and <!-- TOOLABY END -->: where TOOLABY.md and the skills are, and the check. Run again, it replaces only what is between the markers. A CLAUDE.md that already reads AGENTS.md (@AGENTS.md) gets no block of its own.

Skills

SkillFor
toolabyWhat Toolaby is, which skill fits, setup, sign-in and safety.
toolaby-sell-a-featureMaking something Pro: the plan, the feature, gate({ feature }), a free or daily allowance.
toolaby-pricingPlans one-time or by subscription, trials, devices, seats, coupons, the Free plan.
toolaby-test-a-purchasetest-unlock and check --browser --as <plan>; a purchase with a test card.
toolaby-shipCopy to Live, login --live, upgrade --live, pack, the store listing address.
toolaby-extensionpay-moveMoving from ExtensionPay, and your steps after it.
toolaby-extension-patternsWhere gate() goes in a background, popup, side panel or content script, module scripts, the client's port, offline answers.

To add the skills to any project, without wiring it: npx skills add toolaby/claude-plugin, from the plugin's public repository, or npx skills add https://toolaby.app, where Toolaby serves them at /.well-known/agent-skills/index.json.

Verify

An agent says the work is done only after these pass.

  1. npx -y toolaby@latest check --json in the extension's folder. It exits 0, and ok is true.
  2. toolaby_get_tool: the plan at the price asked, and the feature the code gates among the plan's features.
  3. Built, npx -y toolaby@latest check --json --browser --built <output folder>: Chromium loads the extension, its background answers, and its pages open without an error. The first run downloads Playwright and Chromium into ~/.config/toolaby/playwright, never into the project.
  4. On Test, npx -y toolaby@latest test-unlock <tool-id> --plan <plan-id>, then npx -y toolaby@latest check --browser --as <plan-id>: the extension, signed in as your Test buyer with that plan, allows the paid feature.

test-unlock makes a buyer of your own on Test, at your address with +toolaby-test (you+toolaby-test@example.com), and gives it the plan. It is refused on Live.

check --json answers one object:

{
  "ok": false,
  "side": "Test",
  "folder": "/Users/you/word-count",
  "built": null,
  "findings": [
    { "code": "CSP_BLOCKS_TOOLABY", "level": "error", "message": "manifest.json's content security policy leaves https://quiet-otter-4172.toolaby.app out of connect-src: every call of Toolaby's fails to fetch. `npx -y toolaby@latest upgrade acme--word-count` adds it.", "file": "manifest.json", "fix": "npx -y toolaby@latest upgrade acme--word-count", "docs": "https://toolaby.app/docs/troubleshooting#in-the-extension" }
  ]
}

For each error finding, an agent runs its fix, a command, when it has one; otherwise it changes what the message says, and reads docs. The codes never change. These are the ones an agent meets most; Command line lists every one.

CodeMeans
FEATURE_KEY_UNKNOWNThe code gates on a feature key the tool does not have: every buyer is refused.
BACKGROUND_NOT_STARTEDNothing starts Toolaby in the background: none is named, it never starts Toolaby, a build's carries none of it, or it did not answer Toolaby's client (--browser).
EXTERNALLY_CONNECTABLE_MISSINGToolaby's address is not under externally_connectable: sign-in and the purchase never reach the extension.
CSP_BLOCKS_TOOLABYThe content security policy's connect-src (or default-src) leaves Toolaby's address out: every call of Toolaby's fails to fetch.
POPUP_NOT_MODULEA page loads a script with import or export lines without type="module": Chrome refuses it and the page opens blank.
PAGE_THREWA page of the extension threw when it opened (--browser).
NO_PAYWALL_POSSIBLENothing in the extension can ever ask anyone to pay. An error when the tool sells plans; a warning when it has none.
TEST_KEY_IN_LIVE_BUILDA store copy (its manifest has update_url) carries a Test or development key: an error. A production build that carries one: a warning.
HOST_PERMISSION_LEFTThe manifest gives Toolaby's address, or another side's Test address, a host permission or an entry Toolaby does not need.
KEY_OUTDATEDThe tool key is older than Toolaby's: the Free plan, the plans or the signing key changed since it was written.
NOT_SIGNED_INNo session on the side the key is on: the checks that need one were not made.
CLI_OUTDATEDThis command is older than the one Toolaby serves.

Exit codes

CodeMeans
0Done. check with warnings only exits 0.
1Failed, or check found an error.
2Done, with steps left for a person: wire and upgrade when they end Almost wired.

MCP tools

npx -y toolaby@latest mcp acts on Test, or on Live when started with --live. Every tool has a title, annotations, an input schema and an output schema, and answers structured content with the same JSON as text. Every tool has a command, below: an agent without MCP runs it with --json.

ToolCommandDoes
toolaby_whoamiwhoamiThe signed-in developer and their workspaces.
toolaby_list_toolstoolsYour tools, with the ids the others take.
toolaby_get_tooltool getOne tool: the Free plan, features, plans, the tool key, the extension's id, the checkout page, whether a copy has checked in.
toolaby_list_customerscustomersThe tool's customers, by a search text.
toolaby_get_customercustomerOne buyer: entitled or not, plan, licences, subscription status and renewal, grants, devices.
toolaby_analyticsanalyticsThe tool's Analytics: active devices, the funnel, revenue and MRR, uninstalls; or one table as rows.
toolaby_docsdocsA docs page as Markdown, or the index.
toolaby_search_docsdocs searchThe docs pages and passages that match a query.
toolaby_checkcheckA folder's wiring checked, with the findings above.
toolaby_sign_inloginA sign-in link and code for you; done once you approve.
toolaby_create_tooltool createA new tool.
toolaby_update_tooltool updateThe tool's name, line or store listing addresses, Chrome's and Edge's.
toolaby_set_accessaccessWhat the Free plan holds, and whether an account comes first.
toolaby_set_featuresfeaturesThe tool's whole list of features, and the plans that unlock each. Add the plans first. A feature the list leaves out is archived, never deleted: its holders keep it.
toolaby_add_planplan addA plan, one-time or a subscription, with a trial, a device count, per seat. It answers the plan's id; a tool's first plan is default.
toolaby_update_planplan updateA plan's name, trial, devices or per seat.
toolaby_retire_planplan retireTakes a plan off sale. Holders keep it. Destructive.
toolaby_grantgrantAccess without paying, to an address; answers the grant's id.
toolaby_revoke_grantgrant revokeTakes a grant back. Destructive.
toolaby_create_couponcoupon createA coupon code for checkout, such as one for a store reviewer.
toolaby_refundrefundRefunds a buyer's licence and revokes it. Destructive.
toolaby_cancel_subscriptioncancelCancels a buyer's subscription, at the period's end or now. Destructive.
toolaby_copy_to_livecopy-to-liveCopies the tool from Test to Live: the Free plan, features, plans, versions and the extension's identity. Needs both sessions.
toolaby_stripe_statusstripeWhether Stripe is connected, and the link for you to connect it.
toolaby_create_api_keyapi-keys createA server API key, written into an env file and never shown.
toolaby_test_unlocktest-unlockYour Test buyer given a plan, for check --browser --as <plan>. Test only.
toolaby_list_webhook_eventswebhooks eventsThe events a registered endpoint receives, each with an example of what it carries.
toolaby_list_webhookswebhooks endpointsThe webhook endpoints registered, with the events each listens for.
toolaby_add_webhookwebhooks addRegisters your server's endpoint, and writes its signing secret into an env file without showing it.
toolaby_send_test_eventwebhooks triggerSends an event's example to the registered endpoints, as a real delivery.
toolaby_remove_webhookwebhooks removeRemoves an endpoint: deliveries to it stop at once. Destructive.

The first eight only read, as do toolaby_stripe_status and the two webhook lists, and say so in their annotations (readOnlyHint). The five marked destructive say so too (destructiveHint), so a client that asks before such a change can ask before these.

When toolaby_set_access or toolaby_add_plan changes what the tool key carries, the answer says keyChanged: run npx -y toolaby@latest upgrade <tool-id>, then build and reload. Installed copies follow a change to the Free plan without a release.

So while copies are installed, toolaby_set_access does not open a Free plan that counts uses: copies that gate their work with a bare gate() would run all of it free, what your plans sell included, until they update. It answers copies_installed with the versions that checked in this week. Ship the build that gates by feature first. Opening the Free plan then is the person's step, once the build is live on the store: the tool's Access card, or access <tool-id> --access open --now in their own terminal. The MCP server never offers now to an agent. Copy to Live keeps Live's Free plan counting uses the same way, and says so.

The server also has resources, toolaby://docs/{page} (Markdown) and toolaby://tools/{tool} (JSON), and prompts: sell-a-feature, move-from-extensionpay, ship-to-store and fix-wiring.

Commands

Every command acts on Test unless given --live, and prints its raw answer as JSON with --json.

# Read
npx -y toolaby@latest whoami
npx -y toolaby@latest tools
npx -y toolaby@latest tool get <tool-id>
npx -y toolaby@latest customers <tool-id> --query <text> --limit 20
npx -y toolaby@latest customer <tool-id> <email>
npx -y toolaby@latest docs gating
npx -y toolaby@latest docs search "free trial"
npx -y toolaby@latest check --json --browser --built <output folder>

# Change
npx -y toolaby@latest tool create --name "Word Counter" --tagline "Counts the words on a page"
npx -y toolaby@latest tool update <tool-id> --store-url <listing address>
npx -y toolaby@latest access <tool-id> --access free_uses --free-uses 10
npx -y toolaby@latest features <tool-id> --features '[{"key":"export","name":"Export to CSV"}]' --plans '[{"id":"default","features":["export"]}]'
npx -y toolaby@latest plan add <tool-id> --billing subscription --interval month --amount 4 --currency usd --name Pro --trial-days 7
npx -y toolaby@latest plan update <tool-id> <plan-id> --devices 3
npx -y toolaby@latest plan retire <tool-id> <plan-id>
npx -y toolaby@latest grant <tool-id> <email> --days 30
npx -y toolaby@latest grant revoke <tool-id> <grant-id>
npx -y toolaby@latest coupon create <tool-id> --percent-off 100 --code REVIEW --max-redemptions 1 --expires-days 30
npx -y toolaby@latest refund <tool-id> <email>
npx -y toolaby@latest cancel <tool-id> <email>
npx -y toolaby@latest api-keys create --env-file .env --name server

# Test and Live
npx -y toolaby@latest test-unlock <tool-id> --plan <plan-id>
npx -y toolaby@latest stripe --live
npx -y toolaby@latest copy-to-live <tool-id>
npx -y toolaby@latest upgrade <tool-id> --live

# Sign-in and setup
npx -y toolaby@latest login --no-wait --json
npx -y toolaby@latest login --poll <deviceCode>
npx -y toolaby@latest agents --client cursor --project

Command line covers wire, upgrade, create, pack and webhooks.

The docs for agents

  • /llms.txt: what an agent should know first, when to use Toolaby, and every page with its Markdown address.
  • /llms-full.txt: the same, with every page, in one file.
  • Any page as Markdown: its address with .md, such as /docs/gating.md. A request for a page with Accept: text/markdown gets the same Markdown, and every page names its copy in a Link header (rel="alternate", type="text/markdown").
  • On every page, under its title: Copy page, View as Markdown, Open in Claude and Open in ChatGPT.

By address, over MCP

For a client that connects to an MCP server by its address, such as a Claude or ChatGPT connector, the docs are also an MCP server at https://toolaby.app/api/mcp (Streamable HTTP). It has two tools, toolaby_docs and toolaby_search_docs, and reads nothing but these docs, so it asks for no sign-in and holds no key. Where a client asks how to authenticate, choose none.

In Claude on the web, desktop and mobile, it is in the connector directory as Toolaby: browse the connectors, find Toolaby and connect it, with no sign-in.

claude mcp add --transport http toolaby-docs https://toolaby.app/api/mcp

In Cursor: Add the docs server.

The tools that read and change your tools stay with npx -y toolaby@latest mcp on your machine, under your own sign-in.

Safety

  • Test by default. Every command and the MCP server act on Test unless told --live. Test buyers, cards and keys never reach Live by themselves.
  • Live asks first. On Live, every change through MCP first answers a summary and a confirm code, valid for 5 minutes and for those arguments only. The call made again with the code does it. These tools also carry _meta: { "anthropic/requiresUserInteraction": true }. On the command line, refund on Live asks you to confirm.
  • No secret in a chat or an extension. api-keys create --env-file .env writes TOOLABY_API_KEY=… into the file and never prints it. The extension holds the tool key alone (tk_…), which is public.
  • Your roles hold. Every change goes through the same checks as the dashboard. A member whose role cannot change a tool is refused.

Troubleshooting

SymptomFix
The agent has no toolaby_* toolsRestart it or reload its MCP servers. npx -y toolaby@latest agents --json says which clients failed. Check Node.js 20 or later.
A call answers that you are not signed intoolaby_sign_in, or login --no-wait --json and then login --poll <deviceCode>. Approve the code in the browser.
A change on Live answers a confirm codeShow the summary to the person, and call again with the code only on their word.
An answer says keyChangednpx -y toolaby@latest upgrade <tool-id>, then build and reload.
check exits 1For each error finding, run its fix, or change what its message says.
test-unlock is refusedIt runs on Test only. A project with the Live key: upgrade <tool-id> writes the Test key; upgrade <tool-id> --live before the store build.
The tools act on the wrong sidenpx -y toolaby@latest mcp is Test; npx -y toolaby@latest mcp --live is Live.
npx runs another toolabyIn a repository you did not write, install the command (npm i -g toolaby) and type toolaby-cli.

See Troubleshoot an extension for what an extension says when something is wrong.

See also

On this page