I've been saying this for years, and I stand behind it now more than ever: CLIs are not APIs. Some people call them that. I understand the appeal of the framing - it's tidy, it sounds modern, and it gives CLI authors permission to think of their tools as integration surfaces. But the framing is wrong, and adopting it leads to wrong design decisions. A CLI is an interface designed for humans. That's not a limitation. That's the entire point.
The Principle That Hasn't Changed
Good CLI design has always included a consideration that most people don't talk about enough: scriptability.
Not because a CLI is secretly an API waiting to be discovered. Because a well-designed human interface doesn't demand that a human be present. Every interactive prompt, every fuzzy picker, every paginated list that asks you to scroll and select - all of these exist to help the human. And every one of them should have a non-interactive equivalent that lets a script answer silently.
This isn't new thinking. It predates agentic AI by decades. It's why --yes flags exist. It's why --output json exists. It's why environment variables override interactive prompts. Cron jobs needed this. CI/CD pipelines needed this. Shell scripts chained with pipes needed this.
The principle is simple: design the interface for the human, but never require the human to be in the room.
A CLI is an interface for humans. It has never been an API. But a great CLI has always been considerate of its own scriptability - and that consideration is what makes it useful to agents today.
Lee Calcote
Founder, Layer5
What's changed is not the principle. It's the urgency. Agentic AI is here, and it doesn't browse your --help text the way a developer does. It doesn't fuzzy-search through a list of options. It doesn't read your README. It needs to discover what your CLI can do, validate its own inputs before execution, and parse your output without guessing. The principle of scriptability hasn't changed. The bar for what scriptability means has gone through the roof.
What Agents Actually Need
Human CLI users optimize for discoverability and forgiveness. They want tab completion, colorized output, interactive prompts that guide them through complex inputs. When they make a mistake, they want a helpful error message that tells them what to try next.
Agents optimize for predictability and defense-in-depth. They don't need color. They don't need interactive guidance. They need to know, at runtime, what commands exist, what inputs those commands accept, what the valid values are, and what the output schema looks like. They need this information in machine-readable form, queryable from the CLI itself - not baked into a 50-page system prompt that goes stale the moment you ship a new version.
The practical differences break down into four areas.
Runtime schema introspection. An agent should be able to ask the CLI: "What can you do? What does this command expect? What are the valid values for this field?" The CLI itself becomes the documentation. A command like mesheryctl design schema apply dumps the full input schema as JSON. The agent reads it, constructs its payload, and never hallucinates a field name that doesn't exist.
Hallucination-resistant input validation. Agents hallucinate. That's not a moral failing - it's a statistical property of how language models work. Your CLI needs to defend against it. This means strict enum validation (reject any value not in the set), structural validation (does this JSON conform to the schema?), and semantic validation (does this component reference actually resolve to something that exists?). Two layers of defense, minimum. The Meshery CLI spec calls this defense-in-depth, and it's not optional.
Machine-readable output by default. NDJSON - newline-delimited JSON - is the right default for agent consumption. Not pretty-printed JSON arrays that require buffering the entire response before parsing. NDJSON streams one record per line. The agent processes records as they arrive. For a CLI like mesheryctl that returns lists of models, components, and relationships - some numbering in the hundreds - streaming output is the difference between an agent that works and an agent that times out.
Deterministic exit codes. A human reads an error message. An agent reads an exit code. Exit 0 for success. Exit 1-2 for correctable user errors. Exit 3-125 for application-specific failures. Every exit code documented, every exit code stable across minor versions. The agent's retry logic depends on this.
The Meshery CLI Case Study
Meshery is the collaborative cloud native manager - a CNCF project with thousands of contributors that enables teams to adopt, operate, and manage Kubernetes and its workloads. The Meshery CLI, mesheryctl, has been the primary interface for operators since the project's inception.
In early 2026, we published a functional design specification titled "mesheryctl for AI Agents" that lays out how we're evolving the CLI to serve both humans and autonomous agents. The redesign doesn't replace the human interface. It extends the same scriptability principles that have always been part of good CLI design - and raises them to the level that agentic AI demands.
The spec covers four command surfaces. Each one illustrates a different facet of agent-native CLI design.
Design Management
The mesheryctl design surface manages infrastructure designs - the declarative configurations that describe what you want your cloud native stack to look like. For agents, the key additions are:
- A
--payloadflag that accepts raw JSON input, bypassing interactive prompts entirely - A
schemasubcommand for runtime introspection of the design schema - Field selection with
--fieldsto limit output to only what the agent needs - NDJSON pagination for listing designs across large catalogs
--dry-runfor safe exploration without side effects
1# Agent introspects the schema before constructing input2mesheryctl design schema apply --output json34# Agent applies a design using raw JSON payload5mesheryctl design apply --payload '{"name":"prod-redis","config":{...}}' --output ndjson67# Agent lists designs, streaming results8mesheryctl design list --output ndjson --page-size 50
Model Authorship
Models are the packaging unit in Meshery's registry system. A model defines a managed infrastructure component - its schema, its relationships, how Meshery should handle it. The mesheryctl model surface adds four agent-facing subcommands: generate, schema, validate, and register.
The pattern here is schema-driven authorship. The agent asks for the schema, generates a model definition that conforms to it, validates the definition against the schema before submission, and then registers it. At no point does the agent guess at the structure. The CLI enforces correctness at every step.
1# Step 1: Get the model schema2mesheryctl model schema --output json34# Step 2: Validate a generated model5mesheryctl model validate --file ./my-model.json --output json67# Step 3: Register the validated model8mesheryctl model register --file ./my-model.json --output json
Component Definitions
Components are the building blocks inside models - the individual infrastructure resources (a Kubernetes Deployment, an AWS Lambda function, a Terraform resource) that Meshery manages. The mesheryctl component surface follows the same generate/schema/validate/register pattern, but adds the ability to generate component definitions from existing CRDs, Terraform provider schemas, or OpenAPI specifications.
This is where agent-native design gets interesting. An agent can ingest a CRD from a running cluster, generate a Meshery component definition from it, validate the definition, and register it - all without a human touching a YAML file.
Relationship Definitions
Relationships are the most complex surface in Meshery's model system. They define how components interact - hierarchical parent-child structures, network bindings, edge connections, sibling groupings, annotation attachments. The relationship taxonomy spans five top-level kinds, each with subtypes and specific selector semantics.
For agents, the challenge is that relationships require two layers of validation. Structural validation confirms the JSON conforms to the relationship schema. Semantic validation confirms that the referenced components actually exist and that the relationship kind makes sense for those component types. You can't have a network binding relationship between two components that don't expose network interfaces.
The mesheryctl relationship surface handles this with a validate subcommand that runs both layers and returns structured error output that tells the agent exactly what's wrong and why.
The MCP Layer - and Why It's Not Enough on Its Own
There's a lively debate in the industry right now about whether the Model Context Protocol (MCP) is the right abstraction for AI-agent-to-tool integration. MCP adoption has been rapid - OpenAI shipped full MCP support in ChatGPT, and Google DeepMind committed to supporting it across Gemini. The momentum is real.
But MCP is not a replacement for a well-designed CLI. It's a complementary layer. MCP excels at governance - OAuth-based authentication, per-user permissions, structured audit trails, multi-agent orchestration across enterprise boundaries. These are real requirements that CLIs don't natively solve.
Where MCP can stumble is efficiency. Independent benchmarks comparing CLI and MCP interfaces for equivalent agent tasks have found MCP connections failing at meaningfully higher rates than their CLI counterparts, and verbose tool-definition schemas eating into the context budget an agent needs for reasoning. CLI interactions are leaner by construction: the agent calls a command, reads stdout, moves on.
The Meshery CLI spec proposes a mesheryctl mcp command that exposes the CLI's capabilities as an MCP surface. The CLI does the work. MCP provides the governance wrapper. Both layers exist because they solve different problems.
We'll explore the MCP question in depth in a companion post - whether MCP is a durable standard or a transitional layer, and what that means for how you build your tools. For now, the takeaway is this: MCP doesn't replace good CLI design. It depends on it.
MCP doesn't replace good CLI design. It depends on it. The CLI is the execution layer. MCP is the governance layer. Conflating the two leads to tools that are neither efficient nor secure.
Lee Calcote
Founder, Layer5
Six Design Principles
The mesheryctl redesign is guided by six principles that generalize beyond Meshery to any CLI that needs to serve agents:
-
Schema as Source of Truth. Every input and output has a published JSON Schema. The agent never guesses at structure.
-
Non-Interactive by Default. Every interactive prompt has a
--flagequivalent. Every question can be answered silently. This was always good CLI design. Now it's mandatory. -
Defense-in-Depth Validation. Structural validation catches malformed input. Semantic validation catches meaningless input. Both run before any side effect occurs.
-
Streaming Output. NDJSON for lists. Single JSON objects for point queries. Never require the consumer to buffer an entire response.
-
Deterministic Error Reporting. Exit codes are documented and stable. Error output is structured JSON with error codes, not prose messages.
-
Progressive Disclosure. Don't dump every capability into the top-level
--help. Organize commands as noun-verb hierarchies. Let the agent explore the tree:mesheryctl --helpshows resources,mesheryctl model --helpshows actions on models. Hierarchical structure turns CLI discovery into a deterministic tree search.
These principles don't conflict with human usability. They reinforce it. A CLI that validates inputs strictly is also a CLI that gives humans better error messages. A CLI with structured output is also a CLI that humans can pipe through jq. A CLI with non-interactive flags is also a CLI that humans can use in shell scripts.
The best CLIs have always worked this way. The age of agentic AI just made it impossible to ignore.
The mesheryctl functional design spec is open for community input. Join the Meshery Slack to contribute, or explore the Meshery playground to see these patterns in action. Up next: a deep dive into whether MCP is a durable standard or a transitional layer - and what that means for how you build your tools.
Team

