CLI Setup

Install the command-line tool for creating apps.


Prerequisites

For Python Apps: uv

The CLI uses uv for Python environment management:

bash
1curl -LsSf https://astral.sh/uv/install.sh | sh23# Windows4powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

For Node.js Apps: Node.js

Node.js v20 or later:

bash
1# macOS / Linux (via fnm)2curl -fsSL https://fnm.vercel.app/install | bash3fnm install 2245# Or via nvm6curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash7nvm install 22

Hardware

App TypeDevelopment Environment
CPU appsAny machine
GPU appsRequires NVIDIA CUDA GPU

Install CLI

bash
1curl -fsSL cli.inference.sh | sh

Or via package managers:

bash
1brew install inference-sh/tap/belt       # macOS / Linux2npx @inferencesh/belt                    # Node.js3scoop bucket add inference https://github.com/inference-sh/scoop-bucket && scoop install belt  # Windows

Command name

The same CLI is available as belt, infsh, and inferencesh (package installs may expose one or all of these names). Subcommands are identical:

bash
1belt version2infsh version    # same CLI

Connector and MCP examples in this documentation often use belt. App development examples use infsh. Either prefix works.


Verify

bash
1infsh version

Update CLI

bash
1belt update    # or: infsh update

Auto-update runs in the background on most commands. It is skipped for belt version, belt update, and help flags. Set INFSH_NO_AUTOUPDATE=1 to disable automatic upgrades.


Login

bash
1infsh login2belt login --key inf_   # non-interactive: skip browser flow (CI, scripts)

Opens a browser for device authorization in interactive terminals. In non-interactive shells (no TTY, CI set, or BELT_NON_INTERACTIVE=1), pass --key or set INFSH_API_KEY instead.


Check your account

bash
1infsh me2belt me --json    # same payload as GET /me — for scripts and automation

Shows your username and team. When a team override is active, belt me prints a hint to use belt auth switch.

With --json, stdout is the indented GET /me response (user and team objects). See Teams API — Get current user. On failure, diagnostics go to stderr only — stdout stays empty (no {"error":...} object).


Switch teams

If you belong to multiple teams, switch the active team context for all CLI commands:

bash
1belt auth switch              # interactive team picker2belt auth switch my-org       # switch directly by team username3belt auth sw my-org           # alias

The CLI stores the override in ~/.inferencesh/config.json and sends it as the X-Team-ID header on API requests. Switching back to your default team clears the override.


bash
1belt auth token

Prints the stored API key to stdout with no trailing newline — for subshells, curl, and shell scripts:

bash
1curl -H "Authorization: Bearer $(belt auth token)" https://api.inference.sh/me2export INFSH_API_KEY=$(belt auth token)

Requires belt login first (or INFSH_API_KEY set in the environment). When not logged in, errors go to stderr and stdout stays empty.


What you can do

Development

CommandPurpose
infsh app initCreate a new app
infsh app testTest locally
infsh app deployDeploy to inference.sh

Running Apps

CommandPurpose
infsh app runRun an app in the cloud
infsh app sampleGenerate sample input

When an app is missing required secrets or integrations, infsh app run (and belt agent run) prints categorized setup hints instead of a generic API error — for example belt secrets set <KEY> <VALUE> or belt integrations connect <provider>. MCP requirements suggest belt mcp connect <slug>. The same requirement shape is returned by POST /run as HTTP 412 — see Check requirements.

Managing Apps

CommandPurpose
infsh app myList your deployed apps
infsh app listBrowse available apps
infsh app searchSearch apps by name or description
belt suggest <query>Unified discovery (apps, skills, knowledge, docs)
infsh app getGet app details
infsh app pullDownload or sync an app

infsh app pull syncs app code and metadata from inference.sh:

bash
1infsh app pull              # sync current app (from inf.yml in cwd)2infsh app pull --meta       # sync inf.yml metadata only (no code)3infsh app pull <app-id>     # download app by ID to namespace/name/4infsh app pull --all        # sync every local app (finds inf.yml recursively)5infsh app pull <app-id> --force   # overwrite existing directory without prompt

