Skip to content

Blog

MCP vs CLI for AI Agents: Do You Need Both?

You already ship a CLI. Add an MCP server when your customers' agents run in clients that can't run the CLI installed on their machines. A decision guide based on client reach, execution environment, and where your API enforces permissions, traced through one read-only Stripe task.

Decision diagram: where your customers' agents run decides the interface. Hosted assistants such as claude.ai, Cowork, and ChatGPT web lead to remote MCP, both groups to CLI plus MCP, and local agents and CI such as Claude Code, Cursor, and Codex to CLI. All three sit on a shared API for business logic and permission checks.
Published on
Read time
16 min

You already ship an API and a CLI. Now someone wants an MCP server, and nobody can say which customers would use it, from which clients, or with what permissions. Shipping it anyway gives you a second surface to secure. Skipping it may shut out customers whose agents work in clients that don't run it.

Add MCP next to your CLI when your customers' agents run in clients that can't run the CLI installed on their machines. Today that means hosted assistants such as claude.ai and Cowork, plus ChatGPT on the web, whose docs describe remote MCP as the way to reach a vendor. When your customers work in local coding agents with a shell, your CLI already reaches them. Either way, your API and its permission model stay shared underneath.

The choice depends on which clients your customers use, where their agents execute, where your API enforces authority, and which operations each interface covers. Neither interface is safer, cheaper, more universal, or more capable by nature. The evidence below follows one safe, read-only task through both of Stripe's interfaces: retrieving a sandbox customer. Stripe is one implementation, and its auth model and coverage do not describe every MCP server. All vendor and client docs cited were read on October 22, 2026.

TL;DR

  • Start from your customers' clients. The hosted assistant docs read describe remote MCP as the way to reach a vendor, and none show those assistants running a customer's installed CLI.
  • Local coding agents such as Claude Code, Cursor, and Codex can run your CLI and load MCP servers. Test that your CLI reaches your API from inside their sandboxes.
  • Authority lives on your server. Client prompts help a user review a call; server checks decide what it can do.
  • Prove the choice with one acceptance test: the same safe task, run in every client your customers use.

Terms to settle first

Either interface can run locally or hosted. A CLI runs on a laptop or a CI runner. An MCP server can be a local subprocess or a vendor service, like Stripe's remote endpoint https://mcp.stripe.com. Tools that act inside a user's browser session are a separate decision, covered in What is WebMCP.

Which clients can reach which interface

ClientCan the agent run your installed CLI?MCP it can load
claude.ai, CoworkNot shown in the docs read. On claude.ai, Claude's code execution runs "within an isolated, sandboxed container." On Team and Enterprise plans, owners set its network egress to off, package managers only, an allowlist, or all domains.Remote custom connectors, reached from Anthropic's cloud. Local servers "aren't available in Cowork or claude.ai."
Claude DesktopNot shown in the docs read.Remote connectors, plus local servers in claude_desktop_config.json.
ChatGPT webNot shown in the docs read.Remote MCP tools through plugins.
ChatGPT desktop, Codex CLI, Codex IDE extensionYes. Their local commands "run inside a constrained environment instead of running with full access by default."MCP servers; stdio only in local Codex environments. Bearer token or OAuth.
Claude CodeYes. The Bash tool "Executes shell commands in your environment," with permission required.stdio, HTTP with OAuth 2.0, WebSocket, and deprecated SSE.
CursorYes. "Cursor runs shell commands directly in your terminal," under your Run Mode.stdio, SSE, and Streamable HTTP, with OAuth using PKCE.
VS CodeNot covered in the sources read."Command (stdio)" and "HTTP (HTTP or Server-Sent Events)" servers. Organizations can restrict which servers are available.

For hosted assistants, the docs read describe only remote MCP, which is the main reason to add MCP. Local coding agents can run your CLI and load MCP servers too.

"Can run your CLI" still has conditions. Cursor's sandbox "blocks unauthorized file access and network activity," and Codex users set permissions per surface, with /permissions in the CLI. So a CLI call to your API can fail inside the agent's sandbox.

One task through both interfaces: retrieve a sandbox customer

Retrieving a customer is a read, and a sandbox keeps live data out of the test.

