@finchtech/cli
v0.4.0
Published
Finch Agent CLI for wallet-owned marketplace and MCP workflows.
Keywords
Readme
Finch Agent CLI
Install the public npm package with npm install -g @finchtech/cli, then run finch --help. The primary executable is finch; finchtech is an equivalent fallback for machines where another application already owns the finch command.
The Finch Agent CLI stores wallet keys, AgentCLI Session bearers, and MCP grant bearers only in an owner-only FINCHTECH_HOME, which defaults to ~/.finchtech; secrets are never accepted as command arguments or emitted to stdout.
For an existing private key, run finch wallet use --file <PATH> on a fresh installation, then finch login --help to choose an authentication chain. The file must contain a single 0x-prefixed 32-byte hex private key and have owner-only permissions. First import is offline and makes that wallet current. finch wallet create generates a new identity instead. An existing Account switch requires login and remote revocation before changing the current wallet. Incomplete wallet files require recovery from backup; residual local authorization requires restoring the original wallet or explicitly clearing local authorization with finch logout --local.
finch logout revokes Account-bound remote authority before removing local Session and grant state. If invalid, corrupt, or legacy Session metadata prevents that flow, finch logout --local performs an explicit offline reset of only session/ and grants/. It makes no network request and reports remoteRevoked: false; it remains available while an irreversible recovery is pending and preserves profiles, registered wallets, transaction journals, and recovery records so the user can log in again and run the recorded recovery command. Ordinary logout and wallet switching remain blocked until that recovery completes.
CLI-authored EVM addresses accept canonical lowercase or valid EIP-55 input and are normalized to lowercase before request validation and transport. Invalid mixed-case and uppercase forms are rejected. Remote responses and Remote MCP plans remain strictly lowercase so normalization cannot change signed or hashed plan bytes.
Valid remote Identity, Agent, Task, Skill, and OAuth errors are emitted in their original domain envelope with the remote trace ID. Local transport failures use CLI_REMOTE_UNAVAILABLE; malformed or contract-invalid responses use CLI_RESPONSE_INVALID. Locally synthesized failures use a null trace ID rather than impersonating a server trace.
Skill upload failures also retain the final uploadBytes, uploadObjectKind, HTTP remoteStatus (null when no response was obtained), and available allowlisted remoteCode, remoteRequestId, and remoteTraceId in the JSON-encoded state. Locally synthesized errors retain the existing null reasonCode and traceId contract; downstream evidence is labelled explicitly in state. These fields never include raw response text, upload filenames, credentials, or transport causes. not_attempted refers only to chain submission: storage may have accepted an object before a response was lost. Follow contact_support until the individual attempt is reconciled; another publication's status is not evidence about this attempt.
ZIP import failures return AGENT_MARKET_REQUEST_INVALID, exit code 2, and fix_request before upload. The JSON-encoded state identifies SKILL_SOURCE_ZIP_INVALID and a zipReason: archive_too_large, expanded_content_too_large, utf8_flag_missing, filename_encoding_invalid, or invalid_archive. Size failures include actualBytes, maxBytes (10,485,760), and sizeBasis: archive measures the compressed input; declared_expanded is the cumulative uncompressed size declared by entries at the first limit violation, before decompression. A safely decoded root-relative entry path is included when available. Non-ASCII filenames require valid UTF-8 bytes and bit 11 in the ZIP headers; rebuilding with those flags preserves file contents. These import limits are independent of final upload admission.
Intent HTTP failures include remotePath: "/api/skills/intents", remoteStatus, and available safe correlation IDs. responseIssue distinguishes transport_failed, body_read_failed, empty_body, invalid_content_length, response_too_large, invalid_json, and schema_mismatch. Schema failures include at most eight schemaIssues with known field paths and validation keywords; an empty path means the response root or an unrecognized field, whose name is withheld. No response values, arbitrary property names, URLs, or raw causes are printed. Malformed success responses are rejected during intent, before signing or writing a pending-send marker. Use the returned recovery command for the same publication; the CLI never automatically retries intent requests or resubmits transactions. The fingerprint identifies the local recovery journal, not a server trace; use returned remote IDs to correlate server logs.
The CLI measures the exact final multipart request, including metadata and framing. At or below 4,000,000 bytes it posts that request to the inline upload route. Above it the object goes through the staged transport instead: the CLI asks for a signed URL, writes the bytes straight to storage, and has the server read them back, verify them and pin them, so the platform's 4,500,000-byte request-body limit does not apply. These MB thresholds are decimal. The per-object ceilings are enforced against the final object either way: 30 MiB (31,457,280 bytes) for a package, 5 MiB for a cover, and 3 MiB (3,145,728 bytes) for a manifest. The package ceiling is one shared constant, applied by upload admission, by the retrieval route, by this client before it uploads, and by this client when it downloads, so a package that publishes is a package that reads back. Repacking a compressed source ZIP may increase its size. Passing admission does not certify production upload success or authorize replaying a previously failed publication.
The command groups are wallet, login/status/logout, site, mcp doctor, mcp connect, mcp authorize, mcp grant, creator, credentials, intent, operation show, purchase, task, and skill. Run finch --help for the exact command list as one JSON value.
finch site open creates a sixty-second one-use handoff from the active AgentCLI Session and opens the exact configured Finch origin in the local default Browser. finch site login <REQUEST_URL> binds a website-created five-minute request once, then opens the same confirmation page. Both commands require the wallet, CLI, and graphical Browser on the user's machine. A launch failure returns BROWSER_OPEN_FAILED without printing the secret completion URL. The Browser receives only a normal seven-day Finch Web Session; wallet signing, broadcast, and market confirmation remain local CLI actions.
finch mcp doctor is read-only. It returns a checks object for endpoint, wallet, local Session, remote Session authority, and MCP discovery. Each check reports ok, missing, invalid, unavailable, or skipped, with guidance for unhealthy checks. Missing login or wallet state does not prevent independent discovery checks; an invalid endpoint prevents network checks. The command emits one JSON report with exit code 0 when ready, or 2 when any required check is unhealthy. It verifies the endpoint, wallet/key binding, Account, Session identity, environment, audience and expiry, plus the MCP challenge and required OAuth capabilities. Each remote read has a 15-second timeout. Wallet inspection does not migrate legacy files. Client guide availability, client names, guide versions and repository paths do not affect readiness; compatibilityManifestUrl is only an informational link. The Agent Harness owns Remote MCP configuration, OAuth credentials, and refresh; the CLI never configures the Harness and never reads Harness OAuth material.
The CLI approves the Harness's native OAuth request with the active local AgentCLI Session through one of three entry points, tried in this order:
finch mcp connect -- <MCP_CLIENT_LOGIN_COMMAND...>runs the MCP client's own login command, for examplefinch mcp connect -- codex mcp login finch --no-browser. It keeps the command's stdin open while it waits, forwards its output to stderr with the authorization code redacted, takes the first<origin>/oauth/authorize?URL it prints (including an OSC 8 hyperlink target), and approves only that one request. It then waits a bounded time for the command to exit and reportsloginCommandExitCode: 0; a second, different authorization request, a missing URL, or a failed or hanging command is a typedMCP_AUTHORIZATION_FLOW_FAILEDerror whose message names the next step.finch mcp authorize --stdinreads one raw authorization URL that the Agent copied unchanged from the client output, for exampleprintf '%s' '<URL>' | finch mcp authorize --stdin. A URL is never accepted as an argument, because Windows package-manager and Volta launchers split it at&.finch mcp authorize <REQUEST_TOKEN>runs the exact command shown on the Finch authorization page when the Agent cannot see the URL. The versioned base64url token carries the original request without shell metacharacters.
Each entry point applies the same origin, redirect, state, scope, and RFC 9207 issuer checks. A loopback HTTP callback is delivered directly to the waiting listener on this machine, without a Browser or any Finch credential and without following redirects; localhost is tried on each loopback address it resolves to only while no connection exists, and a lost response is reported as uncertain rather than resent. An HTTPS callback, such as a proxied workstation or a web editor, is opened in the local Browser. The one-use code is never returned. Exit code 0 of the login command shows only that it exited successfully; confirm the connection with the Harness's own identity_actor_get. The server refuses a CLI older than 0.4.0 with an upgrade instruction before issuing a code. No entry point uses a Browser Session, Social account, or extension wallet as Agent authority. Configure https://www.finchtech.ai/mcp once through the Harness, then use MCP identity_actor_get together with finch status to verify exact Account and wallet alignment before custody. The server-reported environment is diagnostic and never selects the CLI endpoint or a transaction chain.
Doctor's ready: true is scoped by readinessScope: "cli_session_and_mcp_discovery". Its harnessOAuth.status is always not_checked: CLI login and valid discovery metadata do not establish that the connected Harness has usable OAuth credentials, a saved issuer, or working refresh. The result includes identity-verification and native reauthorization guidance. If the Harness reports an OAuth failure, start its native MCP authorization flow again, approve the fresh request through the entry points above, then verify MCP identity again.
Run finch login --help to list supported production authentication chain IDs (1, 10, 56, 8453, 42161). For example, finch login --chain-id 56 selects BNB Smart Chain for authentication only.
Ordinary installs require no profile file or environment selection. Network commands default to the PROD endpoint at https://www.finchtech.ai. finch login --chain-id <CHAIN_ID> explicitly selects only the authentication chain, which the selected server must support. Market transaction chains come from Remote MCP/API plans and are independent of the login chain. intent approve signs only the shared publication-v2 or Local-purchase-v1 EIP-712 authorization; it cannot sign arbitrary transaction calldata.
operation show and signing-decision recovery require an active, unexpired MCP grant for the current account and endpoint with agent_market:operations:read. The CLI selects that grant from protected local state and never substitutes the AgentCLI Session bearer.
Creator commands are thin projections of the shared Agent Market merchant operations. Reads require agent_market:merchant:read; mutations require agent_market:merchant:write, a stable caller-chosen --request-id UUID for local idempotency recovery, and --expected-revision wherever the shared operation requires If-Match. Structured request bodies come from bounded JSON --from-file documents and are validated against the same shared schemas before HTTP.
Local AgentOn HMAC generation is not a product command. credentials material-download <setupId> --out-file <absolute-path> claims the AgentOn setup, downloads only its exact live lease as raw FCR1, and creates a new owner-only file; stdout contains only keyId and path. credentials fulfill accepts only Direct credential uploads. It accepts either an existing protected FCR1 with --from-file <path>, or a protected raw Bearer token with --bearer-token-file <path> --key-id <keyId>; the latter validates one whitespace-free token and adds the Bearer prefix only in CLI memory. Secret bytes never enter argv or stdout.
purchase transaction <operationId> is read-only. It requires an active agent_market:buyer:purchase MCP grant and returns the two server-composed transaction requests plus their chain authority; it does not sign or broadcast arbitrary calldata.
purchase submit <operationId> requires the same grant and uses only the source-controlled public RPCs for the plan's chain. It uses the protected wallet to re-encode and submit the exact server-composed USDC approval and AgentService Vault purchase. Before signing it verifies eth_chainId, the reviewed chain contract authority, every transaction field, and a successful eth_call simulation. Every returned broadcast hash is atomically checkpointed before receipt waiting; a restart re-verifies the exact wallet, call, receipt, block, and current server authority and never re-broadcasts a known phase. Finch then verifies the canonical confirmation event and creates Call Rights. If the purchase receipt conclusively reverts, the paired zero-allowance cleanup follows the same checkpoint discipline; unknown receipts are never guessed. The RPC owns nonce selection. User RPC and environment variables are ignored, and neither RPC URLs nor wallet keys are emitted.
purchase recover-approval <operationId> --transaction-hash <hash> is the narrow adoption path for an approval broadcast before its durable checkpoint was written. It re-fetches the current server authority and active wallet, then verifies the exact successful approval transaction and sufficient live token allowance on the plan chain before writing one owner-only recovery journal. It never broadcasts, confirms, scans chain history, or accepts a nonce. A subsequent purchase submit continues with the purchase phase without approving again.
If the process exits after broadcasting the Vault purchase but before confirmation returns, recover with purchase confirm <operationId> --transaction-hash <hash>. This command never trusts the supplied hash: Finch fetches and decodes the canonical chain receipt before any Call Rights mutation.
Task and Skill business discovery and preparation stay in the Remote MCP server. The task commands only fund an exact prepared Task pool, sign exact prepared awards, or submit an exact prepared reclaim. Skill purchase, conversion, price, and supply commands submit strict MCP preparations. skill publish-submit --path <file-or-directory> --from-file <plan> and skill version-submit accept either one file or one directory, then apply the plan's independent plaintext, finchip_v2, or lit content mode; filtering, deterministic ZIP construction, encryption, upload, and key custody remain local. skill asset-upload --path <cover> --from-file <plan> uploads a separately prepared public cover, and skill presentation-submit --from-file <plan> publishes bounded public presentation metadata without changing protected package bytes. skill download --from-file <delivery> --out-file <new-file> requires an active AgentCLI Session for both plaintext and protected content. It retrieves packages through the authenticated delivery gateway, signs with the entitled local wallet for protected content, verifies the SkillRoot and every file (or the plaintext ZIP hash for historical Skills), acknowledges the verified download, and then creates an owner-only file. CLI 0.3.8 or newer is required; an acknowledgement failure aborts before output-file creation. Every transaction action uses its plan's chain, source-controlled public RPCs, and reviewed chain-level contract authority. The CLI recomputes transaction bytes locally and rejects mismatched chains, destinations, calldata, values, source commits, or envelope tags.
ZIP import and SkillRoot publication
Version 0.3.1 fixes Skill search continuation: pass the returned nextCursor unchanged as
--cursor. Search uses the server rules; the CLI does not implement a matching algorithm.
Older clients receive an upgrade message from the Skill search API.
Version 0.3.0 upgrades Skill publication and encrypted delivery together. Upgrade with
pnpm add -g @finchtech/[email protected] and verify finch --version before publishing new Skills
or downloading encrypted Skills from the upgraded gateway. Older CLI versions cannot use
the new encrypted delivery, including for historical Skills; 0.3.0 retains historical package support.
A single .zip passed to skill publish-submit --path or skill version-submit --path is expanded locally before filtering and primary-document hashing; request a file source plan for this input. Directory inputs keep ZIP assets as ordinary files. Imports support stored/DEFLATE ZIPs up to the package ceiling compressed and expanded, with at most 1024 entries. Unsafe paths, symbolic links, encrypted ZIPs, ZIP64, conflicting entries, and corrupt content are refused. Include SKILL.md, README.md, or one unambiguous root Markdown document.
New Skills publish a DAG-CBOR SkillRoot hash in one graph bundle. Existing Skill identities keep ZIP-hash updates. New Skills require this updated CLI; it verifies every object and decrypts protected files locally into an ordinary ZIP. Historical ZIP downloads and whole-package decryption remain supported. A pending publication reuses its uploaded bytes and saved root commitment on resume.
The publication ADR specifies the pinned draft, bundle/profile format, compatibility trust boundary, and rollout order.
Finch-managed and Lit downloads use Oracle V2 device-sealed grants and a non-extractable local CryptoKey. The updated gateway also supports historical Finch-managed and Lit ZIPs through this delivery. It refuses old bare-key buyer requests; use the updated CLI. Both providers use the same sealed delivery. See ADR-0065 for deployment requirements.
Publication preparation accepts an optional summary (up to 500 characters). It is committed in
SkillRoot exactly as supplied, matching Browser publication metadata; omission means an empty summary.
Equal public file bytes, paths, name, summary, version and history produce equal roots. Encrypted
publications use random keys/IVs and need not produce the same root. Updates send the proposed
manifest for server validation; URI intents are prepared after the new chain binding is confirmed.
Finch-managed publication key requests use a signed timestamp and a one-time nonce. Each request is valid for five minutes; retrying after expiry or a lost response requires a fresh signature. The gateway rejects older CLI publication requests without timestamps. Historical downloads are unchanged.
Local publication failures
Directory publication rejects symbolic links, including internal relative links and broken links.
It skips excluded paths (for example .git, node_modules, .aws, and credential files) before reading
or descending into them. excluded lists a skipped directory once instead of enumerating its children.
Keep required resource paths functional when preparing a link-free source; deleting required links is
not a valid repair. ZIP imports also reject symbolic links.
Source errors keep exit code 2 and AGENT_MARKET_REQUEST_INVALID. Parse the JSON string in error.state
for diagnosticCode: SKILL_SOURCE_SYMLINK_UNSUPPORTED, SKILL_SOURCE_UNREADABLE, or
SKILL_UPLOAD_SIZE_INVALID, SKILL_SOURCE_ZIP_INVALID, SKILL_SOURCE_PRIMARY_DOCUMENT_INVALID, or SKILL_MANIFEST_SIZE_INVALID. Source diagnostics include a root-relative path (. for the selected
root); size diagnostics include actualBytes and maxBytes. The internal packaging bound is the package ceiling and applies to the final
upload object, including SkillRoot metadata and encryption overhead. STORE ZIP construction does not
compress files. A size rejection occurs before that upload and before transaction submission.
Publish, version, and publication-recovery failures also include phase, fingerprint,
transactionHashes (keyed by primary, uri, or lit), submissionStatus, and recoveryCommand in
error.state. packaging includes local hashing/encryption; transaction covers signing, broadcast,
and receipt handling. A validated remote error keeps its code, message, trace and HTTP status
(remoteStatus), with its original state retained as remoteState; publication retry guidance takes
precedence over a remote service's generic retry flag. Private causes, RPC URLs, credentials and
journal contents are never printed.
Publication failures report retryable and nextAction according to the failure. A projection failure after confirmed transactions can be retryable; inspect unconfirmedActions before claiming the complete publication succeeded. This is not permission to replay a paid operation.
not_attempted means no send was attempted in this invocation and no hashes were found in the
validated journal; it is not proof about other invocations. hash_known includes known transaction
hashes. uncertain means sending or durable checkpointing failed. For creation/version/key stages, contact support before retrying or
recovering, even when a hash is shown. A non-null recoveryCommand is provided only after a journal
is validated or saved and no submission/checkpoint uncertainty was observed. Recheck CLI/MCP identity
and use that command rather than repeating publish-submit. Cleanup failures do not claim a journal
still exists. If source is unavailable or its excluded-path inventory changed across CLI versions,
the fingerprint-only recovery command can use the already stored publication bytes.
These fixes require CLI 0.3.3 or newer; npm 0.3.2 does not include them. Updating a Skill does not upgrade the installed CLI. Journal v6 saves a pending stage before signing/submitting. Missing hashes in creating stages of a pending or legacy v4/v5 journal block automatic resubmission; follow the reported chain-state checks and contact support. CLI 0.3.7 permits the URI assignment stage to converge through its typed recovery path. Known hashes are verified without rebroadcast. The pending marker also blocks destructive local authorization/wallet cleanup through the recovery inventory.
Bootstrap and health reports (CLI 0.3.4+)
First-wallet offline import, installed Account-switch revocation, partial doctor checks and exit code 2, contextual wallet recovery guidance, login authentication-chain help, and strict OAuth UUID response validation require CLI 0.3.4 or newer. Updating the website or Skill does not upgrade an installed CLI.
WebP image detection (CLI 0.3.5+)
CLI 0.3.5 fixes valid WebP covers and packaged detail images being rejected when binary file-size bytes were decoded as UTF-8. Upgrade the installed CLI to receive the local detection fix; website or Skill updates alone do not update the executable. Image types, size limits, and publication recovery rules are unchanged.
Market category compatibility (CLI 0.3.6+)
Use CLI 0.3.6 or newer for the expanded market categories. Skill response display categories now accept bounded text, so future taxonomy additions do not require another CLI upgrade. Updating the website or this Skill does not upgrade an installed CLI.
Staged uploads and external media (CLI 0.3.7+)
CLI 0.3.7 supports authorized external-media manifests and 30 MiB final packages on both upload and download. Browser publishing still uses multipart and refuses external media. Failed staged uploads attempt ticket release and report its result in the sanitized diagnostic. Presentation submission reports progress and whether setting the same URI can safely converge; a stale plan, authorization failure or invalid input still requires correction before retrying. Read the maintained Finch Market Skill for the complete external-host and recovery boundaries.
Diagnostic and interoperability fixes (CLI 0.3.9+)
CLI 0.3.9 removes the mcp.supportedClients field from doctor. Its health checks do not fetch client guides or migrate legacy wallet files. Omitted or empty OAuth scope uses the server-resolved registered defaults; explicit requested scopes remain checked. Callback target, original query values and state remain verified, independently of query ordering or authorization-code length. Upgrade the installed CLI to receive these fixes; updating the Skill or website alone does not apply them.
MCP connection without a Browser (CLI 0.4.0+)
CLI 0.4.0 adds finch mcp connect and finch mcp authorize --stdin, delivers loopback OAuth callbacks directly instead of opening them in a Browser, and verifies the RFC 9207 iss the Finch authorization server now advertises. It identifies its release on authorization, and the server refuses older releases with an upgrade instruction because they cannot accept iss. Upgrade the installed CLI; updating the Skill or website alone does not apply this.
