What the SDK does that the CLI does not

Where each is the right tool.

Written By Dustin

Last updated 24 minutes ago

Reach for the SDK when

  • You need a write session. Several edits staged in memory and landed as one change, rather than a sequence of shell invocations that can be interrupted halfway.
  • You want structured rationale. commit takes a reasoning summary and a structured rationale object directly, so an automated commit carries real provenance.
  • You want a briefing before writing. projectContext and symbolContext orient an agent in one call instead of a dozen shell-outs.
  • You are issuing sub-tokens programmatically, with the chain verified in the engine.
  • You want errors as values. Every operation returns a discriminated union the type system forces you to check, rather than a non-zero exit you have to remember to test.
  • Performance matters. Native bindings, no process spawn per operation.

Reach for the CLI when

  • It is a handful of commands in a shell script. --json is a versioned contract, not a convenience.
  • You need something the SDK deliberately does not expose: policy changes, key management, obliteration, tag forcing, Forge administration.
  • You are gating a pipeline. tovio health, tovio build-check, tovio fsck, and tovio ci check have no SDK equivalents.

The pipeline builder is a separate entry point

The same package publishes tovio-node-sdk/pipeline — a config-as-code workflow builder that has nothing to do with the repository client. It is a pure function from TypeScript to a workflow document; it holds no token and touches no repository.

Where the SDK is narrower on purpose

Like the MCP surface, the SDK is not a complete remote control. Operations that change the security model or destroy data irreversibly stay on the human-driven CLI. That is a design boundary, not a gap waiting to be filled — a compromised edge should not be able to rewrite policy.

They are the same engine

Neither is a reimplementation. The CLI, the SDK, and the MCP server all call into the same Rust core, so a permission decision, a merge result, and a content address are identical whichever door you came through.