Pulled apps write namespace, name, and other metadata into inf.yml so deploy and run commands resolve the correct namespace/name ref.

When syncing an existing directory, the CLI removes old app files before extracting the new archive but preserves local environment and VCS paths: .git, .env, .infsh, .venv, venv, node_modules, and __pycache__.

belt suggest calls the same discovery API as GET /suggest. Results include a suggested CLI command or URL for each hit:

bash
1belt suggest "flux image"2belt suggest "web search" --json     # JSON for agent hooks3belt suggest "deploy" --agent        # full descriptions from API (agent: true)

With no arguments, belt suggest reads stdin (hook JSON or plain text). CLI args take precedence over stdin.

Hook mode (--json): Returns hookSpecificOutput.additionalContext with one line per match: - [type] name — description, then run: <command> on the next line. Results are ranked by score and deduped server-side. When stdin is hook JSON with transcript_path, belt prepends assistant text from the current turn (up to 1000 characters) before searching.

Use --agent to send agent: true in the suggest request body (full descriptions, no 200-rune truncation). Hook integrations installed via belt plugin init <agent> call belt suggest --json automatically.

Use infsh app search when you only need apps. Use belt suggest for cross-collection discovery (skills, knowledge, docs, and apps).

Search concept · Search API

Secrets

CommandPurpose
infsh secrets listList all secrets
infsh secrets set <key> <value>Create or update a secret
infsh secrets get <key>Get a secret (masked)
infsh secrets delete <key>Delete a secret

Connectors (MCP)

CommandPurpose
belt mcp listBrowse MCP connector servers
belt mcp get <slug>Show server details and connection status
belt mcp connect <slug>Connect OAuth for a server
belt mcp refresh <slug>Re-run discovery and enrichment on a server
belt mcp tools <slug>List tools on a connected server
belt mcp run <slug>:<tool>Call a connector tool from the terminal

Connectors overview · Browsing connectors

Integrations (CLI)

List, connect, and inspect OAuth, service account, and MCP connections for your team:

CommandPurpose
belt integrations listList connected integrations (--json for raw API payload)
belt integrations get <provider>Show one integration by provider key (--json for scripts)
belt integrations connect <provider>Connect a native provider (OAuth or service account)
belt integrations disconnect <provider>Remove a team connection
bash
1belt integrations list2belt integrations get google3belt integrations get mcp:mcp.linear.app --json   # includes integration id for agent tools4belt integrations connect google5belt integrations connect slack6belt integrations disconnect google

belt integrations connect looks up the provider in GET /integrations/configs, opens your browser for OAuth when needed, and polls for up to two minutes. If the provider is already connected, the CLI prints the account and suggests disconnecting first. Unknown providers list available options; for MCP servers, use belt mcp connect <slug> instead.

Google OAuth and the managed service account are separate providers (google vs google-sa). Connect the service account from Settings → Integrations (google-sa slug) or with belt integrations connect google-sa.

Non-interactive OAuth (CI, scripts): When stderr is not a TTY, CI is set, or BELT_NON_INTERACTIVE=1, belt integrations connect prints the authorization URL but does not open a browser or poll. Open the URL manually, then verify with belt integrations get <provider>.

Provider keys match the REST API: google, google-sa, gcp, slack, mcp:mcp.linear.app, and so on. MCP servers use compound names (mcp:{hostname}) because each connection is a separate instance. Use belt integrations get --json when you need the integration id for agent connector tools.

Integrations API · Connectors overview

Flows (CLI)

Create, edit, run, and publish flows from the terminal — same APIs as Flows and Flow Runs.

CommandPurpose
belt flow create --name <name>Create an empty flow (--json for raw response)
belt flow listList your flows (ls alias; --json)
belt flow get <id>Show flow metadata (--json)
belt flow describe <id>Show the full graph with node I/O fields and connections
belt flow duplicate <id>Copy a flow (dup / cp aliases)
belt flow delete <id>Delete a flow
belt flow run <id>Start a flow run (--input JSON, -f to stream progress)
belt flow runsList recent flow runs (--limit, --json)
belt flow run-get <run-id>Get run status and output (-f to follow until complete)
belt flow cancel <run-id>Cancel a running flow
belt flow publish <id>Deploy the flow as a standalone app

