| title | CLI Reference | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| type | spec | ||||||||||||||
| tags |
|
||||||||||||||
| created | 2026-03-30 | ||||||||||||||
| updated | 2026-04-27 |
Complete behavior specification for the index CLI. For user-facing quick-start and examples, see packages/cli/README.md. For npm distribution details, see cli-npm-publish.md.
The index CLI is a standalone Bun-based binary in packages/cli/. It communicates with the Index Network protocol server over HTTP/SSE. Distribution is via npm using platform-specific prebuilt binaries.
- Prints a URL pointing to the protocol's Better Auth OAuth flow (Google provider).
- Opens the user's default browser to that URL.
- Starts a temporary local HTTP server (ephemeral port), generates a 32-byte one-time state, and includes the strict loopback callback, exact
version=2, and state in the browser URL. - The web bridge validates and preserves the exact v2 request through authentication, then calls the project-JWT-authenticated
POST /api/auth/cli-credentialendpoint with only{protocolVersion:2}. The session-only endpoint fixes the name, 90-day expiry, and{client:'cli', protocolVersion:2}metadata, and returns the secret and exact key ID for the restricted loopback callback. - After exact state validation, stores the credential, key ID, API-key auth kind, and API base URL in
~/.index/credentials.json. Requests send the key throughx-api-key, which classifies them as the agent surface rather than creating a session-authenticated browser bypass. On re-login, the replacement is stored first and calls the constrained CLI revocation endpoint as the active caller while supplying the captured prior raw secret and exact prior row ID; failure keeps the replacement valid and prints a truthful cleanup warning. - No version downgrade: the web bridge fails every non-v2 request shape closed. There is no
session_tokencallback field and no Bearer API-key fallback on the server; released v1 CLI binaries must upgrade and runindex loginagain. - Prints confirmation with the authenticated user's name and email.
- The local server shuts down after receiving the callback (or after a 120-second timeout).
Calls POST /api/auth/cli-credential/revoke with strict {keyId,targetKey} proof, using the current CLI key in x-api-key and again as targetKey for self-revocation. The endpoint accepts only authoritative, unbound, server-issued CLI rows and returns success only after deletion. Revocation failures retain credentials and exit nonzero. If revocation succeeds but local cleanup fails, logout also exits nonzero and warns that the server key is revoked while the local credential file still needs manual removal. A legacy credentials.json without an exact key ID loads as signed out; logout never lists or guesses another key to revoke.
The index conversation command is the entry point for Human-to-Human (H2H)
direct messaging — the list/with/show/send/stream subcommands backed
by /api/conversations/*.
Human-to-Agent chat from the CLI has been removed. It ran on the retired
orchestrator persona, and API-key callers can no longer start a chat without
naming one; the persona that remains (signal) is web-only.
Invoking index conversation with no subcommand — or with a bare message —
prints an error pointing at the app and exits 1.
- Calls
GET /api/conversationswith auth header. - Renders a table of conversations: ID (truncated), participants, last message preview, created date.
- Exits 0.
- Calls
POST /api/conversations/dmwith{ peerUserId }. - If a DM already exists, returns the existing conversation. Otherwise creates a new one.
- Prints the conversation ID and participant info.
- Exits 0.
- Calls
GET /api/conversations/:id/messageswith optional--limit <n>(default 20). - Renders messages in chronological order showing sender, timestamp, and text content.
- Exits 0.
- Calls
POST /api/conversations/:id/messageswith{ parts: [{ type: "text", text: message }] }. - Prints confirmation with the sent message ID.
- Exits 0.
- Opens
GET /api/conversations/streamas an SSE connection. - Prints real-time events (new messages, conversation updates) to stdout.
- Runs until interrupted with Ctrl+C.
The index profile command lets users view, create, update, and search profiles from the terminal.
- Load credentials via
requireAuth. Exit with error if not logged in. - Call
GET /api/auth/meto get the current user's ID. - Call
GET /api/users/:userIdto get the full profile. - Render a styled profile card showing: name, intro/bio, location, socials, and member-since date.
- Load credentials via
requireAuth. Exit with error if not logged in. - Call
GET /api/users/:userIddirectly with the provided user ID. - Render the same styled profile card.
- Load credentials via
requireAuth. Exit with error if not logged in. - Call
POST /api/enrichment/enrichexactly once to synchronously enrich the authenticated user's public profile. - Return
{ enriched, profile }, whereprofilecontains the current resolved identity, social links, and avatar data. Formatted output prints the resolved name, location, and social-link count.
- Load credentials via
requireAuth. Exit with error if not logged in. - Calls
create_user_contexttool via Tool HTTP API with the provided social links. - Prints confirmation message on success.
- Load credentials via
requireAuth. Exit with error if not logged in. - Calls
update_user_contexttool via Tool HTTP API with{ action, details }. - Prints confirmation message on success.
- Load credentials via
requireAuth. Exit with error if not logged in. - Calls
read_user_contextstool via Tool HTTP API with the search query. - Renders a heading followed by each match as
name (userId)with a short bio snippet — the output is a list rather than a formatted table.
The index intent command exposes subcommands for managing intents (user-facing: "signals") from the CLI.
- Calls
POST /api/intents/listwith optional pagination/filter body. - Renders a table with columns: ID (short), signal (description truncated to 50 chars), status, source, created date.
- Flags:
--archivedincludes archived intents,--limit <n>sets page size (backend default applies if omitted).
- Calls
GET /api/intents/:id. - Renders a detailed card with: full description (payload), summary, confidence, source type, status, intent mode, speech act type, timestamps (created, updated, archived), and index assignments if present in the response.
- Calls
create_intenttool via Tool HTTP API with{ description }. The tool returns one or moreintent_proposalblocks (each with aproposalIdanddescription) rather than a persisted intent. - Confirms each proposal via
POST /api/intents/confirmwith{ proposalId, description }, which persists the active signal. - Prints "Signal created." with the confirmed description.
- Content is the remaining positional arguments joined with spaces.
- Calls
update_intenttool via Tool HTTP API with{ intentId, description }. - Prints confirmation message on success, error on failure.
- Content is the remaining positional arguments joined with spaces.
- Resolves short ID to full UUID via
GET /api/intents/:id. - Calls
delete_intenttool via Tool HTTP API with{ intentId }. - Prints confirmation message on success, error on failure.
- Resolves short ID to full UUID via
GET /api/intents/:id(the tool rejects non-UUID intent IDs). - Calls
create_intent_indextool via Tool HTTP API with{ intentId, networkId }. - Prints "Signal linked to network." on success, error on failure.
- Resolves short ID to full UUID via
GET /api/intents/:id(the tool rejects non-UUID intent IDs). - Calls
delete_intent_indextool via Tool HTTP API with{ intentId, networkId }. - Prints "Signal unlinked from network." on success, error on failure.
The index negotiation command exposes subcommands for inspecting agent negotiations. Negotiations are autonomous turn-by-turn exchanges between broker agents that evaluate whether an opportunity exists between two users.
- Reads credentials. Exits with error if not logged in.
- Resolves the authenticated user via
GET /api/auth/me, then callsGET /api/users/:userId/negotiationswith optional query params (limit,since). - Renders a table with columns: ID (short), counterparty name, outcome (opportunity/no match), role (helper/seeker/peer), turns, created date.
- Supports
--limit <n>and--since <date|duration>(ISO date or human-friendly duration like1h,2d,1w).
- Reads credentials. Exits with error if not logged in.
- Fetches negotiations and matches by ID prefix.
- Renders a detailed card with: ID, counterparty, outcome, role, turn count, created date.
- Below the card, renders a turn-by-turn log showing: turn number, speaker name, action (accept/reject/continue), suggested roles, and reasoning text.
The index opportunity command exposes subcommands for managing opportunities from the terminal.
- Reads credentials from
~/.index/credentials.json. Exits with error if not logged in. - Calls
GET /api/opportunitieswith optional query params (status,limit). - Renders a table with columns: ID (short), counterparty name, category, status, confidence, createdAt.
- Supports
--status <pending|accepted|rejected|expired>filter and--limit <n>.
- Reads credentials. Exits with error if not logged in.
- Calls
GET /api/opportunities/:idwhich returns the opportunity with LLM-generated presentation. - Renders a detailed card with:
- Parties: names and valency roles displayed as human-readable labels (agent = Helper, patient = Seeker, peer = Peer) with color coding.
- Reasoning text.
- Category, confidence (with visual bar), status.
- Timestamps (createdAt, updatedAt).
- Presentation text (if available).
- Reads credentials. Exits with error if not logged in.
- Resolves the opportunity and calls the REST acceptance preflight.
- When no uptake advisory exists, accepts and prints confirmation.
- When unresolved preparatory questions exist, prints each question and leaves the opportunity pending. Answer or dismiss them through a question-capable surface, then retry normally.
- To explicitly continue without resolving them, retry with
--acknowledge-uptake <question-id[,question-id...]>using the complete ID set printed by the latest advisory. This is an advisory override, not an answer.
With --json, structured advisory responses are printed unchanged.
- Reads credentials. Exits with error if not logged in.
- Calls
PATCH /api/opportunities/:id/statuswith{ status: "rejected" }. - Prints confirmation message.
The index network command manages networks (the user-facing term for indexes) through eight subcommands. All commands require authentication and communicate with the protocol API over HTTP.
Lists networks the authenticated user is a member of. Calls GET /api/networks. Renders a table with columns: title, member count, role (owner/admin/member), join policy, created date. Personal networks (isPersonal: true) are filtered from the display.
Creates a network directly for eligible staff or submits an early-access request for other users. The command first calls POST /api/networks with { title, prompt? }; a successful direct creation returns { kind: "created", network } and prints the network summary. The fallback is restricted to a 403 response whose structured error string starts with Network creation is in early access.. Only for that exact early-access denial, the command calls POST /api/network-requests with { name: title, purpose?: prompt }, returns { kind: "requested", request }, and prints the request status and ID. Every unrelated 403 and all other errors are surfaced without submitting a request.
Shows detailed network information. Calls GET /api/networks/:id for the network, then GET /api/networks/:id/members for the member list. Renders a detail card with: title, prompt, join policy, member count, owner. Below the card, renders a member table with: name, email, role, joined date.
Joins a public network. Calls POST /api/networks/:id/join. Prints confirmation with the network title. Returns an error for invite-only networks (403).
Leaves a network. Calls POST /api/networks/:id/leave. Prints confirmation. Returns an error if the user is the owner (cannot leave own network).
Updates network settings. Calls the update_network MCP tool via the Tool HTTP API with { networkId, settings: { title?, prompt? } }, populating only the fields supplied as flags. Prints confirmation with the updated network title.
Deletes a network. Calls the delete_network MCP tool via the Tool HTTP API. Prints confirmation on success.
Invites directly by any valid email through the server invitation flow. Calls POST /api/networks/:id/members/invite with { email }; the server resolves existing users or provisions the pending invitee as needed. Prints whether the invitation was sent or the user was already a member.
Lists the authenticated user's contacts. Calls the list_contacts MCP tool via the Tool HTTP API. Renders a table of contacts with name, email, and added date.
Removes a contact by email. First calls list_contacts to resolve the email to a userId, then calls the remove_contact MCP tool with { contactUserId }.
Extracts content from a URL. Supports optional --objective <text> to focus extraction on a specific topic.
Syncs all user context (profile, networks, intents, contacts) to ~/.index/context.json.
Outputs the synced context to stdout as JSON instead of writing to file.
Marks the user's onboarding as complete.
- The CLI is a pure HTTP client. It must not import any protocol internals.
- Auth tokens are stored in
~/.index/credentials.jsonviaCredentialStore. - 401 responses produce "Session expired or invalid. Run
index loginto re-authenticate." - Network errors produce a clear error message.
- No external CLI framework — argument parsing uses a hand-rolled parser in
args.parser.ts. - The CLI must work on macOS and Linux. Windows is not required.
- The binary name is
index. Distributed vianpm install -g @indexnetwork/cli. - User-facing copy uses "signal" for intents and "network" for indexes.
- SSE parsing must handle partial chunks (tokens may arrive mid-line).
- Valency role display uses friendly labels: agent = "Helper", patient = "Seeker", peer = "Peer".
- Each command handler follows the
handleX(client, subcommand, ...)pattern.
index logincompletes an OAuth flow and stores valid credentials.index loginfails gracefully if the browser cannot be opened (prints URL for manual copy).
index conversation(no subcommand) prints the agent-chat retirement error and exits 1.index conversation listdisplays a formatted table of conversations.index conversation with <user-id>gets or creates a DM and prints the conversation summary.index conversation show <id>displays messages in chronological order.index conversation send <id> <message>sends a message and prints confirmation.index conversation streamopens an SSE connection and prints real-time events.
index profiledisplays the current user's profile card.index profile show <user-id>displays another user's profile card.index profile syncsynchronously enriches the public profile and returns the resolved identity, social, and avatar data.index profile creategenerates a profile from social links and prints confirmation.index profile update <action>updates the profile and prints confirmation.index profile search <query>displays matching profiles.
index intent listdisplays a formatted table of active signals.index intent list --archivedincludes archived signals.index intent show <id>displays full signal details.index intent create <content>processes the content and prints a result.index intent archive <id>archives the signal and prints confirmation.index intent link <id> <network-id>links the signal and prints confirmation.index intent unlink <id> <network-id>unlinks the signal and prints confirmation.index intent links <id>displays linked networks.
index negotiation listdisplays a table of negotiations with outcome and role.index negotiation list --since 1dfilters to the last 24 hours.index negotiation show <id>displays turn-by-turn negotiation details.
index opportunity listdisplays a table of opportunities.index opportunity list --status pendingfilters by status.index opportunity show <id>displays a detailed card with parties, roles, and reasoning.index opportunity accept <id>runs the uptake preflight; it accepts immediately when clear, otherwise prints preparatory questions and the explicit--acknowledge-uptakeretry.index opportunity reject <id>sends rejected status and prints confirmation.
index network listdisplays non-personal networks.index network create <name>creates directly when eligible; otherwise it submits an early-access request only after the exact early-access denial.index network show <id>displays network details and member table.index network join <id>joins a public network.index network leave <id>leaves a network.index network update <id> --title <t>updates network settings.index network delete <id>deletes a network.index network invite <id> <email>invites directly by any valid email through the server invitation flow.
- All commands exit with code 1 and a helpful message when not authenticated.
- 401 responses trigger the standard "Session expired" message.
- Network errors produce clear error messages.
- Bare command with no subcommand prints usage help.