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

Shell installer (curl … | sh): belt update downloads and replaces the binary in place.

Homebrew or Scoop: the CLI detects package-manager installs and refuses to self-update over a managed binary. Run the manager's command instead:

bash
1brew upgrade belt    # Homebrew2scoop update belt    # Scoop

If you installed with brew install inference-sh/tap/belt or scoop install belt, belt update prints the matching command when an upgrade is available.

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.

Credentials are stored in ~/.inferencesh/config.json with 0600 permissions (owner read/write only).


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 compact JSON for the GET /me response (user and team objects). Use --pjson for indented output. See Teams API — Get current user. On failure, stdout is a JSON error object (same as other --json / --pjson commands); stderr still has the formatted message.

Balance: belt balance is a top-level alias for belt me balance (agents often try belt balance first). It prints your team's current balance and nudges you to top up when below $5. Use --json for {"balance": <microcents>, "balance_dollars": <float>}.

bash
1belt balance2belt me balance --json

Requires billing:read scope (included in standard API keys). See Billing API.


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 shell

Running Apps

CommandPurpose
infsh app runRun an app in the cloud
infsh app sampleGenerate sample input (file fields use ./your-file.jpg placeholders)

For multi-function apps, belt app sample defaults to the resolved default function (run, explicit default_function, or the sole function). Use -f / --function for other entry points. belt app get lists all functions with run/sample hints.

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.

JSON inputbelt app run, belt mcp run, and belt flow run resolve input from three sources, in priority order: --input / -i flag → positional argument → piped stdin (when stdin is not a TTY). Each source accepts inline JSON ('{"prompt": "a cat"}'), @filename, or a path to an existing JSON file.

bash
1belt app run namespace/my-app '{"prompt": "a cat"}'          # positional2echo '{"prompt": "a cat"}' | belt app run namespace/my-app   # stdin3belt mcp run linear:list_issues '{"project": "INF"}'         # positional4belt flow run abc123 --input '{"text":"hello"}' -f           # flag (unchanged)

Omit input entirely when the app, tool, or flow does not require it.

Filter output (--jq)belt app run and belt mcp run accept --jq with a jq expression to filter JSON on stdout without piping to an external jq binary (the CLI embeds the same pure-Go engine GitHub CLI uses). String results are printed unquoted (like jq -r); other values are compact JSON, one per line.

bash
1belt mcp run linear:list_issues --jq '.issues[] | {id, title}'2belt app run okaris/flux -i '{"prompt": "a cat"}' --jq '.output.url'3belt app run okaris/flux -i '{"prompt": "a cat"}' --no-wait --jq '.id'   # task id only

belt app run --jq evaluates against the task object (id, status, status_text, output, error, session_id, created_at, updated_at). App outputs live under .output — for example .output.url for a generated file URL. --jq suppresses progress lines on stdout (same as --json). Use --json or --pjson when you need the full task or tool payload instead.

Managing Apps

CommandPurpose
belt app listList your deployed apps (--search, --limit, --cursor, --json; infsh app my / infsh app list aliases)
belt app storeBrowse the public app store (--featured, --category, --new, --limit, --cursor, --json, --save)
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

Programmatic listing:

bash
1belt app list --json                         # your deployed apps (requires login)2belt app list --search "flux" --json3belt app list --limit 50 --cursor <next>     # cursor pagination (see hints in table output)4belt app store --json                        # public store with cursor pagination metadata5belt app store search "video" --category video --json6belt app store --save store-snapshot.json    # write JSON to file instead of stdout

belt app list --json prints the full cursor-list response from POST /apps/list (items as AppDTO[], plus next_cursor, has_next, total_items, …). belt app store --json prints the same cursor-list shape from POST /store/apps/list (items as PublicAppStoreDTO[]) — see List approved apps. In table output, both commands print next page: / prev page: hints with the --cursor value when more results exist. --save writes the store payload to a file (always pretty-printed) and prints a confirmation line to stdout.

infsh app pull syncs app code and metadata from inference shell:

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 app get shows schemas, pricing, and run/sample hints for an app ref (namespace/name, namespace/name@version-id, or app ID). With --json, stdout is {"app": <AppDTO>, "pricing": ...} from GET /apps/{ref}.

bash
1belt app get okaris/flux2belt app get okaris/flux@abc123 --versions   # version history3belt app get okaris/flux --json              # includes status fields for scripts

When lifecycle status is not active, human-readable output shows a banner after the description:

StatusDisplayRun hints
deprecated⚠ deprecated (warning) plus optional status_messageShown — app still accepts runs
maintenance⚙ under maintenance (warning) plus optional status_messageOmitted — the banner already indicates runs are unavailable
retired✕ retired (error) plus optional status_messageOmitted — the banner already indicates runs are unavailable

belt app run against a maintenance or retired app returns API errors (503 app_maintenance, 410 app_retired) — see Tasks API. Use belt app get before scripting runs to check status and the owner's message (for example, a replacement app ref).

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.