Graph editingbelt flow edit applies draft mutations via POST /flows/{id}/actions:

CommandPurpose
belt flow edit node add <id> <name> --app <ref>Add an app node (resolves namespace/name to app ID)
belt flow edit node rm <id> <name>Remove a node
belt flow edit node inspect <id> <name>Show input/output fields with types and defaults
belt flow edit node set-input <id> <name> <key> [value]Set a static value or --from node:key connection
belt flow edit node clear-input <id> <name> <key>Clear an input value or connection
belt flow edit edge add <id> <source> <target>Add a structural edge between nodes
belt flow edit edge rm <id> <source> <target>Remove an edge
belt flow edit output set <id> <field> --from <node>:<key>Map a node output to the flow output
belt flow edit output rm <id> <field>Remove an output mapping
belt flow edit set-schema <id> --input '...' --output '...'Set flow-level input/output JSON Schema (type must be "object"; see Flows API)
belt flow edit actions <id> [json]Apply raw action JSON (escape hatch for uncovered mutations)
bash
1belt flow create --name voice-pipeline2belt flow edit node add abc123 tts --app elevenlabs/tts3belt flow edit node set-input abc123 tts text "hello world"4belt flow edit node set-input abc123 voice-changer audio --from tts:audio5belt flow edit output set abc123 audio --from voice-changer:audio6belt flow describe abc1237belt flow run abc123 -f8belt flow publish abc123

Use input as the source node in --from to wire a node input to a flow-level input (for example --from input:text). belt flow run -f streams NDJSON progress events with polling fallback when SSE is unavailable.

Flows guide · Creating a flow · Flows API · Flow Runs API

Agent integration (CLI)

Wire belt into a local coding agent runtime (discovery hooks and core skills):

CommandPurpose
belt plugin init claudeInstall belt plugin for Claude Code (marketplace; patches cached hook shims after install)
belt plugin init codexInstall belt plugin for OpenAI Codex (requires Codex CLI)
belt plugin init cursorInstall belt skills and hooks for Cursor
belt plugin init geminiInstall belt skills and hooks for Gemini CLI
belt plugin init windsurfInstall belt skills and hooks for Windsurf
belt plugin infoShow belt plugin capabilities and install status
belt plugin doctorCheck Claude Code belt plugin health (--fix to auto-repair stale caches and hook shims; lists each fix and prompts restart)
belt plugin historyImport knowledge from Claude Code conversation history
belt review --agent <name>Extract knowledge from agent sessions (hook command)

belt review is called by Stop and PreCompact hooks installed via belt plugin init <agent>. Claude Code plugin hooks call belt plugin review instead. It reads hook JSON from stdin, evaluates the session transcript, and saves reusable knowledge to your workspace.

bash
1belt review --agent cursor --trigger stop        # called by Cursor Stop hook2belt plugin review --trigger stop                # called by Claude Code Stop hook3belt review --agent claude-code --trigger stop   # same pipeline as belt plugin review4belt review --agent codex --dry-run                # preview without saving5belt review --agent cursor --force                 # skip 10-turn gating
FlagPurpose
--agentRuntime: claude-code, codex, cursor, gemini, or windsurf (defaults to claude-code)
--triggerHook that invoked review: stop, precompact, or session-end (default stop)
--forceRun immediately instead of every 10 user turns on Stop
--dry-runPrint extraction results without saving

Claude Code uses fork-based extraction and can auto-publish skills. Other agents use transcript-based extraction through the inference.sh API. Requires belt login.

Coding agents — skills directories, hook behavior, and Claude Code details

Agents (CLI)

