zing-cli
CLI tool + MCP server for paid semantic search and chunk retrieval on the Zing decentralized knowledge platform. Executes USDC micro-payments on Sui and queries the zing-indexbind API.
Two usage personas:
- CLI user — run
zing search,zing chunks,zing expanddirectly in a terminal - MCP agent — AI agents use
zing mcp serveto getzing_search,zing_chunks,zing_expand_chunkstools over stdio
Prerequisites
- Rust toolchain — edition 2021
- USDC on Sui — at least 0.01 USDC on Sui mainnet to fund your zing wallet
Installation
Option 1: Install from GitHub
Option 2: Clone and build
Option 3: Build in place
The binary zing is placed in ~/.cargo/bin/ — ensure it's on your PATH.
Verify
# → zing 0.1.0
Configuration
Zing manages its own config and keypair, fully independent from Sui CLI.
First run
On first run, zing auto-creates its config directory:
~/.zing/
zing_config/
client.yaml — active address, active env, RPC endpoints
zing.keystore — Ed25519 private key (Sui keystore format)
A new Ed25519 keypair is generated and the address is printed. Fund this address with at least 0.01 USDC on Sui mainnet to use paid search.
Defaults and overrides
| Variable | Overrides | Default |
|---|---|---|
ZING_API_URL |
API base URL | https://search.zing.services |
ZING_PLATFORM_USDC_ADDRESS |
Payment recipient | hardcoded platform address |
--api flag |
API base URL | overrides env/fallback |
--rpc flag |
Sui fullnode URL | https://fullnode.mainnet.sui.io:443 |
CLI Commands
zing version
Show the CLI version.
zing search — Paid semantic search
Search across all indexed wikis.
# Basic search
# Scoped to a specific creator's wiki
# Custom result count (default: 20, max: 50)
# Override endpoints
# JSON output
| Flag | Type | Description |
|---|---|---|
--owner |
string | Filter to a specific creator's wiki |
--limit |
int | Max results (default: 20, max: 50) |
--api |
string | Override API base URL |
--rpc |
string | Override Sui fullnode URL |
--json |
bool | Output JSON for agent consumption |
zing chunks — Paid chunk retrieval
Retrieve semantic chunks with per-chunk pricing. Returns precise raw text segments with metadata.
# Basic chunk retrieval
# Return full untruncated text (no excerpts)
# Scoped with custom limit
# JSON output
| Flag | Type | Description |
|---|---|---|
--owner |
string | Filter to a specific creator's wiki |
--limit |
int | Max results (default: 20, max: 50) |
--expand |
bool | Return full untruncated chunk text (no extra cost) |
--api |
string | Override API base URL |
--rpc |
string | Override Sui fullnode URL |
--json |
bool | Output JSON for agent consumption |
zing expand — Expand truncated chunks
Retrieve the full untruncated text for up to 20 chunks by their IDs. Use this when a chunk result shows truncation metadata.
# Expand specific chunk IDs
# JSON output
| Flag | Type | Description |
|---|---|---|
--api |
string | Override API base URL |
--rpc |
string | Override Sui fullnode URL |
--json |
bool | Output JSON for agent consumption |
zing client — Wallet utilities
# Show the active zing address
# Show SUI and USDC balances
zing mcp serve — Start MCP server
Start an MCP server on stdio for AI agent integration. Exposes zing_search, zing_chunks, and zing_expand_chunks as MCP tools. See MCP Server for full documentation.
# With API override
| Flag | Type | Description |
|---|---|---|
--api |
string | Override API base URL |
JSON Output Schemas
The --json flag on search, chunks, and expand commands returns structured JSON instead of human-readable output. All monetary values are in micro-USDC (1 USDC = 1,000,000 micro-USDC).
Search (--json)
Chunks (--json)
Truncation: When truncated is non-null, the text field is an excerpt. The truncated object tells you what was omitted:
| Field | When | Meaning |
|---|---|---|
content_type |
always | "prose", "code", or "table" |
table_rows_total / table_rows_shown |
table chunks | Hidden data rows |
code_lines_total / code_lines_shown |
code chunks | Truncated lines |
prose_chars_total / prose_chars_shown |
prose chunks | Truncated characters |
Use zing expand <chunk_id> or the zing_expand_chunks MCP tool to retrieve the full text.
Expand (--json)
MCP Server
zing mcp serve starts an MCP server over stdio that AI agents (Claude Desktop, Cursor, Codex, etc.) can connect to as a subprocess. The server provides three tools.
Client Setup
Claude Desktop — add to claude_desktop_config.json:
Cursor — add to .cursor/mcp.json:
With API override:
Tool: zing_search
Description:
Search the Zing decentralized knowledge base. Provide short keyword queries (2-4 words preferred). Returns articles with relevance scores, excerpts, tags, and budget info. If you already have specific article_ids from previous results, use zing_chunks with article_ids to retrieve their content directly instead of searching again. Default limit is 20.
Parameters:
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
q |
string | yes | — | Search query (compact keywords preferred) |
owner |
string | no | null |
Filter to specific creator's wiki address |
limit |
int | no | 20 |
Max results (capped at 50) |
Response fields:
| Field | Type | Description |
|---|---|---|
results[].article_id |
string | On-chain article address |
results[].title |
string | Article title |
results[].excerpt |
string or null | Best-matching text snippet |
results[].heading_path |
string[] | Heading hierarchy for the match |
results[].score |
float | Relevance score (cross-encoder reranked) |
results[].article_token_count |
int | Total tokens in the article |
results[].recency_days |
int | Days since last index |
results[].tags |
string[] | Extracted topic tags |
budget.paid_usdc |
string | Total USDC sent (in micro-USDC) |
budget.consumed_usdc |
string | USDC consumed by this request |
budget.remaining_usdc |
string | USDC remaining after this request |
Tool: zing_chunks
Description:
Retrieve raw text segments from search results with per-chunk pricing. Provide short keyword queries. Returns chunks with text, scores, content_type, and truncation metadata. Set expand=true (no extra cost) to return full text instead of excerpts. Use article_ids to filter to specific articles. When truncation metadata is present, call zing_expand_chunks with those chunk_ids to retrieve full text. Default limit is 20.
Parameters:
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
q |
string | yes | — | Search query (compact 2-4 word keywords) |
owner |
string | no | null |
Filter to specific creator's wiki address |
limit |
int | no | 20 |
Max results (capped at 50) |
expand |
bool | no | false |
Return full untruncated text instead of excerpts (no extra cost) |
article_ids |
string[] | no | null |
Filter to specific article IDs |
Response fields:
| Field | Type | Description |
|---|---|---|
chunks[].chunk_id |
int | Unique chunk identifier |
chunks[].article_id |
string | On-chain article address |
chunks[].title |
string | Article title |
chunks[].text |
string | Chunk text (excerpt or full if expand=true) |
chunks[].score |
float | Blended relevance score |
chunks[].chunk_token_count |
int | Estimated tokens in this chunk |
chunks[].heading_path |
string[] | Heading hierarchy |
chunks[].content_type |
string | "prose", "code", or "table" |
chunks[].language |
string or null | Programming language for code chunks |
chunks[].truncated |
object or null | Truncation metadata (see below) |
budget.* |
string | Same structure as zing_search |
Truncation workflow:
zing_chunks → chunk.truncated is non-null → zing_expand_chunks(chunk_ids) → full text
Tool: zing_expand_chunks
Description:
Expand truncated chunks to retrieve full untruncated text. Pass chunk_ids from chunks results that have non-null truncated fields. Max 20 chunk IDs per call.
Parameters:
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
chunk_ids |
int[] | yes | — | Chunk IDs to expand (max 20) |
Response fields:
| Field | Type | Description |
|---|---|---|
chunks[].chunk_id |
int | Chunk identifier |
chunks[].article_id |
string | On-chain article address |
chunks[].heading_path |
string[] | Heading hierarchy |
chunks[].chunk_text |
string | Full untruncated chunk content |
chunks[].content_type |
string | "prose", "code", or "table" |
chunks[].token_count |
int | Estimated tokens |
chunks[].truncated |
object or null | Truncation metadata (always non-null for expand) |
budget.* |
string | Same structure as zing_search |
Payment Flow
Each request costs a flat search/infrastructure fee (default 0.0005 USDC for ≤20 results, scales linearly for larger limits) plus per-result/per-chunk token fees:
- Send USDC — the CLI sends USDC via
0x2::balance::send_funds<USDC>to the platform address. USDC coins are always consolidated into address balance before payment to avoid stale RPC cache issues. - Sign message — BCS-encodes
ApiAccessMessage {q, wiki, transaction_digest, timestamp, expand?, article_ids?}and signs as aPersonalMessagewith the Ed25519 keypair fromzing.keystore. - Submit — sends the signed request to the indexbind API. The server verifies the on-chain payment, runs the search/chunk pipeline, and returns results up to the paid budget.
The budget breakdown is shown in all output:
Budget: paid=10000, consumed=1250, remaining=8750
Project Structure
zing-cli/
Cargo.toml — workspace root (zing-cli + zing-eval)
README.md
src/
main.rs — CLI entry: clap subcommands, output formatting
lib.rs — module declarations
config.rs — loads config, auto-creates keypair on first run
error.rs — typed error codes
keystore.rs — loads Ed25519 keypair from zing.keystore
sui.rs — USDC balance, coin consolidation, payment PTB
api.rs — ApiAccessMessage signing + HTTP calls
models.rs — request/response types (serde)
mcp.rs — MCP server (zing_search, zing_chunks, zing_expand_chunks tools)
eval/ — zing-eval RAG evaluation framework
src/
main.rs — eval CLI (run, list, formula)
checks.rs — L1 retrieval / L2 score sanity
golden.rs — YAML query loader
runner.rs — API client for chunk/search estimate
l3_eval.rs — LLM judge (opt-in)
report.rs — JSON report writer
types.rs — shared types
queries/ — golden query YAML definitions