StepStripe CLIStripe MCP
ClientA local coding agent with a shell, such as Claude Code or Cursor.Any client in Stripe's setup list: Cursor, Claude Code, Claude Desktop and web, Codex, ChatGPT, VS Code, and "Other."
Where it executesOn the customer's machine, through the agent's shell.On Stripe's remote server. Connectors in claude.ai, Cowork, and Claude Desktop reach it from Anthropic's cloud.
Install and onboardingInstall the CLI. For versions newer than v1.50.0, "an Administrator or IAM Admin must enable CLI access before you can authenticate" under Settings → Team and security → MCP and CLI access.Add https://mcp.stripe.com in the client, or "Install the Stripe CLI with npm install -g @stripe/cli and run stripe agent setup." Admins enable MCP access for the team, separately for live mode and sandboxes.
Credentialsstripe login "opens the Stripe Dashboard, where you confirm the code and configure the CLI's access to accounts, sandboxes, and live mode." Credentials go to "your operating system's secure credential store (when available)."OAuth "when a client accesses Stripe on behalf of your Stripe user account," or an agent API key "when an AI application needs independent, persistent access to Stripe," sent as a bearer token when the client lacks OAuth.
Delegated authorityThe accounts and environments approved at login, after an admin enables CLI access.The OAuth consent page grants access to chosen live mode accounts or sandboxes, with permissions set per environment. Grant the sandbox only.
Tool or commandstripe customers retrieve <id>, run without --live.stripe_api_read ("Read data with any Stripe API GET method") against the listed method "Retrieve a customer." The docs do not show its argument schema; stripe_api_details returns parameter details for a method, so confirm the arguments in a live client.
ResultStripe's reference shows a sample response with "livemode": false.Record what the client returns and compare it with the CLI result for the same customer ID.
Approval boundaryClient: the shell tool's permission prompt. Server: CLI access in the Dashboard and the login scope.Client: tool approval, which Stripe says to turn on. Server: MCP access in the Dashboard and the OAuth grant. Stripe's human confirmation covers certain stripe_api_write actions, so this read does not trigger it.

Both columns end at the same Stripe API, configured on the same Dashboard page, MCP and CLI access. The CLI adapts to agents too. Its --non-interactive flag will "Print the browser URL, verification code, and next command as JSON, then exit." It turns on automatically when standard input isn't a terminal.

Client approval and server permission are separate layers

Client approval happens in the customer's application. In its default mode, Claude Code asks permission before most Bash commands, and Cursor asks for approval before using MCP tools by default. These prompts help a person review a call, and their settings belong to the customer.

Server permission happens in your API. At Stripe, admins enable MCP and CLI access per environment. Agent-tagged keys "work the same as other restricted API keys for authentication and permissions." They are also "automatically subject to approval rules, which require a designated reviewer to approve sensitive actions before they take effect." The MCP spec puts the same duty on servers. They "MUST validate that access tokens were issued specifically for them as the intended audience," and they "MUST NOT accept or transit any other tokens."

Several comparison pages say a CLI will "inherit the permissions of whoever invoked it" or reach "everything the shell has access to." Stripe's CLI docs describe something else: login scoped per account and environment, admin enablement, and a device name you set with STRIPE_DEVICE_NAME that is visible in the Dashboard. At Stripe, both interfaces call the same API and are gated from the same Dashboard settings page.

Stripe's calendar shows why the permission model needs a named owner: "Migrate by November 30, 2026. Starting in December, Stripe MCP will stop accepting full-access secret keys and restricted API keys without the Agent tag." After that, requests with an unsupported key receive a 401 response with an OAuth discovery challenge.

Compare the three options on the same criteria

Stripe facts are labeled; the rest depends on your implementation.

