Skip to content

CLI Reference

The indx command line has three core operations: build, inspect, and query. Build is the bare indx <dir> --out invocation — there is no build keyword. All three run over the same pipeline and data model as the SDK. A fourth command, app, launches a local web UI and ships in the optional indx[app] extra.

This page documents every flag, the stdout shapes, and all exit codes.

Install with pip install indx (Python 3.11–3.13). For the programmatic equivalent of every command, see the SDK reference.

Terminal window
indx <dir> --out <dir> [--config indx.toml] [options] # build a knowledge space
indx inspect <archive.indx> [options] # summarize an archive
indx query <archive.indx> "<text>" [options] # semantic search
indx app [options] # launch the local web UI (needs indx[app])
indx mcp <archive.indx> [options] # serve a space to AI agents over MCP (needs indx[mcp])

Process a directory (or a .zip) through the six-stage pipeline and write an AI-ready knowledge space to --out. The output directory receives the handbook.indx archive plus the expanded index.json, chunks/, and embeddings/ layout.

Build is the implicit default subcommand — there is no indx build keyword. Passing a directory (or .zip) as the first positional triggers a build. inspect and query are the only named subcommands.

FlagTypeDefaultDescription
<dir> (positional)path— (required)Directory or .zip to process.
--out, -opath— (required)Output directory; receives handbook.indx, index.json, chunks/, embeddings/.
--config, -cpath./indx.toml if presentConfiguration file. See the configuration reference.
--parserstrdoclingOverride the parser engine.
--llmstropenai:gpt-5-miniOverride the enrichment LLM (none to disable, ollama:qwen2.5 for local).
--vlmstrnoneOverride the vision model.
--embedderstropenai:text-embedding-3-smallOverride the embedder (bge-m3 for local).
--storestrqdrantOverride the vector store backend.
--formatstrindxOutput writer: indx, jsonl, langchain, or llamaindex (the .indx is the sealed archive’s file extension; the writer name is indx).
--namestrhandbookArchive base name (produces handbook.indx).
--strictflagoffPromote per-item skips to fatal failures.
--resumeflagoffReuse cached stage outputs for unchanged files and config.
--dry-runflagoffWalk only and print the build plan (files, folders, selected components); run no models and write nothing. Exits 0.
--offlineflagoffFill unset slots with the zero-dependency offline stack: plaintext, none, none, hash, jsonl, .indx. Explicit flags still win.
--awsflagoffFill unset slots with the AWS managed stack: textract parser, bedrock LLM/VLM/embedder, s3vectors store. Requires pip install "indx[aws]". Mutually exclusive with --azure, --gcp, and --offline.
--azureflagoffFill unset slots with the Azure managed stack: docintel parser, azure LLM/VLM/embedder, azure-search store. Requires pip install "indx[azure]". Mutually exclusive with --aws, --gcp, and --offline.
--gcpflagoffFill unset slots with the GCP managed stack: docai parser, vertex LLM/VLM/embedder, bigquery store. Requires pip install "indx[gcp]". Mutually exclusive with --aws, --azure, and --offline.
--jsonflagoffEmit a machine-readable build summary with counts, components, elapsed time, and per-stage timings.
--jobs, -jintCPU countParallel workers for parse/embed.
--no-embedflagoffSkip stage 06 vectorization (produce a graph-only space).
--quiet / --verboseflagnormalDecrease / increase log verbosity.

By default the build prints one progress line per stage, then a summary:

indx ./docs → ./ai-ready
01 walk 128 files, 14 folders
02 parse 128 ok, 0 skipped
03 chunk 1042 chunks
04 relate 380 relations
05 enrich 128 documents (openai:gpt-5-mini)
06 embed 1042 vectors → qdrant, sealed handbook.indx
done: 1042 chunks, 128 docs, embed_dim=1536 (12.4s)

--quiet suppresses the per-stage lines, but the summary still prints. --verbose adds detail such as per-stage cache hits and misses when --resume is active.

SDK equivalent:

from indx import DirectoryPipeline
space = DirectoryPipeline(
parser="docling",
llm="openai:gpt-5-mini",
embedder="openai:text-embedding-3-small",
store="qdrant",
).run("./docs", "./ai-ready")

The --strict flag corresponds to strict=True in the SDK. --no-embed corresponds to dropping the embed-pack stage (pipeline.drop("embed-pack")). Full details are in the SDK reference.

Summarize a sealed .indx archive without re-running the pipeline. By default it prints space stats, a document-type histogram, and a sample of relations.

FlagTypeDefaultDescription
<archive.indx> (positional)path— (required)The .indx archive to inspect.
--jsonflagoffEmit the full space.stats object as JSON instead of the human-readable summary.
--documents [type]str (optional)List documents, optionally filtered by detected type.

