<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jan Čurn</title>
    <description>The latest articles on DEV Community by Jan Čurn (@jancurn).</description>
    <link>https://dev.to/jancurn</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F366414%2F46ed2d8a-51e3-48d3-b4d2-438d39008d13.jpg</url>
      <title>DEV Community: Jan Čurn</title>
      <link>https://dev.to/jancurn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jancurn"/>
    <language>en</language>
    <item>
      <title>MCP + CLI &gt; MCP vs. CLI</title>
      <dc:creator>Jan Čurn</dc:creator>
      <pubDate>Wed, 14 Oct 2026 12:06:02 +0000</pubDate>
      <link>https://dev.to/apify/mcp-cli-mcp-vs-cli-36hd</link>
      <guid>https://dev.to/apify/mcp-cli-mcp-vs-cli-36hd</guid>
      <description>&lt;p&gt;&lt;a href="https://x.com/skirano/status/2034269154404868314" rel="noopener noreferrer"&gt;That tweet&lt;/a&gt; got 1.6k likes in March: &lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-2034269154404868314-418" src="https://platform.twitter.com/embed/Tweet.html?id=2034269154404868314"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2034269154404868314-418');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2034269154404868314&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Perplexity’s CTO &lt;a href="https://x.com/morganlinton/status/2031795683897077965" rel="noopener noreferrer"&gt;reportedly told his team&lt;/a&gt; they’re moving from MCP to APIs and CLIs:&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-2031795683897077965-871" src="https://platform.twitter.com/embed/Tweet.html?id=2031795683897077965"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2031795683897077965-871');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2031795683897077965&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;OpenClaw &lt;a href="https://x.com/chrysb/status/2025701861031121331" rel="noopener noreferrer"&gt;left MCP out on purpose&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-2025701861031121331-772" src="https://platform.twitter.com/embed/Tweet.html?id=2025701861031121331"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2025701861031121331-772');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2025701861031121331&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Garry Tan’s version was shorter: &lt;a href="https://x.com/garrytan/status/2031910564344262988" rel="noopener noreferrer"&gt;“MCP sucks honestly.”&lt;/a&gt;"&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-2031910564344262988-310" src="https://platform.twitter.com/embed/Tweet.html?id=2031910564344262988"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2031910564344262988-310');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2031910564344262988&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;They’re half right: the problem is real, but the diagnosis isn’t.&lt;/strong&gt; What’s broken is how most agents use MCP, and the fix is not to throw the protocol away but to stop using it badly.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This piece builds on my talk at AI Engineer World’s Fair “MCP doesn’t suck. Your agent does.” (San Francisco, July 2026). &lt;a href="https://www.youtube.com/watch?v=pAnLpiAG6Es" rel="noopener noreferrer"&gt;Watch it on YouTube&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/pAnLpiAG6Es" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem is the harness, not the protocol
&lt;/h2&gt;

&lt;p&gt;Most agents treat MCP tools as prompt-time function calls. Connect a server and every tool definition lands in the context window. Call a tool and the full result lands there too. Ten servers with five tools each, and you pay thousands of tokens on every turn before the agent has done anything. Results pile up, context rots, the agent gets slower and less accurate, and data the model never needed to see is now inside the model.&lt;/p&gt;

&lt;p&gt;None of that is in the spec. MCP already has the fixes: progressive tool discovery (Anthropic’s &lt;a href="https://www.anthropic.com/engineering/advanced-tool-use" rel="noopener noreferrer"&gt;tool search tool&lt;/a&gt;, Cursor’s &lt;a href="https://cursor.com/blog/dynamic-context-discovery" rel="noopener noreferrer"&gt;dynamic context discovery&lt;/a&gt;), code mode (&lt;a href="https://blog.cloudflare.com/code-mode/" rel="noopener noreferrer"&gt;Cloudflare&lt;/a&gt; and &lt;a href="https://www.anthropic.com/engineering/code-execution-with-mcp" rel="noopener noreferrer"&gt;Anthropic&lt;/a&gt; both wrote it up), and sub-agents with split context. But most MCP clients don’t implement them. The protocol moves faster than the ecosystem.&lt;/p&gt;

&lt;p&gt;Now look at what CLIs get right, mostly by accident. Agents never load a CLI’s docs all at once; they read &lt;code&gt;--help&lt;/code&gt; when they need it. They run CLI tools as code by default, chaining them with pipes and shell scripts. And every model knows the shell by heart, because there’s 50 years of it in the training data. The catch here: a CLI is a local black box. No standard transport, no standard auth, no discovery, no way to scope or intercept what it does to a remote service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That’s why agents have MCP connectors, not CLI connectors.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP for remote, CLI for local
&lt;/h2&gt;

