Background
Many icp commands support a --json flag for machine-readable output, but --help currently says nothing about what the output looks like beyond "Output command results as JSON". For an agent (or a developer writing scripts) this means the JSON schema has to be discovered by running the command live or reading the source code.
This RFC asks: where and how should JSON output schemas be documented?
Current state
The following commands produce structured JSON output with no schema documentation in --help:
| Command |
Schema (verified from source) |
icp deploy --json |
{"canisters": [{"name": string, "canister_id": string, "url": string|null}]} |
icp network status --json |
{"managed": bool, "api_url": string, "gateway_url": string|null, "root_key": string, "candid_ui_principal": string|null, "proxy_canister_principal": string|null} |
icp canister call --json |
{"response_bytes": string, "response_text": string|null, "response_candid": string|null} |
icp canister create --json |
{"canister_id": string, "canister_name": string|null} |
icp canister list --json |
{"canisters": [string]} |
icp canister logs --json |
{"log_records": [{"timestamp": u64, "index": u64, "content": string}]} |
icp canister snapshot create --json |
{"snapshot_id": string, "taken_at_timestamp": u64, "total_size_bytes": u64} |
icp canister snapshot list --json |
{"snapshots": [{"snapshot_id": string, "taken_at_timestamp": u64, "total_size_bytes": u64}]} |
icp cycles balance --json |
{"balance": string} |
icp cycles mint --json |
{"deposited": string, "new_balance": string} |
icp cycles transfer --json |
{"block_index": string} |
icp token transfer --json |
{"block_index": string} |
icp identity list --json |
{"default_identity": string, "identities": [{"name": string, "principal": string}]} |
icp identity new --json |
{"seed_phrase": string} |
Note: icp canister status --json produces a more complex structure (full status object) that is not listed here as it is not a simple flat schema.
Why it matters
Two specific workflows already referenced in the icp-cli skill documentation rely on parsing JSON output without having the schema documented:
icp network status --json — used in dev server configuration to extract api_url and root_key
icp deploy --json — used to extract canister_id and url per deployed canister
An agent or script guessing field names (e.g. canisterId vs canister_id, apiUrl vs api_url) will silently get undefined/null with no error.
Options for discussion
Option A — Document schemas inline in --help
Add the schema to each --json flag description, e.g.:
--json Output as JSON: {"canisters": [{"name": string, "canister_id": string, "url": string|null}]}
Pros: schema is right where the flag is; works offline; agents reading --help get it immediately.
Cons: verbose; schema in two places if also in generated docs; must be kept in sync manually.
Option B — Document schemas in generated CLI reference only
Keep --help terse ("Output command results as JSON") and document schemas in docs/reference/cli.md and https://cli.internetcomputer.org/llms.txt.
Pros: single source of truth; no --help clutter.
Cons: agents running --help at invocation time don't see it; requires network access to docs.
Option C — Brief note in --help pointing to docs
--json Output as JSON. Schema documented at https://cli.internetcomputer.org/reference/cli.md
Pros: --help stays clean; agents know where to look.
Cons: requires network access; URL may change.
Option D — Standardise on a stable JSON envelope
Wrap all JSON output in a consistent {"command": "...", "data": {...}} envelope so agents can rely on the outer shape without knowing the inner schema, and document the inner schemas in generated docs.
Questions for maintainers
- Which option (or combination) fits best with the project's documentation philosophy?
- Should JSON schemas be considered a stable public API and versioned accordingly?
- Is
icp canister status --json output intentionally undocumented given its complexity, or should it be documented too?
Background
Many
icpcommands support a--jsonflag for machine-readable output, but--helpcurrently says nothing about what the output looks like beyond "Output command results as JSON". For an agent (or a developer writing scripts) this means the JSON schema has to be discovered by running the command live or reading the source code.This RFC asks: where and how should JSON output schemas be documented?
Current state
The following commands produce structured JSON output with no schema documentation in
--help:icp deploy --json{"canisters": [{"name": string, "canister_id": string, "url": string|null}]}icp network status --json{"managed": bool, "api_url": string, "gateway_url": string|null, "root_key": string, "candid_ui_principal": string|null, "proxy_canister_principal": string|null}icp canister call --json{"response_bytes": string, "response_text": string|null, "response_candid": string|null}icp canister create --json{"canister_id": string, "canister_name": string|null}icp canister list --json{"canisters": [string]}icp canister logs --json{"log_records": [{"timestamp": u64, "index": u64, "content": string}]}icp canister snapshot create --json{"snapshot_id": string, "taken_at_timestamp": u64, "total_size_bytes": u64}icp canister snapshot list --json{"snapshots": [{"snapshot_id": string, "taken_at_timestamp": u64, "total_size_bytes": u64}]}icp cycles balance --json{"balance": string}icp cycles mint --json{"deposited": string, "new_balance": string}icp cycles transfer --json{"block_index": string}icp token transfer --json{"block_index": string}icp identity list --json{"default_identity": string, "identities": [{"name": string, "principal": string}]}icp identity new --json{"seed_phrase": string}Note:
icp canister status --jsonproduces a more complex structure (full status object) that is not listed here as it is not a simple flat schema.Why it matters
Two specific workflows already referenced in the
icp-cliskill documentation rely on parsing JSON output without having the schema documented:icp network status --json— used in dev server configuration to extractapi_urlandroot_keyicp deploy --json— used to extractcanister_idandurlper deployed canisterAn agent or script guessing field names (e.g.
canisterIdvscanister_id,apiUrlvsapi_url) will silently getundefined/nullwith no error.Options for discussion
Option A — Document schemas inline in
--helpAdd the schema to each
--jsonflag description, e.g.:Pros: schema is right where the flag is; works offline; agents reading
--helpget it immediately.Cons: verbose; schema in two places if also in generated docs; must be kept in sync manually.
Option B — Document schemas in generated CLI reference only
Keep
--helpterse ("Output command results as JSON") and document schemas indocs/reference/cli.mdandhttps://cli.internetcomputer.org/llms.txt.Pros: single source of truth; no
--helpclutter.Cons: agents running
--helpat invocation time don't see it; requires network access to docs.Option C — Brief note in
--helppointing to docsPros:
--helpstays clean; agents know where to look.Cons: requires network access; URL may change.
Option D — Standardise on a stable JSON envelope
Wrap all JSON output in a consistent
{"command": "...", "data": {...}}envelope so agents can rely on the outer shape without knowing the inner schema, and document the inner schemas in generated docs.Questions for maintainers
icp canister status --jsonoutput intentionally undocumented given its complexity, or should it be documented too?