The --json output mirrors the SpaceStats model: documents, chunks, relations, embeddings, embed_dim, the per-type types histogram, and bytes_source. See data models for field meanings.

By default inspect prints the space stats, a document-type histogram, and a sample of relations:

handbook.indx (indx 1.0, produced by indx 0.4.2)
documents 128 chunks 1042 relations 380 embed_dim 1536
types policy 41 guide 33 reference 29 faq 25
relations (sample)
chunk:0a1f → chunk:9c3e follows
chunk:7b22 → chunk:1d80 references
doc:contracts → doc:terms cross-references

With --documents [type], each row lists the document id, detected type, source path, and chunk count. Passing a type filters the listing to that detected type.

SDK equivalent: inspect reads the KnowledgeSpace you get from KnowledgeSpace.load("./ai-ready/handbook.indx"). It uses space.stats for the summary and space.documents(type=...) for the document listing.

Run a semantic search against a sealed archive and return the most similar chunks. The query text is embedded with the same embedder pinned in the archive manifest, guaranteeing query-time compatibility.

FlagTypeDefaultDescription
<archive.indx> (positional)path— (required)The .indx archive to search.
"<text>" (positional)str— (required)The query string.
-kint5Number of hits to return.
--typestrRestrict results to a single document type.
--jsonflagoffEmit the results as a SearchHit[] JSON array (including .chunk, .neighbors, and .source).

Default output is human-readable: for each hit, the rank, similarity score, source path, and chunk text along with its neighbor chunk ids (the context window). With --json, each element is a serialized SearchHit carrying the matched chunk, its score, and resolved neighbor chunks.

Terminal window
indx query ./ai-ready/handbook.indx "how long is data retained?" -k 3 --type policy

SDK equivalent:

from indx import KnowledgeSpace
space = KnowledgeSpace.load("./ai-ready/handbook.indx")
for hit in space.search("how long is data retained?", k=3):
print(hit.score, hit.source.path)
print(hit.chunk.text)

-k maps to the k argument of space.search(query, k=...). See the SDK reference.

Launch a local web UI that exercises the whole pipeline from the browser — configure a stack, run a build with live stage progress, then inspect and query the result. The server runs on one origin (it serves both the UI and a JSON + SSE /api) and operates on server-side paths. This command ships in the optional indx[app] extra (pip install "indx[app]").

FlagTypeDefaultDescription
--hoststr127.0.0.1Interface to bind.
--portint8000Port to serve on.
--open / --no-openflag--openOpen (or don’t open) a browser on start.
--config, -cpath./indx.toml if presentConfiguration file to load into the editor.
Terminal window
indx app # http://127.0.0.1:8000, opens a browser
indx app --no-open --port 9000 # bind a different port, don't open a browser

If the indx[app] extra is not installed, indx app fails loud with a pip install "indx[app]" hint and exits 1 — a MissingDependencyError is a plain IndxError, so it maps to the fatal runtime code, not the configuration code (3). A missing UI bundle is non-fatal: the server still starts and serves /api, with a warning. Because app is a subcommand, a directory literally named app must be built as ./app (indx ./app --out ...).

See the web app guide for the four tabs, the Offline preset, and the dev workflow.

Serve a built knowledge space over the Model Context Protocol — the universal AI-agent connector. The server exposes three tools (indx_search, indx_overview, indx_get_document) to any MCP client: Claude Desktop, Cursor, or the TypeScript Mastra framework, with no Python on the client side. Ships in the optional indx[mcp] extra (or indx[agent]).

FlagTypeDefaultDescription
<archive> (positional)path— (required)A .indx archive or an output directory containing one.
--namestrarchive stemServer name advertised to MCP clients.
--transportstrstdioMCP transport: stdio, sse, or streamable-http.
Terminal window
indx mcp ai-ready/handbook.indx # serve over stdio (Claude Desktop / Cursor)
indx mcp ai-ready/handbook.indx --transport sse # serve over SSE for a networked client

Like app, mcp is a subcommand, so a directory literally named mcp must be indexed as ./mcp (indx ./mcp --out ...). If the indx[mcp] extra is absent, the command fails with a pip install indx[mcp] hint and exits 1. For the Python equivalent (and in-process tools for LangChain, OpenAI Agents, Pydantic AI, and the Claude Agent SDK), see the AI agents guide and the SDK reference.

Every command returns one of these process exit codes:

CodeMeaning
0Success.
1Fatal pipeline/runtime error (including a --strict skip promoted to fatal).
2Usage error (bad flags or arguments).
3Configuration error (invalid indx.toml or an unknown component name).
4Archive error (corrupt or incompatible .indx).

A nonexistent archive path is a usage error (2), not an archive error — inspect/query validate the path before the command runs. Exit 4 is reserved for a path that exists but is not a valid .indx (corrupt, not a zip, or an incompatible indx_version).