CommandPurpose
belt agent create <name> [description]Create an agent from flags (no YAML file)
belt agent deploy <path>Create or update an agent from a YAML definition
belt agent listList your agents
belt agent delete <ref>Delete an agent (rm alias)
belt agent run <ref> "<message>"Run an agent from the terminal
belt agent run <ref> "<message>" --chat <id>Continue an existing chat
belt agent run <ref> "<message>" --no-waitReturn chat ID immediately (use belt chat to follow up)
belt agent run <ref> "<message>" --timeout <duration>Max wait for response (default 4m; e.g. 10m)

belt agent create calls POST /agents with a first version. Use it for quick agents from the terminal; use belt agent deploy when you need skills, context fields, output schema, or other YAML-only options.

Redeploying the same agent name creates a new version instead of failing with a name conflict — the same upsert behavior as infsh app deploy. The namespace is assigned from your logged-in team server-side, so the namespace field in YAML is optional. You only need a stable name in the file to update an existing agent.

bash
1belt agent create my-helper "A helpful assistant"2belt agent create todo-bot --model openrouter/claude-sonnet-46 --prompt "You manage Todoist tasks"3belt agent create todo-bot --model openrouter/claude-sonnet-46 \4  --mcp 46e8a4bq...:find-projects \5  --mcp 46e8a4bq...:add-tasks6belt agent create my-bot --json    # raw AgentDTO on stdout
FlagPurpose
--modelCore app ref (e.g. openrouter/claude-sonnet-46)
--promptSystem prompt
--mcpMCP tool as integration_id:tool_name (repeatable). Find integration IDs after belt mcp connect — see Connector tools on agents; list tool names with belt mcp tools <slug>
--jsonOutput the created agent as JSON

On success, the CLI prints namespace/name@version-id for use with belt agent run.

Without --no-wait, belt agent run streams chat events until the agent finishes, needs approval, or hits --timeout (default 4m). On timeout, the CLI prints the chat ID so you can follow up with belt chat get or belt chat pending. Tool calls print as muted progress lines while they run:

code
1 calling search...2 search completed

Failed tools print → {name} failed. The final assistant message is printed when the run completes.

Chat (CLI)

Manage agent conversations and human-in-the-loop approvals from the terminal:

CommandPurpose
belt chat listList chats (--status busy, awaiting_input, idle, completed)
belt chat get <chat-id>Show transcript and pending tool invocations
belt chat send <chat-id> "<message>"Send a follow-up message
belt chat watch <chat-id>Stream until idle or another approval is needed
belt chat pendingList tool invocations awaiting approval
belt chat approve <invocation-id>Approve HIL tool (--watch / -w to stream the response)
belt chat reject <invocation-id>Reject (--reason "...")
belt chat stop <chat-id>Stop a running chat

When belt agent run stops at awaiting_input, the CLI prints belt chat approve / reject commands for each pending invocation.

Agents REST API · Approval settings · Human-in-the-loop

Skills (CLI)

CommandPurpose
belt skill use <namespace>/<name>Print a skill's instructions to stdout
belt skill add <namespace>/<name>Install a skill into your workspace
belt skill files <namespace>/<name>List supporting files (references, scripts, examples)
belt skill view <namespace>/<name> <path>View one supporting file

belt skill use does not inline supplementary files. When a skill has extra files, stderr prints tips for belt skill add and belt skill files.

Skill registry · Search concept · Search API

Knowledge (CLI)

belt know is an alias for belt knowledge. Refs use namespace/name or namespace/name@version-id (same as the REST API). The CLI sends X-API-Version: 2 on API calls automatically.

CommandPurpose
belt know listList entries (--type, --search, pagination)
belt know search <query>Search your knowledge entries
belt know get <ref>Show metadata, file list, and instructions (up to 64KB)
belt know upload <path>Upload a directory, file, or stdin (--type, --name)
belt know delete <id>Delete an entry
bash
1belt know list --type observation2belt know get acme/onboarding              # latest version (no login for public entries)3belt know get acme/onboarding@abc123       # specific version4belt know upload ./my-skill/               # directory with SKILL.md → skill5belt know upload ./notes.md --type reference