CriterionCLI only (status quo)MCP only for agentsBoth
Supported clients and distributionLocal coding agents with a shell. Stripe ships its CLI as an npm package.Remote servers reach hosted and local clients; stdio reaches local clients only.Both groups of customers.
Install and updatesInstalled per machine; behavior can change by version, as Stripe's v1.50.0 rule shows.Stripe: one remote endpoint, added per client by URL, connector, or plugin.Stripe's CLI sets up MCP with stripe agent setup.
Discovery, schema, helpStripe: command reference per resource. Depends on implementation.Stripe: tool descriptions, a methods list, and stripe_api_details for parameters. Depends on implementation.Two descriptions to keep consistent.
Auth and scopesStripe: login scoped to accounts, sandboxes, and live mode, or a key by --api-key or STRIPE_API_KEY.Stripe: OAuth or an agent API key. Spec: stdio takes credentials from the environment; HTTP servers validate audience.Same keys and server checks underneath, if you build it that way.
Approval UIThe agent's shell permission prompt.The client's tool approval, plus Stripe's human confirmation for certain writes with user credentials.Two client prompt models for customers to configure.
API operation coverageStripe: commands for "all types of Stripe API resources."Stripe: "much of the API," through an enumerated list; no OAuth for connected accounts. Depends on implementation.Document the gaps between the two.
AuditabilityStripe: CLI device name visible in the Dashboard. Depends on implementation.Stripe: authorized clients appear as OAuth sessions. Depends on implementation.Map both to one identity model.
ErrorsStripe: non-interactive login prints next steps as JSON.Stripe: unsupported keys get a 401 with an OAuth discovery challenge after the migration.The same failure should read the same in both.
Retry and idempotencyNot covered in the Stripe CLI pages read. Depends on implementation.Stripe: after a human approves a confirmed write, the user tells the agent to retry the call. Otherwise depends on implementation.Test both before you expose writes.
Ongoing maintenanceOne agent surface.A remote service with auth flows and client compatibility to support.Two surfaces over one API, kept in step by contract tests.

The interfaces differ most in client reach, approval UI, and coverage. Auth and audit depend on how your API enforces them.

The counterargument: agents can already call your CLI

At full strength: any agent with a shell can call your CLI, which already has auth, help text, and full API coverage. An MCP server adds a second surface to maintain and gives customers no new capability.

Stripe's CLI "has commands to interact with all types of Stripe API resources," while its MCP server covers "much of the API." Cloudflare launched cf, "the agentic CLI for the entire Cloudflare API," covering "over 3,000 operations," and the launch post does not mention MCP. SmartScope argues that thin MCP wrappers around CLIs can be removed when the agent has terminal access, and keeps MCP for cases such as "Lack of Terminal Access."

The objection holds for local coding agents. It fails for hosted assistants, whose docs describe remote MCP as the path to a vendor. "No new capability" is also contested at Stripe, where the MCP path has per-client OAuth sessions and, with user credentials, human confirmation for some writes.

Decision matrix

ShipWhen these conditions holdWatch for
CLI onlyYour customers' agents run in local coding agents or CI with a shell. The operations they need exist in the CLI. Your API scopes CLI credentials by account and environment.Customers asking from hosted assistants, and agent sandboxes that block your API's network calls.
MCP only for agentsYour customers' agents run mostly in hosted assistants. You can run remote auth and validate token audience on the server.The CLI stays for people and CI, under the same permission model.
BothYour customers split between hosted assistants and local coding agents. You can fund contract tests across both.Business logic creeping into one interface, and coverage gaps such as Stripe's connected-accounts limit on MCP OAuth.

Stripe ships both: one API, one Dashboard settings page for MCP and CLI access, and a CLI that installs the MCP configuration.

Keep one implementation underneath both

If you ship both, keep business logic and permission checks in your API and both interfaces thin. Stripe's design points this way: stripe_api_read maps onto the API's GET methods, and CLI commands map onto API resources. Then test both against the same task fixtures:

  • One fixture per task: a sandbox record, the expected fields, and the credential scope.
  • The same call through both interfaces returns the same data.
  • The same credential without access fails in both.
  • A missing record, a revoked session, and disabled access return messages an agent can act on.

If a test passes in one interface and fails in the other, the two interfaces have drifted.

Operating cost and security limits

Comparisons such as Blocks.ai, Speakeasy, and Manveer Chawla weigh context-window overhead heavily. Those figures depend on the model, client, server, and tool loading, so they cannot settle this for your API. If you measure, record the model and version, the client and version, the task, how tools load, the number of runs, and what you counted.

Security limits apply to both. The MCP spec says local MCP servers "may have direct access to the user's system." For clients that offer one-click local server setup, it recommends they "Warn that MCP servers run with the same privileges as the client." VS Code warns that "Local MCP servers can run code on your machine, and tools can access external services using your permissions." Stripe asks users to "exercise caution when using the Stripe MCP with other servers to avoid prompt injection attacks." A CLI run through an agent's shell has that shell's access to the machine, which is why clients gate the shell tool. On either path, your API credential decides what the call can do.