&lt;p&gt;The fix is to use each where it’s strong. MCP stays the standard remote interface: server discovery, authentication, and access control. The CLI becomes the local interface between the agent and MCP. That’s what we built in &lt;a href="https://github.com/apify/mcpc" rel="noopener noreferrer"&gt;&lt;code&gt;mcpc&lt;/code&gt;&lt;/a&gt;, an open-source universal CLI client for MCP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; ┌──────────┐   Bash()   ┌────────┐    MCP    ┌────────────┐
 │ AI agent │ ─────────► │  mcpc  │ ────────► │ MCP server │
 └──────────┘            └────────┘           └────────────┘
                                     Sessions, OAuth, Tools,
                                     Resources, Prompts,
                                     Tasks, x402, ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The agent only needs one tool, &lt;code&gt;Bash()&lt;/code&gt;, to call &lt;code&gt;mcpc&lt;/code&gt;, learn how it works through &lt;code&gt;--help&lt;/code&gt;, and interact with MCP servers. And it can leverage the full MCP protocol out of the box: persistent sessions, OAuth 2.1 (including enterprise SSO), tools, resources, prompts, async tasks, skills, x402 payments, and a code mode using &lt;code&gt;--json&lt;/code&gt;. &lt;code&gt;mcpc&lt;/code&gt; speaks MCP 2026-07-28 and falls back to older versions. No LLM inside, fast, and minimal dependencies. As a bonus, one login and one set of live sessions can be shared between many agents on the same machine.&lt;/p&gt;
&lt;h2&gt;
  
  
  What it looks like in the shell
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;apify/tap/mcpc          &lt;span class="c"&gt;# or: npm install -g @apify/mcpc&lt;/span&gt;