When belt know get finds supplementary files (references, scripts, examples), the CLI prints tips for belt skill add and belt skill files so you can install or inspect them locally.

Knowledge API · Creating skills

Feedback (CLI)

Submit customer-discovery answers and open feedback. Responses are stored on your account via POST /me/survey (requires belt login).

CommandPurpose
belt feedbackList pending survey questions (or show answers already submitted)
belt feedback <question-id> "<answer>"Answer a structured question
belt feedback "<message>"Send open feedback (question_id = open)

Structured question IDs: discovery, use_case, feedback.

bash
1belt feedback                                    # see what's pending2belt feedback discovery "found it on github"3belt feedback use_case "building AI agents for customer support"4belt feedback "love the speed, wish there were more templates"

After most commands, the CLI may show one unanswered question in the tips area (stderr). Each question has its own 72-hour cooldown; after you answer one, the next unanswered question appears on the following command. When all three structured questions are answered, a one-time freeform prompt suggests belt feedback "...".

The same questions can appear in coding-agent hook context via belt suggest --json — agents can run belt feedback on your behalf. Submissions include optional metadata: agent (detected runtime, e.g. cursor) and context (your five most recent belt commands, comma-separated).

The CLI records the last 10 commands you run in ~/.belt/history (via the post-command tips hook; skipped for belt feedback itself and when tips are suppressed with INFSH_NO_TIPS=1 or --json). When you submit feedback, the last five entries are sent as context.

Suppress survey prompts and other stderr tips with INFSH_NO_TIPS=1.

Survey API · Coding agents — hook context

Tasks (CLI)

CommandPurpose
belt task listList recent tasks (--status, --limit, --cursor, --app)
belt task get <id>Get task status and output (-f / --follow to stream until complete)
belt task logs <id>View execution logs (--type to filter; -f to tail live output)
belt task cost <id>Show cost breakdown in microcents
belt task timings <id>Show timing breakdown by phase
belt task cancel <id>Cancel a running task

For HTTP equivalents, see Tasks API (list, logs, timings, telemetry, and status endpoints). Resource telemetry is available via GET /tasks/:id/telemetry or client.tasks.getTelemetry(id) in the JavaScript SDK.


JSON output (--json)

Many commands accept --json for machine-readable output (belt task get, belt agent list, belt chat send, and others). belt me --json is an exception: it prints the API payload on success but does not emit a JSON error object on failure.

On failure with --json active, the CLI writes a JSON error object to stdout in addition to the human-readable message on stderr:

json
1{"error": "not logged in or session expired. run 'belt login' to authenticate"}

Parse stdout for automation; ignore stderr unless you need the formatted message. Successful --json responses use the command-specific schema documented in each command's help (belt task get --help).

Billing and plan limits

Billing and plan-limit errors include upgrade URLs in the error string when the API returns entitlement metadata (upgrade_available: true).

Error kindTypical messageWhat to do
Insufficient balanceBilling URL in messageAdd credits at Billing
Plan limitSubscription URL in messageUpgrade at Subscription
Not logged inSession expiredRun belt login

Inspect usage programmatically with GET /entitlements/usage — see Entitlements API.

Billing API · Subscription API · Troubleshooting — Plan limits


Environment Variables

VariableDescription
INFSH_API_KEYAPI key (overrides config file)
BELT_NON_INTERACTIVEForce non-interactive mode (skip browser login, MCP OAuth polling, spinners, and stdin prompts). Also set automatically when CI is truthy.
INFSH_NO_AUTOUPDATEDisable automatic CLI updates
INFSH_NO_TIPSDisable stderr tips and survey prompts after commands
INFSH_ENGINE_BINPath to a custom private engine binary

Shell Completions

bash
1infsh completion bash  # or zsh, fish, powershell

Next

Coding Agents — Build with AI assistants

Creating an App — Manual setup

we use cookies

we use cookies to ensure you get the best experience on our website. for more information on how we use cookies, please see our cookie policy.

by clicking "accept", you agree to our use of cookies.
learn more.