Included with IVYX Studio

IVYX in your terminal

The same gateway your workspace runs on, with no window open.

Every capability call in IVYX passes a policy gate, and until now that gate was only reachable with Studio in front of you. ivyx is the same gate on a command line, so an MCP client, a CI job and a script all meet the rule that lives in your repository.

$ ivyx init  # write .punica/policy.yaml and .punica/serve.yaml$ ivyx capability list  # what is installed, and what this project serves$ ivyx serve --stdio  # speak MCP to any client$ ivyx runs tail  # gate decisions as they happen

The first four commands, in the order you would run them. ivyx --help is the reference that ships with the binary.

Set it up once

Two commands stand between a fresh install and an agent calling your workspace from another window.

Getting it

It ships inside IVYX Studio on macOS and Linux, and one command in the palette puts it on your PATH. That command copies the CLI into your home directory rather than linking into the app, so updating Studio does not break it, and the launcher runs the app's own runtime, so the machine does not need a Node of its own.

$Install 'ivyx' command in PATH

Connect it to an MCP client

serve prints what it exposes and where the policy came from, and then goes quiet so the stream belongs to the protocol.

$claude mcp add ivyx -- ivyx serve --stdio

serve speaks stdio in this release. --print-config prints the connection line for Claude Code, Claude Desktop or Cursor, or the raw JSON if your client wants a config file.

A project says what it exposes in .punica/serve.yaml, so a capability nobody listed is refused rather than served.

Made for CI

policy explain runs the gate and executes nothing, so a rule can be asserted in a pipeline before anything is allowed to happen. It answers with what the gate will do rather than what the catalogue advertises, which is not always the same thing.

$ivyx policy explain mlops.model.promote --args '{"alias":"production"}'

--json is on every command, so a refusal is a failing step rather than a line in a log.

Exit codes

0
The call is allowed.
2
Refused, or the input was invalid.
1
Something went wrong.

Nine commands

The first wave, and ivyx --help is the reference that stays current.

Serve

  • ivyx serve --stdio

    Serve capabilities to an MCP client.

  • ivyx status

    Whether serve is running, what it serves, where policy is.

  • ivyx init

    Write .punica/policy.yaml and .punica/serve.yaml.

Policy

  • ivyx policy lint

    Schema, unknown ids, unreachable rules.

  • ivyx policy explain

    Run the gate against a call. Nothing executes.

  • ivyx capability list

    Every capability installed, or only the ones served.

Record

  • ivyx runs show

    Every gated call in one run.

  • ivyx runs tail

    Gate decisions as they happen.

  • ivyx evidence verify

    Signature and hashes of an evidence package.

Five things it does not do

It does not carry its own policy

The rule comes from the project, found by walking up from your directory the way git finds a repository. A second policy file would be a second definition of the policy.

It does not decide for a person

A call that needs a person is refused when nobody is there, and the record says it needed a person rather than that it failed. What counts as needing one is the gate’s answer, not the catalogue’s: an approval a capability declares is enforced, and one the catalogue synthesized for display is not.

It does not hold a signing key

There is no account and no cloud, and the CLI signs nothing. Studio’s key is sealed by the OS keychain inside its own process and is not readable from here, which status reports in those words rather than as “no key”. Verifying an evidence package still works, because a signature carries the public half a verifier needs.

It does not run where it cannot enforce

It probes the substrate for the guards it depends on rather than comparing version numbers, and on an older one it stops and names what is missing. It also reads the capability budget back after applying it and refuses to serve if it did not take effect, because a server that believes it serves four capabilities while serving five hundred is worse than one that does not start.

It does not overwrite what you wrote

init writes only the files that are missing, so running it in a project that already has a policy leaves that policy alone. runs tail marks a record as seen only after it has read it, so a file caught mid-write is retried rather than skipped.