Human-readable output groups results by category (app, skill, knowledge, and so on). Each section header shows the category and a command template (for example belt skill use <name>). Result lines include an optional inline [tag], the name, and description. After a cross-collection search, stderr may suggest scoped follow-ups such as belt app suggest "...".

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. Hook stdin is JSON with a prompt field (or plain text). When transcript_path is present, belt extracts assistant text from the current turn (since the last user message, up to 1000 characters) and sends it as the context field to POST /suggest for semantic ranking — keyword matching still uses prompt only. Belt also sends scope signals from the current directory (git: remote, lang:, module:, and similar tags) on every suggest call so knowledge captured in the same repo or language ranks higher. API failures are silent in --json mode so hooks do not pollute agent stderr.

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.

belt suggest also sends scope tags from the current working directory (git remote, module name, language, path) so project-relevant knowledge ranks higher in results. Entries uploaded with belt know upload carry the same tags unless you used --global.

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 (--json)
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 (--category, --featured, --json)
belt mcp search <query>Search servers by name or description (same filters as list)
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 (slug:tool to show one tool's schema)
belt mcp run <slug>:<tool>Call a connector tool from the terminal (<slug> alone lists tools, same as mcp tools)

belt mcp run and belt mcp tools use slug:tool format — the first colon splits the server slug from the tool name (for example linear:list_issues). Pass only the slug to belt mcp run to list available tools instead of calling one. If you mistype an MCP subcommand, the CLI prints this format hint. After belt mcp list, stderr may show tips for belt mcp search, get, and connect.

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 opencodeInstall belt skills and OpenCode plugin (npm install + opencode plugin --global when CLI is on PATH)
belt plugin init piInstall belt skills and Pi TypeScript extension (pi install when Pi CLI is on PATH)
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 shell 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 get <ref>Show agent details (version, tools, skills, context)
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.

belt agent get accepts the same refs as belt agent runnamespace/name, namespace/name@version-id, or agent ID. With --json, stdout is the full AgentDTO from GET /agents/{ref}.

bash
1belt agent get myteam/support-bot2belt agent get myteam/support-bot@latest3belt agent get agent_abc123

Human-readable output uses lowercase labels and lists attached skills with their resolved ref and version pin:

code
1  agent:  myteam/support-bot2  version: abc1233  description: Handles customer support4  system prompt: You are a helpful support agent...5  core app: openrouter/claude-sonnet-4667  tools:8    - search (call): Search the web910  skills:11    - myteam/pricing-rules@ver_xyz: Pricing guidelines1213  context:14    - tenant_id (required): Tenant identifier

Each skill line shows skill_id@version_id when the agent pins a specific skill version; otherwise it falls back to the skill name from the agent definition. System prompts longer than 200 characters are truncated.

With --no-wait, the CLI returns as soon as the run is accepted. Without --json, it prints Chat started: <chat-id> with muted belt chat get / belt chat pending hints. With --json --no-wait, stdout is only {"chat_id": "<id>"} — use this in scripts that poll with belt chat get or belt chat watch.

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. With --json (and no --no-wait), stdout is the full POST /agents/run response after streaming completes. 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. After a successful run, the CLI prints a muted continuation hint with the chat ID — use belt chat send <chat-id> "<message>" for follow-ups without starting a new run.

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); prints a continuation hint below the table
belt chat get <chat-id>Show transcript and pending tool invocations (--last N, --all, --full)
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.

belt chat get shows the last 3 messages by default. Use --last N for more, --all for the full transcript, or --full to disable truncation of message text and tool argument JSON (default truncates at 200 and 100 characters respectively). Pending tool invocations always show full args and an approve: hint.

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

Skills (CLI)

Refs use namespace/name or namespace/name@version-id (same as the REST API). belt skill use without a version fetches the latest.

CommandPurpose
belt skill listList your uploaded skills (--json; table includes relative updated times)
belt skill upload <path>Publish or update a skill from a local directory
belt skill use <ref>Print a skill's instructions to stdout
belt skill add <ref>Install a skill into your workspace
belt skill files <ref>List supporting files (references, scripts, examples)
belt skill view <ref> <path>View one supporting file
belt skill versions <namespace>/<name>List version history (version ID, date, notes)
belt skill supersede <old> <new>Mark an outdated skill as superseded by a replacement

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.

belt skill versions requires belt login — it resolves the skill by name, then calls GET /knowledge/{id}/versions. The table marks the current version at the bottom.

belt skill supersede requires belt login. Both arguments are namespace/name refs or skill IDs. The old skill is hidden from belt suggest and other discovery results; the replacement skill is unchanged. Use this when you publish a replacement under a new name instead of versioning in place.

bash
1belt skill versions myteam/code-review2belt skill use myteam/code-review@abc123   # specific version3belt skill supersede myteam/old-review myteam/code-review

