Agent CLI
Use the Starkscan CLI for shell workflows, release validation, and local-first exports.
Agent CLI
Use the CLI when you need reproducible shell commands, local-first exports, or an operator-friendly surface that sits on top of the same Starkscan API contract.
Before using the CLI in unattended workflows, check the Launch matrix for the current release state and trust boundary. For npm package provenance, Socket links, and exact-version pinning rules, use Package trust.
Use this surface for
- shell workflows with explicit commands and outputs
- local transfer exports and privacy-sensitive analysis
- release validation from a terminal
- preparing the same binary for stdio MCP in Codex or Claude Code
When not to start here
- Use the REST API first when you need zero-install integration.
- Use the SDK when you are writing app code.
- Use MCP when the consumer is already an MCP client.
Try in app before you script it
The explorer is still the fastest way to understand the data you are about to automate:
- Dashboard for top-level chain state
- Transactions for rows and detail pages
- Contracts for contract metadata and activity
- Watchlist for repeat address analysis
Install with npm or npx
Install the default npm CLI for normal use. Pin
@starkscan/[email protected]in unattended automation when reproducible installs matter.
npm install -g @starkscan/cli
starkscan initFor a one-off agent run without a global install:
npx -y @starkscan/cli init --agent --output-format jsonThe npm launcher uses native CLI artifacts bundled in the published package when available, verifies archives against the bundled release manifest, caches the native Starkscan binary, and forwards all arguments to it. It does not require Rust or repository access.
Agents can inspect the launcher decision before running the native binary:
npx -y @starkscan/[email protected] --launcher-jsonThe JSON includes the resolved binary path, package version, release tag,
source (bundled, download, or bin-path), cache-hit status, and
verification status. The launcher may resolve and verify the binary first, but
this command does not execute the native starkscan binary.
For MCP clients, prefer the dedicated MCP launcher. It delegates to the same CLI package underneath but keeps onboarding stable for MCP hosts:
npx -y @starkscan/[email protected] print-config --transport remote
npx -y @starkscan/[email protected]print-config emits JSON with environment-variable placeholders, so keep API
keys in your shell or agent secret store instead of pasting literal keys into
client config files.
The public package and command are @starkscan/cli and starkscan.
First-run init
Run init before handing the CLI to an agent. It prints the active base URL, chain, auth placeholder, validation commands, and MCP client snippets without writing secrets to disk.
starkscan init
starkscan init --agent --output-format json
starkscan init --agent --mcp codex --output-format jsonUse --mcp codex, --mcp claude, --mcp cursor, --mcp claude-desktop, or --mcp cline when you want one client-specific snippet instead of all snippets.
Pinned fallback
Public users should use npm or npx. Maintainer-only native artifact and source-install fallbacks are intentionally kept out of the public docs so external agents do not depend on repository internals.
Environment
export STARKSCAN_API_KEY="mzk_test_REPLACE_ME"
export STARKSCAN_CHAIN="SN_MAIN"
# Optional: only set this for preview or self-hosted hosts.
# export STARKSCAN_BASE_URL="https://preview.example.com/api"For hosted external access, the CLI defaults to https://api.starkscan.co.
Override STARKSCAN_BASE_URL only when targeting preview or a self-hosted host.
The CLI then calls the normal /v1/* routes underneath that base for you.
The CLI sends X-Starkscan-Api-Key for hosted API auth. Use STARKSCAN_*
env names for new beta clients; old internal names are compatibility aliases.
The CLI only forwards STARKSCAN_API_KEY, --api-key,
STARKSCAN_INTERNAL_API_KEY, or --internal-api-key to Starkscan HTTPS hosts
or localhost/loopback fixtures. When intentionally testing a private API host,
pass --allow-untrusted-base-url explicitly so keys are not replayed to an
unexpected endpoint by default.
Supported STARKSCAN_CHAIN values are SN_MAIN and SN_SEPOLIA.
If you need a pinned native release instead of npm, use the maintainer release runbook for the matching Starkscan tag. External clients should not need repository access.
First successful commands
starkscan status
starkscan address-activity 0xwallet --limit 50
starkscan address-summaries 0xwalletA 0xcontractB --output-format json
starkscan address-intelligence 0xwalletA 0xcontractB --output-format json
starkscan tx-details 0xtxA 0xtxB --log-limit-per-tx 32
starkscan contract-events 0xcontract --topic0 0x... --from-block 7800000 --limit 100
starkscan contract-entrypoints 0xtoken
starkscan contract-read 0xtoken --selector balanceOf --calldata 0xwallet
starkscan token-total-supply 0x0123...
starkscan token-balance-of <ownerAddress> <tokenAddress> --block-tag pendingstarkscan token-balance-of intentionally keeps the owner-first CLI order for shell readability.
The REST API and SDK remain token-first, so translate it as:
- CLI:
starkscan token-balance-of <ownerAddress> <tokenAddress> - REST:
GET ${STARKSCAN_BASE_URL:-https://api.starkscan.co}/v1/$STARKSCAN_CHAIN/token/<tokenAddress>/balance-of/<ownerAddress> - SDK:
starkscan.tokenBalanceOf(tokenAddress, ownerAddress)
Use that command only when you already know the exact token contract you want. If the workflow is "does this wallet already hold USDC?" or "skip wallets with any nonzero holdings," prefer:
- CLI:
starkscan address-token-holdings <ownerAddress> - REST:
GET ${STARKSCAN_BASE_URL:-https://api.starkscan.co}/v1/$STARKSCAN_CHAIN/address/<ownerAddress>/token-holdings
That matters on Starknet because a symbol such as USDC can map to more than one live contract or alias. An exact-token balance-of can return 0 for one USDC contract while the wallet still holds another USDC variant.
Add:
starkscan address-token-holdings 0xwalletFor large wallet-screening jobs, use address-token-holdings rather than looping token-balance-of for every wallet.
Before you make a definitive skip/allow decision from that response, check the holdings completeness flags. Treat the result as complete only when exact=true, truncated=false, and completeness.reasonCode="complete".
General shell workflows
starkscan block 7800000
starkscan tx 0x1234abcd
starkscan tx-details 0x1234abcd 0x5678ef90 --log-limit-per-tx 32
starkscan search 0x1234abcd
starkscan address-activity 0xwallet --limit 50
starkscan address-transactions 0xwallet --limit 50
starkscan address-summaries 0xwalletA 0xcontractB --output-format json
starkscan address-intelligence 0xwalletA 0xcontractB --output-format json
starkscan contract-events 0xcontract --topic0 0x... --from-block 7800000 --limit 100
starkscan contract-entrypoints 0xtoken
starkscan contract-read 0xtoken --selector balanceOf --calldata 0xwallet
starkscan feed --max-events 10Summaries, attribution, and verification
starkscan address 0xwallet # address summary (activity counts, first/last seen)
starkscan address-attribution 0xwallet # best-known friendly label / attribution metadata
starkscan address-summaries 0xwalletA 0xcontractB
starkscan address-intelligence 0xwalletA 0xcontractB
starkscan token 0x0123... # token summary
starkscan contract-verification 0xcontract # verification status + source metadataaddress / token return the aggregate summary; use address-activity / token-transfers for the paged detail.
Live feed: snapshot or stream
starkscan feed # one snapshot
starkscan feed --stream --block-limit 5 --tx-limit 20 # follow /feed/stream
starkscan --output-format stream-json feed --stream --max-events 50--stream follows the live feed; omit --max-events (or pass 0) to stream until interrupted. stream-json is accepted only by feed: feed --stream emits compact line-delimited events even when --pretty is also set, while feed without --stream emits a single {"type":"result",...} envelope. Any other command run with --output-format stream-json exits with a usage error.
Discover everything
starkscan examples # copy-pasteable API, CLI, SDK, and MCP snippets for your active host
starkscan doctor # check base URL, auth, API reachability, and hosted MCPMCP helper commands
The CLI includes MCP helpers for agents and local operator checks:
| Command | Use |
|---|---|
starkscan mcp quickstart | Print client setup snippets for the selected transport. |
starkscan mcp print-config | Emit machine-readable client config with environment placeholders, not literal secrets. |
starkscan mcp tools | List the current tool names exposed by the CLI/MCP surface. |
starkscan mcp start --transport remote | Run the stdio MCP proxy against hosted Starkscan HTTP APIs. |
starkscan mcp serve --transport remote | Alias for start, matching MCP launcher vocabulary. |
starkscan mcp serve --transport local | Maintainer/self-hosted fallback that serves the embedded local runtime. |
Global flags
These apply to every command and can be placed before or after the subcommand:
| Flag | Env | Default | Purpose |
|---|---|---|---|
--base-url | STARKSCAN_BASE_URL | https://api.starkscan.co | Optional Starkscan API base URL override; custom hosted values may be an API-host root or an app-host /api base |
--chain | STARKSCAN_CHAIN | SN_MAIN | chain id, currently SN_MAIN or SN_SEPOLIA |
--api-key | STARKSCAN_API_KEY | — | hosted API key (sent as X-Starkscan-Api-Key) |
--allow-untrusted-base-url | — | false | permit forwarding --api-key or --internal-api-key to a non-Starkscan, non-localhost base URL; use only for intentional private endpoints |
--output-format | — | text | text, json, or stream-json. text/json apply to every command; stream-json is accepted only by feed (line-delimited with --stream, one result envelope otherwise) and other commands reject it with a usage error |
--pretty | — | false | pretty-print JSON output |
--retries | — | built-in | retries for transient HTTP failures; values above 10 are clamped to 10 |
--timeout-ms | STARKSCAN_TIMEOUT_MS | built-in | HTTP timeout in milliseconds |
For agent callers, --output-format json keeps stdout parseable on failure:
successful commands return { "ok": true, "data": ... }; failures before a
result payload is emitted return
{ "ok": false, "error": { "code": "auth_error", "message": "HTTP 401: unauthorized", "exitCode": 3, "exitClass": "auth", "httpStatus": 401, "requestId": "starkscan-cli-..." } }
and still exit non-zero. Diagnostic commands such as doctor can emit
{ "ok": false, "data": ... } with a non-zero exit. stream-json failures emit
one compact type: "error" line, while text mode keeps human-readable errors on
stderr.
Transaction hashes, addresses, token addresses, and calldata values are
validated locally as 0x-prefixed Starknet field elements. Contract-read
selectors can be function names such as balanceOf or selector felts. Malformed
inputs exit 2 before any network request; JSON mode emits
code: "usage_error".
JSON output canonicalizes address-shaped fields such as address,
fromAddress, toAddress, contractAddress, and tokenAddress to lowercase
0x plus 64 hex characters. Hashes, calldata, selectors, and other felt values
are not rewritten.
CLI exit codes are stable for agents: 0 success, 1 runtime, 2
usage/bad input, 3 auth, 4 rate-limited, 5 timeout, and 6 not found.
Local-first transfer exports
starkscan --output-format json token-transfers 0x0123... \
--address 0x0456... \
--address 0x0789... \
--from-block 7800000 \
--to-block 7802500 > transfers.jsonThat gives you a narrow token + address(es) + block range export directly on your machine instead of in a shared dump.
For multi-wallet monitoring without a block range, repeat --address the same way:
starkscan token-transfers 0x0123... \
--address 0xwalletA \
--address 0xwalletB \
--limit 100For the full external starter, including the matching REST and SDK flows plus the shared env contract, use Monitor 10 wallets.
Batch address classification
starkscan --output-format json address-summaries \
0xwalletA \
0xcontractB
starkscan --output-format json address-intelligence \
0xwalletA \
0xcontractBFor file-based batches, put one address per line and use the same command with --file:
starkscan --output-format json address-intelligence --file wallets.txtUse address-summaries when you already have a backend list of addresses and need ordered aggregate facts such as class hash, account hint, deployment metadata, latest activity, and activity count. Use address-intelligence when you also need utility classification fields such as label/protocol, deployed flag, and inbound-funds flag. Both commands preserve request order, reject duplicate or malformed addresses before making a request, ignore blank/comment lines in files, and follow the API batch cap of 128 addresses.
Contract event indexers
starkscan --output-format json contract-events 0xcontract \
--topic0 0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9 \
--from-block 7800000 \
--to-block 7800500 \
--limit 100Use contract-events when you need the canonical paginated log stream for one contract before applying protocol-specific decoding. Keep filters server-side first: contract address, exact topic0..topic3, block range, then continue with --cursor.
For Voyager /events migrations, replace page/lastPage loops with cursor pagination. keys maps to topic0..topic3, name maps to eventName when attributed, and transactionHash maps to txHash:
starkscan --output-format json contract-events "$MARKET_ADDRESS" \
--from-block "$FROM_BLOCK" \
--to-block "$TO_BLOCK" \
--limit 100 \
| jq '.data as $page | {
items: [$page.items[] | {
name: .eventName,
keys: [.topic0, .topic1, .topic2, .topic3] | map(select(. != null)),
data,
blockNumber,
transactionHash: .txHash,
transactionNumber: .txIndex,
number: .logIndex,
timestamp: (.timestampIso | sub("\\.[0-9]+Z$"; "Z") | fromdateiso8601),
timestampIso
}],
nextCursor: $page.nextCursor
}'Treat eventName as display/routing attribution. Keep protocol-critical decoding on raw topic* and data[].
Batch transaction hydration
starkscan --output-format json tx-details \
0xabc... \
0xdef... \
--log-limit-per-tx 32Use tx-details when you already have an ordered tx hash list and want bounded Starkscan transaction previews in one batch. Check logsTruncated and tokenTransfersTruncated before treating child arrays as exhaustive.
Logs are included by default for this convenience command; pass --no-include-logs when you only need compact preview rows.
Smoke-test the CLI path
Run the core read commands against your host before handing the CLI to an agent — a clean status plus a known block, tx, and search confirms the binary, host, and key are wired:
starkscan status
starkscan block <head>
starkscan tx <sample>
starkscan search <sample>When to choose another surface
- Use the SDK for app code.
- Use the REST API for raw HTTP contract debugging.
- Use MCP when an agent needs tool calls rather than explicit commands.
- Stay in the explorer app when the job is visual investigation instead of automation.