Where things are
Driving the CLI
- Read the surface first:
simforge --helplists the commands,simforge <command> --helpgives one command’s flags. Never guess a flag. - Parse stdout as one JSON document. On failure, key on
codein the stderr JSON and follow itshint. - Exit 1 means fix the invocation or install what is missing. Exit 2 means the input itself is wrong: report or repair it, do not retry it unchanged.
- Sign-in needs a person:
simforge login --deviceprints a URL and code. Relay them to the user and wait. Never print or store tokens. - Cloud runs cost money. Always price with
--dry-runfirst and pass a--max-costno higher than the budget you were given. - Long-running servers (
simforge env serve,simforge world serve,simforge mcp) run until stopped: start them in their own terminal, not inside a call that waits for them to finish.
Signing in without the CLI
An agent that calls the hosted API (/api/v1) directly signs in through auth.md, the recipe for agent sign-in that every /api/v1 401 points to (WWW-Authenticate: Bearer resource_metadata=…). The agent registers with the email of the person’s SimForge account and shows the person a link and a code. The person signs in on simforge.ai, enters the code, chooses the organization and approves. The agent then gets a one-hour access token and an identity assertion that renews it.
Only that account can approve, and only once its email is verified. The person sees the agent under Account → CLI sessions and can revoke it there. A backend with no person at hand uses an API key instead.
MCP
simforge mcp serves the CLI over the Model Context Protocol (stdio). By default it lists a small core set of tools (under 40 KB of schemas): the authoring, render and run commands, plus a simforge tool that runs any other command from its argv. --profile full lists every command as its own tool; --only render --only scenario lists the commands under those paths; --cwd sets the working folder. Inputs are typed with each flag’s allowed values, range and default; annotations mark read-only, destructive and idempotent tools. Every call runs the same binary and returns the command’s JSON result, exit code and error once, as structured content, with a one-line text summary. Local runs are the default; a tool call with cloud: true and a max-cost runs hosted.