Remote auth also brings support work. On Atlassian MCP server issue #281, opened October 21, 2026, users report that sign-in never completes from the claude.ai connector, Claude Code, and Cursor. One says "Looks like a 429 error." One vendor and one issue, but plan for that kind of ticket. If customers will bring their own agents to your API through other protocols, see What is Poppy.

Onboarding acceptance test

Run this checklist before you commit to CLI only, MCP only, or both:

  1. List the clients your customers actually use, from support tickets, sales calls, and top accounts.
  2. Pick one safe, read-only task with a sandbox fixture, such as retrieving a sandbox customer.
  3. Verify setup in each client from a clean account, using only your public docs.
  4. Verify the authorization boundary: the credential reaches the sandbox only, a live request is refused, and turning off access blocks both interfaces.
  5. Verify the execution environment: in each local agent, the CLI reaches your API from inside the agent's sandbox at its default permissions.
  6. Verify operation coverage: the task exists in each interface, and you have listed the operations one interface lacks.
  7. Verify errors: a wrong ID, a revoked session, and an unsupported key each return a message the agent can act on.
  8. Verify successful completion: the same record and fields come back in every client. Record the model, client version, and date.
  9. Rerun the test after any change to key or auth policy, such as Stripe's November 30, 2026 migration.

This week, run the test in the two clients your customers use most, with a sandbox record and no writes. The results tell you which row of the decision matrix you are in.

FAQ

Yes, in local coding agents. Claude Code has a Bash tool and also loads MCP servers. Cursor runs shell commands in your terminal and loads MCP servers, and its MCP tools follow the same Run Modes as terminal commands. Stripe's CLI even configures its MCP server with stripe agent setup.

Neither is more secure by nature. Security depends on where your API enforces authority. At Stripe, both interfaces call the same API and are gated from the same Dashboard settings page. The MCP side requires OAuth or agent-tagged keys, which carry approval rules, and lists its OAuth sessions where you can see them.

It can, but a local stdio wrapper reaches only clients that load local servers, such as Claude Desktop, Claude Code, Cursor, and Codex. It does not reach claude.ai, Cowork, or ChatGPT on the web. To reach hosted assistants, the server must be remote; Claude, for example, reaches it from Anthropic's cloud.

A CI runner has a shell, so the CLI fits. Stripe's CLI accepts keys through --api-key or STRIPE_API_KEY. Scope the CI key to the environment the pipeline needs.


Sources


Read more about

Blog

What Is NVIDIA OpenShell, and What Does It Add Beyond a Container?

·15 min read

NVIDIA OpenShell is a policy layer on top of Docker, Podman, Kubernetes, or a microVM. What it controls beyond a hardened container, which defaults and approvals widen an agent's access, and a checklist to run before you adopt it.

Blog

Context Engineering vs Prompt Engineering: How to Diagnose Agent Failures

·13 min read

Prompt engineering shapes the instructions. Context engineering manages everything an agent sees. A method to diagnose which context factor broke an API integration task, with a worksheet and four worked cases.

Blog

Why ChatGPT still recommends the API endpoint you removed

·14 min read

AI assistants keep recommending removed API endpoints because training data predates your release, and deleting the reference page removes the page most likely to tell an assistant the endpoint is gone. A removal playbook for spec, reference, llms.txt, changelog, samples, and help center, plus a check to see whether assistant answers changed.

Blog

Profound alternative for developer tool companies: what to choose

·15 min read

Compare Profound and EkLine for a developer tool company: what each measures, whether it tests coding agents, where the fix goes, and when to keep Profound.

Blog

OpenAI Prompt Caching: When Is the New 12-Hour Cache Cheaper?

·13 min read

OpenAI's 12-hour prompt cache doubles the write price of the 30-minute default. A break-even rule, five modeled workloads, and a replay script show when longer retention lowers the bill and when a higher hit rate costs more.

Blog

What Is LFM2.5-24B-A2B, and Can It Run Your Agent Locally?

·15 min read

LFM2.5-24B-A2B uses 2.45B parameters per token, but runtimes normally keep all 24B weights in memory. What hardware it needs, how its tool calls work, and a worksheet for deciding whether to adopt, test or defer it for a local agent.