Skill registry · Supersede Skill API · Search concept · Search API · Knowledge API — versions

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, --json, 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, --global)
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 reference6belt know upload ./notes.md --global       # skip project scope tags

By default, belt know upload attaches project scope tags from the working directory (git remote, module name, language, path) so /suggest can rank the entry higher in matching projects. Pass --global to omit scope — use this for team-wide references that should surface everywhere.

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.

belt know upload auto-collects scope signals from the current directory (git remote, module name, language) and stores them on the new version — see Knowledge — Scoping.

Knowledge API · Creating skills

Files (CLI)

belt file (alias belt files) lists, uploads, downloads, and deletes files in your workspace. Use it to save outputs from belt app run or belt mcp run without shelling out to curl.

CommandPurpose
belt file listList your files (ls alias; --json, --limit, --cursor, --type, --search / -q, -l / --long)
belt file download <url-or-id>Download to cwd or -o / --out path (-o - pipes to stdout)
belt file upload <path> [path...]Upload via presigned URL; returns permanent URI (--name for a single file only)
belt file info <id>Show metadata including media dimensions, duration, and codec
belt file delete <id>Delete a file (rm alias; --force / -f to skip confirmation)
bash
1belt file list --type image --limit 202belt file list --search photo3belt file list -q avatar --type image4belt file download https://files.inference.sh/abc/image.png5belt file download 01abc123def456 -o ./output.png6belt file upload ./photo.jpg --name avatar.jpg7belt file upload *.png8belt file info 01abc123def456 --json9belt file delete 01abc123def456 --force

--type filters by content category (image, video, audio, text) — the CLI matches MIME types like image/%. --search / -q filters by filename substring (case-insensitive). Combine both to narrow results (for example -q avatar --type image). In table output, the type column shows short labels (image, video, audio, or subtypes like json, pdf, docx, csv, text) instead of raw MIME strings. Downloads accept a file URL (for example from task output) or a file ID from belt file list. If the destination filename already exists, download auto-renames with (1), (2) suffixes. Uploads and downloads show live progress (speed, bytes transferred, ETA); batch uploads print a [1/N] counter per file.

belt app run auto-uploads local file paths in --input JSON — use belt file upload when you need a URI outside a task run.

Files API · SDK Files

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: use_case, discovery, need, testimonial (legacy feedback is still accepted by the API).

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 need "better template discovery"5belt feedback testimonial "fastest way to ship agents with real integrations"6belt feedback "love the speed, wish there were more templates"

Before most commands, the CLI may show one unanswered question at the top of stderr (the notice block). Each question has a 1-hour cooldown; after you answer one, the next unanswered question appears on a later command. When all four structured questions are answered, an occasional freeform prompt (72-hour cooldown) suggests belt feedback "...". Survey notices are skipped for belt version, belt update, belt feedback, belt login, and belt logout so scripts and agents parsing those commands get clean output.

Survey prompts are not injected into belt suggest --json hook output — only the stderr notice path above. 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, --json, or --pjson). 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

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 / --pjson)

Many commands accept --json (-j) for machine-readable output on stdout. As of CLI v1.15.13, --json writes compact single-line JSON so it pipes cleanly to jq and other tools. Use --pjson when you want indented JSON for human debugging in the terminal.

For belt app run and belt mcp run, --jq '<expr>' filters output inline (no external jq required) — see Filter output (--jq) above.

Both flags suppress contextual stderr tips (post-command tips only — hook tip: lines inside belt suggest --json output are unchanged). Commands that support --save (for example belt app store --save) always write pretty-printed JSON to the file, regardless of --json or --pjson.

All list commands support JSON output: belt agent list, belt chat list, belt task list, belt flow list, belt flow runs, belt integrations list, belt app list, belt app store, belt skill list, belt know list, belt file list, belt mcp list, belt secrets list, and others. Detail commands include belt me, belt balance, belt task get, belt chat send, belt app get, belt agent get, belt agent create, belt file info, belt file download, belt file upload, belt file delete, and belt agent run ({"chat_id": "..."} with --no-wait; full run response otherwise).

bash
1belt task list --json | jq '.[].id'          # compact — pipes cleanly2belt task get task_abc --pjson               # indented — easier to read3belt app store --json --save store.json      # stdout compact; file pretty-printed

On failure with --json or --pjson 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 message when the API returns entitlement metadata with upgrade_available: true — under top-level meta on version 2 problem+json responses, or error.meta on legacy version 1 envelopes.

Error kindTypical messageWhat to do
Insufficient balanceBilling URL in messageAdd credits at Billing
Plan limitSubscription URL in messageUpgrade at Subscription
Addon entitlementAdd-ons URL in messageSubscribe at Add-ons
Not logged inSession expiredRun belt login

When addon_plan_id is present in entitlement metadata, the CLI links to the add-ons page instead of the subscription page.

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.