mcpc login mcp.apify.com             &lt;span class="c"&gt;# OAuth once; tokens go to the OS keychain&lt;/span&gt;
mcpc connect mcp.apify.com @apify    &lt;span class="c"&gt;# persistent session&lt;/span&gt;
mcpc @apify                          &lt;span class="c"&gt;# server info, capabilities, instructions&lt;/span&gt;
mcpc @apify &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"crawler"&lt;/span&gt;           &lt;span class="c"&gt;# progressive tool discovery&lt;/span&gt;
mcpc @apify tools-get search-actors  &lt;span class="c"&gt;# one tool's schema, only when needed&lt;/span&gt;
mcpc @apify tools-call search-actors keywords:&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"tiktok scraper"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And code mode, where the agent writes a script instead of making a round trip through its context for every call:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mcpc @apify tools-call search-actors keywords:&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"tiktok scraper"&lt;/span&gt; limit:&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nt"&gt;--json&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.content[0].text | capture("`(?&amp;lt;actor&amp;gt;[^`]+)`").actor'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | xargs &lt;span class="nt"&gt;-I&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; mcpc @apify tools-call fetch-actor-details actor:&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"{}"&lt;/span&gt; &lt;span class="nt"&gt;--json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That’s progressive discovery and code mode on any MCP server, whether or not the agent’s own MCP client supports either.&lt;/p&gt;
&lt;h2&gt;
  
  
  What the evals say
&lt;/h2&gt;

&lt;p&gt;We built &lt;a href="https://github.com/apify-projects/connector-bench" rel="noopener noreferrer"&gt;connector-bench&lt;/a&gt; to measure the efficiency of &lt;code&gt;mcpc&lt;/code&gt; against CLIs and naive MCP implementations. Each run gives an agent the same cross-server task under three harnesses: raw MCP with every tool loaded into context, the native CLIs for the same services, and &lt;code&gt;mcpc&lt;/code&gt;. We track cumulative cost against wall-clock time.&lt;/p&gt;

&lt;p&gt;Here’s an example comparing &lt;a href="https://mcp.apify.com/" rel="noopener noreferrer"&gt;Apify MCP server&lt;/a&gt; with &lt;a href="https://docs.apify.com/cli/" rel="noopener noreferrer"&gt;Apify CLI&lt;/a&gt; on an Actor discovery scenario:&lt;/p&gt;



&lt;p&gt;In many of our tests, &lt;code&gt;mcpc&lt;/code&gt; finishes the job faster than native CLI, albeit sometimes with higher cost. That’s understandable, as native optimized CLIs are usually less verbose and more token-efficient than a generic CLI wrapper for MCP. But we believe there is plenty of room for optimization and the performance of &lt;code&gt;mcpc&lt;/code&gt; will converge towards native CLIs.&lt;/p&gt;
&lt;h2&gt;
  
  
  So stop saying CLI beats MCP
&lt;/h2&gt;

&lt;p&gt;MCP + CLI beats both. Even OpenClaw uses MCP through &lt;a href="https://github.com/openclaw/mcporter" rel="noopener noreferrer"&gt;mcporter&lt;/a&gt;, an MCP-to-CLI converter, which proves the point. The problem was never the protocol. It was that agents implemented MCP poorly.&lt;/p&gt;

&lt;p&gt;MCP has ten official SDKs for languages like TypeScript, Python, or Go, but none for the shell, the most universal programming language. &lt;code&gt;mcpc&lt;/code&gt; is our attempt to fill that gap, so any agent with a code runtime can use all of MCP.&lt;/p&gt;

&lt;p&gt;Try it, break it, star it: &lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/apify" rel="noopener noreferrer"&gt;
        apify
      &lt;/a&gt; / &lt;a href="https://github.com/apify/mcpc" rel="noopener noreferrer"&gt;
        mcpc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      The most compatible MCP CLI client. Supports: tools, resources, prompts, completions, async tasks, skills, stdio and Streamable HTTP (MCP 2026-07-28 and 2025-11-25). Persistent sessions, OAuth 2.1 with DCR, CIMD, client credentials, and ID-JAG, OS keychain, --json for code mode, grep across servers, proxy for AI sandboxes, x402 &amp;amp; more.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;mcpc — a universal MCP CLI client&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/0a88327748a227ae8bf40048cee3a8233ea9ed2a6d688d39d0b92d7ff556c286/68747470733a2f2f61706966792e6769746875622e696f2f6d6370632f636c69656e742d6c6f676f2e7376673f763d33"&gt;&lt;img src="https://camo.githubusercontent.com/0a88327748a227ae8bf40048cee3a8233ea9ed2a6d688d39d0b92d7ff556c286/68747470733a2f2f61706966792e6769746875622e696f2f6d6370632f636c69656e742d6c6f676f2e7376673f763d33" alt="mcpc logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@apify/mcpc" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/2753d4659235a3bf7754e65d01939c21790adfcd4db4ba581c6f16b7cb79235e/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f4061706966792f6d6370632e737667" alt="npm version"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/@apify/mcpc" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/557f903ac4b9fd0a69a6c7cfeefabe0c0d51981b99a71d3d12afe95b9207e019/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f646d2f4061706966792f6d6370632e737667" alt="npm downloads"&gt;&lt;/a&gt;
&lt;a href="https://github.com/apify/mcpc/actions/workflows/ci.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/apify/mcpc/actions/workflows/ci.yml/badge.svg" alt="CI"&gt;&lt;/a&gt;
&lt;a href="https://github.com/apify/mcpc/blob/main/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f405a432f040b3a418d080841f2039f194b87a6469a6c4a1e6f1d269715cd043/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f6c2f4061706966792f6d6370632e737667" alt="License"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mcpc&lt;/code&gt; is a command-line client for the &lt;a href="https://modelcontextprotocol.io/" rel="nofollow noopener noreferrer"&gt;Model Context Protocol (MCP)&lt;/a&gt;
that maps every MCP operation to an intuitive shell command.&lt;/p&gt;
&lt;p&gt;Use it to manually inspect and debug MCP servers, to script repeatable MCP workflows in plain shell, or to
give AI agents the full MCP protocol through a single &lt;code&gt;Bash()&lt;/code&gt; tool call, so they can interact with any MCP
server and its latest capabilities using the most universal programming interface there is: the UNIX shell.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key features:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🔧 &lt;a href="https://github.com/apify/mcpc#mcp-support" rel="noopener noreferrer"&gt;&lt;strong&gt;Full MCP support&lt;/strong&gt;&lt;/a&gt; - Tools, prompts, resources, async tasks, skills, notifications, and logging over stdio and Streamable HTTP.&lt;/li&gt;
&lt;li&gt;🔄 &lt;strong&gt;Persistent sessions&lt;/strong&gt; - Keep connections to multiple servers alive in parallel, whether the server protocol is stateful or stateless.&lt;/li&gt;
&lt;li&gt;🗺️ &lt;strong&gt;Progressive tool discovery&lt;/strong&gt; - Find relevant MCP tools on the fly to save tokens and increase accuracy.&lt;/li&gt;
&lt;li&gt;🔌 &lt;strong&gt;Code mode&lt;/strong&gt; - JSON output composes with…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/apify/mcpc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>mcp</category>
      <category>ai</category>
      <category>cli</category>
      <category>aie</category>
    </item>
  </channel>
</rss>
