ready. A receipt records what happened
without storing the prompt or output in it.
Before you begin
- Your organization has private-preview access, and an owner has invited you. The CLI and API call an organization a tenant.
- You have a Millwork organization API key for the organization you want to use, or can create one when setup opens Millwork. Configure it below.
- You have Node.js 20 or 22. The local diagnostic checks these two versions.
- Your organization has room in its run quota. You can add credit in Billing if setup asks for it.
Configure your API key
Open Millwork dashboard → API keys in the organization you want to use. Reuse a key you saved for that organization, or create one. If you do not have access yet, contact Millwork to apply for the preview. In version0.1.12 and later, a local interactive tenant start opens your
normal system browser when it cannot find a key. Keep the terminal command
running. Enter the Millwork organization API key on the private local page and choose
Save and continue. The CLI checks the key against the intended Millwork API,
saves it in $HOME/.millwork/organization-key.json where only your user can
read it, and returns to that same command. The command continues a saved setup
if one exists; otherwise it shows a plan for your approval. The key is not
placed in the URL or terminal output.
With --no-browser in an interactive terminal, enter your key at the hidden
prompt to check it, save it and return to the command. That prompt writes the
same $HOME/.millwork/organization-key.json. Use the private terminal method
below with an older CLI, in CI or scripts, or without an interactive terminal;
that method writes the older $HOME/.millwork/api_key instead.
--json stays non-interactive unless you explicitly add --open-browser.
A later millwork command reads either file, so you do not export the key
again. The CLI reads $HOME/.millwork/organization-key.json for the Millwork
API that checked the key, and reads $HOME/.millwork/api_key only for the
default https://api.getmillwork.dev/v1.
Start another setup
Repeatingtenant start continues the saved setup for that command and
Millwork key. If it is already ready, the CLI says so and shows its application
ID, completion time and model. It shows the saved result without starting a
new model run.
To review a fresh setup instead, run:
--no-browser if you use the hidden key prompt. Add
--template byok-open-model to choose your provider and model, or
--model-deployment-id to request a particular available catalog deployment.
Review the new plan and answer n to stop. The flag does not approve setup
or spending.
Each --new-setup invocation gets a new setup request key. If a response is
lost, keep that key and retry with --idempotency-key "<saved request key>"
and the same template and model choices. Once you have an application ID,
continue with --application-id. Do not use --new-setup to recover uncertain
work.
For a script, use tenant start --new-setup --json. It returns the plan,
application_key and next_action, then exits 2 without applying it. When
the plan is ready, next_action.command holds the exact approval command as
an argument array. Run it only after approving that plan’s effects and spend;
keep the same request key for retries. Resolve any choices or blockers first
if no approval command is returned. The ready-setup response carries the
same human information in setup_recovery, including completed_at,
model_key and new_setup.command. A time or model unavailable from an older
server is null.
--new-setup cannot be combined with an application ID, resume action, saved
request key, approval digest, --yes, --plan or --dry-run. Those flags
inspect, continue or approve an existing request; use the commands above for
a new one.
Private terminal fallback
If you already saved that organization’s key in$HOME/.millwork/api_key,
load it below. Otherwise run this block in your own Bash or
Zsh terminal, paste the key at the hidden prompt and press Enter. It saves the key in a file that only your user can read, then
loads it into this terminal without printing it:
SOLVERAPI_API_KEY gives the CLI your Millwork key in this terminal. Setting
a key in a hosting service does not configure your computer. For scripts,
load it from your secret store.
Never commit $HOME/.millwork/api_key or paste its contents into a conversation.
Check that the saved file exists and only your user can read it:
Load a saved key
In a new terminal, load the saved key without entering it again:MILLWORK_API_KEY for REST,
use this instead:
SOLVERAPI_API_KEY takes precedence over the browser-saved CLI key. A saved key
is bound to the exact Millwork API base that checked it; changing
SOLVERAPI_BASE_URL does not send that key to the new address.
Keep the CLI version for this setup
The npm commands on this page name an exact published version. Save that version with your application ID and use it throughout this setup. The shortermillwork examples mean the same version, either through npm or a
matching global installation.
If the CLI prints an unversioned npm continuation command, use this page’s
pinned npm prefix while preserving its application ID, digest, request key
and other arguments. Do not switch versions for a poll or retry.
The agent guide also explains how an
assistant can resolve the public version once before starting, then retain
that exact version for its whole journey.
Check this terminal
The CLI useshttps://api.getmillwork.dev/v1 by default. Check your local setup:
local_configuration_ready is true. This checks local
configuration without contacting the API; it does not prove the key is valid.
Next, run the setup command at the top of this page. Millwork checks the key
before showing a plan. A rejected key needs a local key fix, not another
request for access; see API key help.
1
Choose how to connect
The default setup uses a model Millwork provides. Your Millwork organization API key is
all you need; Millwork manages the provider connection.To use your own provider account instead:Setup shows the configured provider and model choices. Choose one when there
are several; a single available choice is selected automatically. The plan
shows what will be used before you approve it. Setup can reuse a connection
you already have.With the CLI installed, inspect providers and saved
connections with
millwork provider list. For a particular provider, follow
Connect a provider account.--yes here lets npm start the CLI without its package-download prompt.
Review the plan before approving it. For your provider account, setup and
the paid model run have separate approvals.The plan shows the model and spending allowance before you approve it.
Millwork uses the models available to your organization; it does not switch
between its provider account and yours without your choice.2
Approve setup
A live run has a platform fee when Millwork accepts it, plus model usage.
Use the fee shown in the current prompt; it is separate from the model budget.
For a model Millwork provides, both come from your Millwork credit. With your
provider account, Millwork charges the platform fee and your provider bills
model usage. A model call already running can exceed its budget; the budget
stops further calls once recorded spend reaches it.
Model access and billing lists the default fee and
explains charges and refunds.Review the plan in the terminal, including its effects and costs. Answer
y
to approve those effects or n to stop. A funded plan for a model Millwork
provides can include both the free test and the paid run in this first approval.If setup needs provider access, complete the browser step it shows.
OpenRouter asks you to sign in and approve access. For a provider that uses an
API key, enter its key on Millwork’s private setup page. For AWS Bedrock, enter
a short-term Bedrock API key there. Millwork lists
your available system profiles and matches the Bedrock model you selected; STS is an
advanced option you select explicitly. Keep provider
credentials out of the terminal and chat.Return to the same terminal. It waits for the browser step, tests the
connection and continues. If the browser does not open, use the private link
printed in your terminal before its displayed expiry. To skip automatic
browser opening, add --no-browser to setup. On a remote terminal,
open that link on your browser device. If the command stopped, continue with
the application ID below.If a coding assistant started setup, it keeps the application ID and opens
your normal system browser. Complete the private browser step, then return
to the assistant; it continues the same application. Use your own terminal
only if the assistant cannot show the private setup step safely.
In the browser, check that the Millwork organization matches the one whose
key you configured. If it is wrong, sign out and sign in to the intended
organization before completing setup.Tell the assistant when you have finished; share the application ID, not the
setup link. Finishing the browser step does not start a paid run.Millwork saves the progress as a setup application. Keep the
Application: ID so you can continue this setup if the terminal closes.3
Check access, then approve the model run
Setup first performs a test run (the API calls it Echo). It does not call
a model, so it has no platform fee and no model cost. It counts toward your
run quota. A test run alone does not finish setup.For your provider account, the CLI then shows the proposed model run and
asks for a separate approval. The same applies when setup paused for credit.
A run is one task you send to Millwork; the API calls it an
execution.
Before answering y, check the model and provider, who pays for model usage,
the platform fee, model budget, and runtime limit. Also review the data rules
for the task.If setup asks for credit, add credit and continue
with the same application. Review the new prompt before approving paid work.4
Read the answer and keep the receipt
On success, the CLI prints
First live result ready., your answer, the receipt
ID, model usage, platform fee, and remaining credit. It also selects the model
for future CLI tasks.Setup is complete when you have a live model result and a receipt naming which
model and provider answered.The receipt summary says No check connected. Millwork checked that an answer
was present, but did not check whether it was correct. You can finish setup
without your own output check.To check future answers against your own rules, follow
Connect an output check. Begin with that
guide’s installed-client check. If the installed help does not include
verifier init, verifier connect, and verifier test --local, stop; that
client cannot complete the output-check journey. Do not substitute an older
global CLI.The guide supplies the complete public and protected connection commands,
checks readiness before retaining the saved check ID, and stops after
connection when you do not want a model run. Its later section shows how to
select the saved check for a task and confirm its result on the receipt.If credit is shown as unavailable or not visible, the answer and receipt are
still retained. Ask an organization owner to check
Billing; an unavailable
balance does not mean zero credit.Run your next task
To use the shortermillwork commands below, install the CLI:
millwork --version --json before using an existing global installation.
If it differs from the version saved for your setup, use the exact npm command
from Keep the CLI version for this setup.
If your shell says millwork: command not found, see
Use the CLI without a global install.
Read your current model and its preset, the saved data and budget settings
used during setup:
Preset: line for another public-data task:
pooled-open-model-public-v1; your connected provider model uses
byok-open-model-public-v1. The preset must match your current model.
The command prints the answer, run status, receipt ID, and the receipt’s model
usage and platform fee on separate lines. Run
millwork tenant show again to read your current Millwork credit.
Change your model
Read your current selection withmillwork tenant show, then list the choices:
millwork tenant show and use its current preset for the next task.
Declining or failing setup keeps your previous selection. If a choice is
refused, check model availability.
Use the CLI without a global install
A successful global install can leavemillwork outside your shell’s PATH.
You can keep using the CLI through npm:
npm prefix --global and add
the bin directory inside that path to your shell’s PATH. Open a new terminal
and run millwork --version --json to confirm it is found.
Disconnect your provider account
To stop Millwork using a connected provider account, disconnect it:Continue an interrupted setup
Saved-application responses can include a private setup link. If an assistant runs the JSON commands below, it must capture stdout and stderr privately before reading selected non-secret fields, as the agent guide describes. Keep raw responses out of chat and shared logs. Read progress without continuing any work:--idempotency-key and keys from --new-setup are not replaced.
If that retry cannot finish, JSON output returns application_key and a
next_action.command. After an uncertain response, the command continues the
same approved request. After a refusal, such as an expired approval or another
key conflict, it inspects the saved request without changing it. Read the
reported problem before continuing; do not repeat a rejected approval. Keep
the key. Once you have an application ID, continue by that ID. If local recovery
data is unavailable, use your saved key or application ID.
Continue without a terminal
With--json, or anywhere there is no terminal to answer a prompt, that same
command presents saved progress. It does not consume a finished browser
approval or authorize a paid run. An already queued or running live execution
can still be polled to its result and receipt. To consume browser approval,
name that step explicitly:
poll_consent takes up a browser approval that has already finished, moving
setup on to its connection test and model sync. If your application sits at
consent_pending while the approval is done, this is the step that was
missing.
Starting the paid run is separate. Continue only when next_action.type is
authorize_byok_live_proof or authorize_pool_live_proof and the application
has a current proposal. Otherwise follow its returned next action.
The live-proof digest is not the plan digest you approved at the start.
The plan digest approves its listed effects, which can include paid work for
a model Millwork provides. The later live-proof digest approves a separate
proposed run with its current fee and model-usage budget. Read these from the
application before you authorize:
The difference between the combined allowance and model budget is Millwork’s
fee. The allowance is not a final charge or guaranteed cap: a model call
already running can exceed its budget.
Pass the digest exactly as you read it; an expired digest is refused rather
than renewed. If any of these values is missing, keep the application and ask
for the missing spending details. After you explicitly approve this proposal,
submit its digest:
retry_consent for a fresh browser
approval on the same setup, retry_connection_test and retry_deployment_sync
after a provider-side failure, and refresh_byok_readiness or
refresh_pool_readiness to re-check before authorizing. Each needs its own
--idempotency-key. Use a new key for a new observation or action; keep the
same key when retrying the exact request after a lost response. Reusing a
previous poll’s key returns its old observation.
If you started without provider/model filters or a custom request key, and
the CLI did not replace the request key, look up that template with the
same Millwork key:
byok-open-model for your provider account, or starter for a free test.
If you supplied a request key, include it with --idempotency-key. If the CLI
returned a replacement application_key, use that value instead. Once you
have an application ID, use --application-id. A request key identifies
one operation across retries.
For provider connect or a start with source/model filters, this unfiltered
lookup may find a different setup or none at all. Use the application ID from
the original terminal output. If you lost it and did not choose a request key,
contact support before starting again. Repeating tenant start
can continue work; use tenant show when you only want to inspect it.
Add credit and continue
Open Billing, add credit, and confirm the updated balance. Then continue the same application with the command above. Adding credit does not approve a paid run; review its new spending prompt. If you cannot open Billing, ask an organization owner to help.Refresh a stale plan
A plan can stop matching before it expires if your credit, model choice, or organization settings change. If you have an application ID, continue that application to get the current proposal. If you have only a plan, request a new one with--plan --json and review it before applying its new digest.
An error naming digest means the plan needs another review, not a new API
key. If a request may already have started work, inspect its application and
run first. Do not start a second application to find out what happened.
Provider access expired
An expired browser link needs a fresh browser step on the same saved application. A spending proposal has its own expiry and needs a new review. If the provider has revoked or expired your credentials, replace access on the existing connection before another model call. AWS access has its own deadline: renew the key or STS session on the same connection. A new setup link or spending approval does not extend that access. Renewal keeps the connection’s existing method.Model not ready for setup
If setup refuses a model from your catalog, keep your current selection and read the reason. The model may not be available for setup through the chosen provider account, or the provider may be unable to serve it. Choose another available model or contact support with the model key and safe error details. Connecting your own account is a separate choice that changes who bills model usage.Manage your provider connections
Runmillwork provider list to see available providers separately from your
existing connections and their saved models. Use a source ID to set up a
provider, or a connection ID to manage access you already saved.
Rotation and disconnect act on the named connection. They do not approve a
paid run or choose another model. The TypeScript SDK exposes
the corresponding API operations through
sourceConnections.
If your organization cannot start
Use a coding assistant or script
Approve a plan in a script
In a non-interactive session, planning and applying are two separate commands. First save the plan locally; this does not create a setup application:effects, digest, issued_at, and expires_at.
request_policy.budget.max_cost_usd is the model budget. maximum_spend_usd
combines that allowance with the configured platform fee; it is not a final
quote or a guaranteed spending cap. Applying the digest approves the effects listed
in that exact plan, including paid work when listed. Apply only a current,
unexpired plan you have approved:
--template byok-open-model to both commands.
Keep the returned application_id and follow its next_action. --json
changes the output format; it does not make the command read-only. Browser
setup remains a separate step. With --json, the CLI leaves browser launch
to you unless you request --open-browser. That flag opens a current setup
link; it does not poll for consent or approve a paid run. It cannot be combined
with --no-browser. The assistant keeps the application and its response
private, opens your normal system browser, and continues after you finish.
Use the explicit JSON steps to consume consent
and, after your approval, authorize the later paid proposal.
Use a coding assistant explains the
private-terminal fallback if the browser step cannot be shown safely.
Choose a provider and model in a script
First read the available choices without creating a connection:--source-id aws_bedrock --auth-scheme aws_sts_sigv4 to that first command.
Keep --auth-scheme aws_sts_sigv4 on both the exact plan and apply commands
below; continuing an existing setup keeps its selected method.
Read byok_offerings for the source, authentication method and model choices.
Pick source_id and served_variant_id from the same offering and check its
auth_scheme, then request its exact plan:
digest and issued_at:
--model-deployment-id.
Repeat it when applying; any source or model filters you add must match it.
--served-variant-id requires --source-id, and both apply only to
byok-open-model. A plan command cannot open a browser or apply changes.
For scripts, choose and save an --idempotency-key when applying the plan.
Keep it for that setup. It lets you look up the application with
tenant show --template byok-open-model --idempotency-key "<original key>" --json.
Without a custom key, the CLI derives one from the template and source/model filters. After setup starts, save its application ID and
use the continuation command. Changing a key
to investigate a lost response can start another setup.
Setup writes no project files unless you add --write after reviewing the
plan’s file_manifest. Existing files are never overwritten.
For local diagnostics, run millwork --version --json, millwork docs --json,
or millwork doctor --json. They do not call the API or print your key.
doctor exits with status 1 if a key is not configured or a local check fails.
Prefer direct API calls? Run a model walks through
choosing a catalog model and reading its result and receipt.