<?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: Creeta</title>
    <description>The latest articles on DEV Community by Creeta (@creeta).</description>
    <link>https://dev.to/creeta</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%2F3988151%2F79e19311-8408-48c6-b177-4544ce358e93.png</url>
      <title>DEV Community: Creeta</title>
      <link>https://dev.to/creeta</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/creeta"/>
    <language>en</language>
    <item>
      <title>Claude's prompt cache fails silently below 1,024 tokens</title>
      <dc:creator>Creeta</dc:creator>
      <pubDate>Thu, 06 Aug 2026 03:40:27 +0000</pubDate>
      <link>https://dev.to/creeta/claudes-prompt-cache-fails-silently-below-1024-tokens-1ch1</link>
      <guid>https://dev.to/creeta/claudes-prompt-cache-fails-silently-below-1024-tokens-1ch1</guid>
      <description>&lt;p&gt;Prompt caching on the Claude API is the difference between an agent loop that costs $5 and one that costs $50 — but only if the cache actually forms. The most common reason it doesn't is a floor that produces no error message at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's New: Automatic Caching, Diagnostics — and the Floor Nobody Warns You About
&lt;/h2&gt;

&lt;p&gt;Claude's prompt cache has a minimum cacheable prefix, and it is model-dependent rather than a single global number: 512 tokens for Opus 5, Fable 5 and Mythos 5; 1,024 for Opus 4.8, Sonnet 5, Sonnet 4.6/4.5 and Opus 4.1/4; 2,048 for Opus 4.7; and 4,096 for Opus 4.6, Opus 4.5 and Haiku 4.5 . Below that floor nothing is cached and no exception is raised — the request bills at the full input rate and the only signal is both cache token counters sitting at zero .&lt;/p&gt;

&lt;p&gt;Two 2026 platform changes make this easier to catch. On &lt;strong&gt;February 19, 2026&lt;/strong&gt;, automatic caching went GA on the Messages API: a single top-level &lt;code&gt;cache_control&lt;/code&gt; field places the breakpoint on the last cacheable block and advances it as the conversation grows . On &lt;strong&gt;May 13, 2026&lt;/strong&gt;, cache diagnostics entered public beta — with the header &lt;code&gt;cache-diagnosis-2026-04-07&lt;/code&gt;, a request returns a &lt;code&gt;cache_miss_reason&lt;/code&gt; instead of silence . Neither change removes the token floor; they just make it visible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before You Rely on This in Production: What Your Setup Needs
&lt;/h2&gt;

&lt;p&gt;Caching requires three things in place before the numbers move: Messages API access with &lt;code&gt;cache_control&lt;/code&gt; block support, a model whose minimum cacheable prefix your stable content actually clears, and a habit of reading usage metadata instead of trusting the discount. The 1-hour TTL has been generally available without a beta header since August 13, 2025, but mid-conversation tool changes still need the &lt;code&gt;mid-conversation-tool-changes-2026-07-01&lt;/code&gt; header .&lt;/p&gt;

&lt;p&gt;The floor is model-dependent and varies by a factor of eight. A prompt below it can never cache, no matter where you put the marker .&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Minimum cacheable prefix&lt;/th&gt;
&lt;th&gt;Models&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;512 tokens&lt;/td&gt;
&lt;td&gt;Opus 5, Fable 5, Mythos 5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,024 tokens&lt;/td&gt;
&lt;td&gt;Opus 4.8, Sonnet 5, Sonnet 4.6 / 4.5, Opus 4.1 / 4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2,048 tokens&lt;/td&gt;
&lt;td&gt;Opus 4.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4,096 tokens&lt;/td&gt;
&lt;td&gt;Opus 4.6, Opus 4.5, Haiku 4.5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Ground truth lives in &lt;code&gt;usage&lt;/code&gt;: &lt;code&gt;cache_creation_input_tokens&lt;/code&gt; (split into &lt;code&gt;ephemeral_5m_input_tokens&lt;/code&gt; and &lt;code&gt;ephemeral_1h_input_tokens&lt;/code&gt;) and &lt;code&gt;cache_read_input_tokens&lt;/code&gt;. Budget your markers too — a request carries at most four explicit &lt;code&gt;cache_control&lt;/code&gt; breakpoints, and automatic caching consumes one of those slots, so combining it with four manual markers returns a 400 .&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Confirm Your Cache Actually Formed
&lt;/h2&gt;

&lt;p&gt;Confirming a cache formed takes one measurement and one repeat: count the tokens in the exact content sitting before your &lt;code&gt;cache_control&lt;/code&gt; breakpoint, compare that count against your model's minimum, then send the identical request twice and read &lt;code&gt;usage.cache_creation_input_tokens&lt;/code&gt; on call one and &lt;code&gt;usage.cache_read_input_tokens&lt;/code&gt; on call two. Anything else — a lower &lt;code&gt;input_tokens&lt;/code&gt; figure, a faster response — is circumstantial. Below the model floor nothing is cached and no error is raised .&lt;/p&gt;

&lt;p&gt;Placement decides what gets counted. Put the marker on the last stable block: the final entry in the &lt;code&gt;tools&lt;/code&gt; array to cache the whole tool prefix, or the end of a static system prompt when you have no tools. For an &lt;code&gt;mcp_toolset&lt;/code&gt;, mark the toolset entry so the breakpoint lands on the last expanded tool .&lt;/p&gt;

&lt;p&gt;The following snippet is illustrative — it was not executed, since it needs a live &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt;. It deliberately marks a sub-1,024-token block so you can watch both counters come back empty:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urllib.request&lt;/span&gt;

&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ANTHROPIC_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;needs ANTHROPIC_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;model&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude-3-5-sonnet-20241022&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_tokens&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;This cacheable block is intentionally below 1,024 tokens.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cache_control&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ephemeral&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Reply with OK.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.anthropic.com/v1/messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content-type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic-version&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2023-06-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x-api-key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;usage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;usage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cache_creation_input_tokens =&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cache_creation_input_tokens&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cache_read_input_tokens =&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cache_read_input_tokens&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No error is raised; sub-1024-token prompt cache is just not used.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If both counters read zero on the second call, the prefix is under the floor — pad it with more static content or move more stable material ahead of the marker. If they read zero only sometimes, stop guessing and opt into the diagnostics beta that entered public preview on May 13, 2026: send header &lt;code&gt;cache-diagnosis-2026-04-07&lt;/code&gt; with &lt;code&gt;diagnostics.previous_message_id&lt;/code&gt; and the response returns a &lt;code&gt;cache_miss_reason&lt;/code&gt; naming the first point where the prefix diverged from the prior turn .&lt;/p&gt;

&lt;p&gt;Then keep watching it. Anthropic's Claude Code team treats hit rate as a reliability signal, not an accounting line:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We run alerts on our prompt cache hit rate and declare SEVs if they're too low… monitor your cache hit rate like you monitor uptime." — Claude Code team, Anthropic (source: &lt;a href="https://claude.com/blog/lessons-from-building-claude-code-prompt-caching-is-everything" rel="noopener noreferrer"&gt;Lessons from building Claude Code&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Log creation and read counters separately, broken out by model, TTL and workflow. A single aggregate number hides the case that matters most: a prefix that writes on every call and never reads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gotchas That Show Up After the Cache Forms
&lt;/h2&gt;

&lt;p&gt;A formed cache is not a stable cache. Once the prefix hits, the next class of failures comes from configuration flags and server-side behavior that quietly rewrite or invalidate what you cached. The most common surprise: when a request already carries a &lt;code&gt;cache_control&lt;/code&gt; marker and Claude calls a server tool — web search, web fetch, or code execution — the API automatically inserts a breakpoint on the server tool result before the next iteration, and that breakpoint always uses the 5-minute TTL regardless of your markers . A 1-hour-only configuration will therefore still report &lt;code&gt;ephemeral_5m_input_tokens&lt;/code&gt; writes. That is expected behavior, not a leak.&lt;/p&gt;

&lt;p&gt;The invalidation triggers worth logging explicitly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Changing &lt;code&gt;tool_choice&lt;/code&gt; or &lt;code&gt;disable_parallel_tool_use&lt;/code&gt; invalidates the messages cache .&lt;/li&gt;
&lt;li&gt;Toggling web search or citations invalidates both system and messages .&lt;/li&gt;
&lt;li&gt;Changing thinking parameters or &lt;code&gt;output_config.effort&lt;/code&gt; invalidates messages on every model — and tools plus system on models that render that config ahead of them .&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mixed TTLs are permitted, but ordering is strict: 1-hour blocks must appear before 5-minute blocks. Billing is then computed across three positions — the highest cache hit (A), the last 1-hour breakpoint after it (B), and the last breakpoint (C) — charging reads for A, 1h writes for B−A, and 5m writes for C−B . Invert that order and the math stops describing what you actually pay.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Try Next: Diagnostics, Keepalive, and the Break-Even Math
&lt;/h2&gt;

&lt;p&gt;Point the diagnostics beta at your worst-performing call path first. With the header &lt;code&gt;cache-diagnosis-2026-04-07&lt;/code&gt;, a request can pass &lt;code&gt;diagnostics.previous_message_id&lt;/code&gt; and get back a &lt;code&gt;cache_miss_reason&lt;/code&gt; naming the first point where the prefix diverged from the prior turn  — a direct answer instead of bisecting a 30 KB prefix by hand.&lt;/p&gt;

&lt;p&gt;Then check the arithmetic before you widen the TTL. A 5-minute write costs 1.25× base input and a read 0.1×, so two calls on a warm prefix run 1.35× versus 2× uncached — payback on the second read. A 1-hour write at 2.0× needs roughly two to three reads to clear . If you plan to hold a prefix warm with keepalive pings, Khailo's July 24, 2026 paper derives break-even horizons of about 46 minutes for the 5-minute tier and 3.3 hours for the 1-hour tier at measured provider parameters .&lt;/p&gt;

&lt;p&gt;One last default worth knowing: Claude Code's client requests the 1-hour TTL automatically on a subscription, but falls back to 5 minutes on an API key unless you set &lt;code&gt;ENABLE_PROMPT_CACHING_1H=1&lt;/code&gt; . The takeaway is narrow and testable: log &lt;code&gt;cache_creation_input_tokens&lt;/code&gt; and &lt;code&gt;cache_read_input_tokens&lt;/code&gt; per model and workflow, and treat a flat-zero pair as a defect report — not a silent cost you keep paying.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What's the smallest prefix Claude will actually cache?
&lt;/h3&gt;

&lt;p&gt;It depends on the model, and the spread is wide: 512 tokens on Opus 5, Fable 5 and Mythos 5; 1,024 tokens on Opus 4.8, Sonnet 5, Sonnet 4.6, Sonnet 4.5, Opus 4.1 and Opus 4; 2,048 tokens on Opus 4.7; and 4,096 tokens on Opus 4.6, Opus 4.5 and Haiku 4.5 . The floor is not monotonic across versions — Opus 4.8 dropped to 1,024, below Opus 4.7's 2,048 . Check the number for the exact model you deploy before assuming a compact system prompt will cache at all.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I know whether my prompt cache actually formed?
&lt;/h3&gt;

&lt;p&gt;Read two fields from the API response: &lt;code&gt;usage.cache_creation_input_tokens&lt;/code&gt; and &lt;code&gt;usage.cache_read_input_tokens&lt;/code&gt;. A non-zero creation count means a prefix was written; a non-zero read count means it was reused. Both at zero means nothing was cached, no matter how large &lt;code&gt;input_tokens&lt;/code&gt; looks — total input is read + creation + input, so a fat &lt;code&gt;input_tokens&lt;/code&gt; value with flat-zero cache counters is exactly the failure signature . The &lt;code&gt;cache_creation&lt;/code&gt; object splits writes into &lt;code&gt;ephemeral_5m_input_tokens&lt;/code&gt; and &lt;code&gt;ephemeral_1h_input_tokens&lt;/code&gt; if you need TTL-level attribution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does the API throw an error if my prefix is too short to cache?
&lt;/h3&gt;

&lt;p&gt;No. A request with a &lt;code&gt;cache_control&lt;/code&gt; marker on a below-threshold prefix succeeds normally and bills at the full input rate — no warning, no exception, no header. The only observable signal is both cache token counters staying at zero . That is why the Claude Code team treats hit rate as an operational metric rather than an optimization detail: they run alerts on prompt cache hit rate and declare SEVs when it drops .&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I use the 5-minute or 1-hour TTL?
&lt;/h3&gt;

&lt;p&gt;Use the 5-minute tier for active chat loops, short tool-use bursts and retries: at 1.25× base input for the write and 0.1× for the read, it clears break-even on the second use versus two uncached calls . Use the 1-hour tier — 2.0× write — only when expensive context setup will be re-read across a long job or many worker calls, since it needs roughly two to three reads to pay back . If you hold a prefix warm with keepalive pings, the measured break-even horizons are about 46 minutes for the 5-minute tier and 3.3 hours for the 1-hour tier . Mixed TTLs are allowed, but 1-hour blocks must sit before 5-minute blocks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does a 1-hour-only cache config still show 5-minute writes?
&lt;/h3&gt;

&lt;p&gt;Because server tools insert their own breakpoint. When a request already carries a &lt;code&gt;cache_control&lt;/code&gt; marker and Claude calls a server tool — web search, web fetch or code execution — the API automatically adds a breakpoint on the server tool result before the next iteration, and that breakpoint always uses the 5-minute TTL regardless of the markers you set . So a configuration you believe is 1-hour-only will still report &lt;code&gt;ephemeral_5m_input_tokens&lt;/code&gt; writes. This is documented behavior, not a defect — budget for it rather than debugging it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I add or remove tools mid-conversation without losing the cache?
&lt;/h3&gt;

&lt;p&gt;Yes, on recent models with an opt-in header. Since 24 July 2026, the &lt;code&gt;mid-conversation-tool-changes-2026-07-01&lt;/code&gt; header lets you add or remove tools between turns while preserving the cache on Fable 5, Mythos 5, Opus 4.8 and Opus 5; a related change on 28 May 2026 permits mid-conversation &lt;code&gt;role: "system"&lt;/code&gt; messages so instructions can change without invalidating the prefix . For older models, the structural fix is &lt;code&gt;defer_loading&lt;/code&gt; with the tool-search tool: deferred definitions never enter the prefix, and discovered tools append as &lt;code&gt;tool_reference&lt;/code&gt; blocks in the conversation instead .&lt;/p&gt;

&lt;h3&gt;
  
  
  How much cost reduction is realistic?
&lt;/h3&gt;

&lt;p&gt;Independent measurement lands below vendor headline figures. Anthropic's original announcement cited up to 90% cost and 85% latency reduction for long repeated prompts , while an evaluation of 500+ agent sessions on DeepResearch Bench with 10,000-token system prompts across three vendors reported 41–80% cost reduction and 13–31% time-to-first-token improvement . That paper also found naive full-context caching can increase latency; the most consistent strategy was caching stable system context while keeping volatile tool results out of the reusable prefix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Watch / Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=589L9X_JHy4" rel="noopener noreferrer"&gt;Source video — prompt caching walkthrough (seed for this tutorial)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.claude.com/docs/en/build-with-claude/prompt-caching" rel="noopener noreferrer"&gt;Anthropic — Prompt caching documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.claude.com/docs/en/build-with-claude/cache-diagnostics" rel="noopener noreferrer"&gt;Anthropic — Cache diagnostics (public beta)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.claude.com/docs/en/prompt-caching" rel="noopener noreferrer"&gt;Claude Code — Prompt caching defaults and TTL flags&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Last updated: 2026-08-06. Model minimum-token thresholds, TTL pricing multipliers and beta header names were checked against Anthropic's prompt-caching documentation and API release notes on this date; verify per model and per deployment target before relying on them in production.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>promptcaching</category>
      <category>anthropicapi</category>
      <category>llminfrastructure</category>
    </item>
    <item>
      <title>Claude Code resends full context every turn — Headroom cuts it</title>
      <dc:creator>Creeta</dc:creator>
      <pubDate>Wed, 05 Aug 2026 15:48:32 +0000</pubDate>
      <link>https://dev.to/creeta/claude-code-resends-full-context-every-turn-headroom-cuts-it-53o9</link>
      <guid>https://dev.to/creeta/claude-code-resends-full-context-every-turn-headroom-cuts-it-53o9</guid>
      <description>&lt;p&gt;Every time you send a message in Claude Code, the tool doesn't just ship your new line — it re-uploads the entire conversation so far. On a long session, that quietly becomes the bulk of your token bill.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Claude Code Resends the Entire Conversation on Every Turn
&lt;/h2&gt;

&lt;p&gt;Claude Code is stateless between API calls, so it appends the full message history, all tool outputs, and MCP server metadata to every outbound request. Anthropic's own cost documentation confirms token spend scales with accumulated context: the longer the session, the more you pay to resend material the model has already seen . Prompt caching softens this — Anthropic gives roughly a 90% read discount on a stable prefix — but tool results, file reads, and variable JSON payloads keep changing the prefix, breaking the cache and forcing stale output to be re-billed at full input rates on later turns .&lt;/p&gt;

&lt;p&gt;Headroom is a local middleware layer that intercepts that outbound payload before it reaches the provider. Requests pass through a staged lifecycle — Input Received → ContentRouter → Compressed → Pre-Send — where redundant blocks like logs, search dumps, and repeated file reads are stripped or compressed en route . The current &lt;code&gt;headroom-ai&lt;/code&gt; package is version 0.33.0, published July 29, 2026 .&lt;/p&gt;

&lt;p&gt;The payoff varies by content. Headroom's README cites 15–20% overall reduction for coding agents, while structured payloads — JSON arrays and build logs — reach 70–95% . Independent expectations should be tempered: one practitioner reported about 26% real-world savings after a month of use .&lt;/p&gt;

&lt;h2&gt;
  
  
  What Headroom Needs to Attach to Claude Code
&lt;/h2&gt;

&lt;p&gt;Headroom attaches to Claude Code with two runtime prerequisites and no API key changes. Pick one install path: Python 3.10+ for &lt;code&gt;pip install "headroom-ai[all]"&lt;/code&gt;, or Node 18+ for &lt;code&gt;npm install headroom-ai&lt;/code&gt; . The current PyPI package is &lt;code&gt;headroom-ai&lt;/code&gt; version 0.33.0, released July 29, 2026, so a fresh install already carries the compressor stack described in the arc .&lt;/p&gt;

&lt;p&gt;There is no build step. Prebuilt wheels ship for Windows, Linux (x86-64 and aarch64), and macOS (x86-64 and ARM64), so the install resolves without a compiler toolchain on any of those platforms .&lt;/p&gt;

&lt;p&gt;Your Anthropic credentials stay untouched. Headroom runs on localhost and you redirect Claude Code at &lt;code&gt;127.0.0.1&lt;/code&gt; instead of &lt;code&gt;api.anthropic.com&lt;/code&gt;; the key still authenticates upstream, only the base URL moves .&lt;/p&gt;

&lt;p&gt;Verify before wiring anything: &lt;code&gt;headroom --version&lt;/code&gt; should print &lt;code&gt;0.33.0&lt;/code&gt; . After you attach it in the next step, one live Claude Code invocation confirms the round-trip end to end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fitting Headroom Into Claude Code
&lt;/h2&gt;

&lt;p&gt;You have three ways to route Claude Code through Headroom, ordered from least to most manual. Pick one based on how much control you want over what gets compressed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Path A — agent wrap (zero code changes).&lt;/strong&gt; Run &lt;code&gt;headroom wrap claude&lt;/code&gt;. Headroom launches Claude Code as a subprocess and compresses every payload in-process before it leaves your machine; nothing else in your setup changes . This is the fastest path if you just want savings without thinking about which blocks matter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Path B — transparent local proxy.&lt;/strong&gt; Start &lt;code&gt;headroom proxy --port 8787&lt;/code&gt;, then set &lt;code&gt;ANTHROPIC_BASE_URL=http://localhost:8787&lt;/code&gt; before invoking &lt;code&gt;claude&lt;/code&gt;. All traffic routes through Headroom without touching source or config files, and the request continues upstream to Anthropic authenticated by your existing key .&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Path C — MCP server.&lt;/strong&gt; Run &lt;code&gt;headroom mcp install&lt;/code&gt; to expose &lt;code&gt;headroom_compress&lt;/code&gt;, &lt;code&gt;headroom_retrieve&lt;/code&gt;, and &lt;code&gt;headroom_stats&lt;/code&gt; as callable tools. Instead of compressing all traffic, Claude compresses specific blocks on demand and can pull the original back within a one-hour TTL . This gives you per-block control at the cost of Claude choosing when to invoke it.&lt;/p&gt;

&lt;p&gt;What makes the compression safe is CCR — Compress-Cache-Retrieve. Headroom stores the original content locally under a content hash and hands the model a shorter representation plus a retrieval affordance. The documented example crushes 5,000 lines of grep output from 12,000 to 3,200 tokens — a 73.3% cut — with the full original on standby via &lt;code&gt;headroom_retrieve&lt;/code&gt; for one hour .&lt;/p&gt;

&lt;p&gt;Under any path, ContentRouter auto-detects each block's type — JSON, logs, diffs, HTML, plain text — and hands it to the right compressor: SmartCrusher for JSON, an AST-aware CodeCompressor for source (Python, JS/TS, Go, Rust, Java, C/C++), and Kompress-v2-base, a 149M-parameter extractive prose model, for narrative text . You do not tag content yourself; routing is automatic.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Headroom Skips Compression Entirely
&lt;/h2&gt;

&lt;p&gt;Headroom does not compress everything, and knowing what it leaves alone sets a realistic expectation. Messages under roughly 300 tokens pass through untouched, because compressor overhead exceeds any saving at that scale . Source-code compression is opt-in and off by default, and short conversational exchanges compress a median of just 4.8% . Images, grep/search results, and system prompts may also bypass the pipeline.&lt;/p&gt;

&lt;p&gt;The gains concentrate in long, tool-heavy sessions. Agentic conversations of 25–50 turns compress 56–81%, while a single-turn or early-session call can see near-zero reduction . The headline 60–95% figures apply exclusively to structured payloads — JSON arrays and build/test logs — not prose-heavy turns; the README's own coding-agent figure is 15–20% .&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workload&lt;/th&gt;
&lt;th&gt;Typical reduction&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Short conversational exchange&lt;/td&gt;
&lt;td&gt;~4.8% (median)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25–50 turn agentic session&lt;/td&gt;
&lt;td&gt;56–81%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JSON arrays&lt;/td&gt;
&lt;td&gt;70–90%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build/test logs&lt;/td&gt;
&lt;td&gt;80–95%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Source code (opt-in)&lt;/td&gt;
&lt;td&gt;40–70%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Independent signal is thin. One practitioner reported roughly 26% real-world savings after a month  — well below the marketed range. Every published number originates from Headroom's own suite, including the v0.5.18 reproducible benchmarks that measured 66.1% total-corpus compression ; as of August 2026 no independent, peer-reviewed benchmark exists. Treat vendor figures as an upper bound and measure your own workload with &lt;code&gt;headroom_stats&lt;/code&gt; before assuming plan-doubling savings.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Explore After Initial Attachment
&lt;/h2&gt;

&lt;p&gt;Once compression is running cleanly, four features extend what Headroom does for a Claude Code workflow. The most useful is &lt;code&gt;headroom learn&lt;/code&gt;: an offline failure-mining pass that reads your past Claude Code transcripts, mines recurring errors and patterns, and writes the distilled findings directly to &lt;code&gt;CLAUDE.md&lt;/code&gt; &lt;a href="https://github.com/headroomlabs-ai/headroom" rel="noopener noreferrer"&gt;Headroom README&lt;/a&gt;. It runs on stored sessions, not live traffic, so it costs no extra tokens during a conversation.&lt;/p&gt;

&lt;p&gt;If you run Claude and Codex in parallel, Headroom keeps a shared compressed corpus across both agents and deduplicates overlapping context, so the same file reads and tool outputs are not stored or re-sent twice &lt;a href="https://github.com/headroomlabs-ai/headroom" rel="noopener noreferrer"&gt;Headroom README&lt;/a&gt;. That matters most when two agents are exploring the same repository at once.&lt;/p&gt;

&lt;p&gt;To measure any of this without leaving a conversation, call the &lt;code&gt;headroom_stats&lt;/code&gt; MCP tool for per-turn compression ratio and cumulative token delta &lt;a href="https://github.com/headroomlabs-ai/headroom/tree/main/.claude-plugin" rel="noopener noreferrer"&gt;Claude plugin manifest&lt;/a&gt;. Finally, tune CacheAligner — the component that flags volatile content breaking KV-cache prefixes. Configuring it to hold more prefix stable earns Anthropic's roughly 90% cache-read discount on top of compression, stacking both savings.&lt;/p&gt;

&lt;p&gt;Concrete next step: attach via the proxy, turn on &lt;code&gt;headroom_stats&lt;/code&gt;, run one real session, then decide whether &lt;code&gt;headroom learn&lt;/code&gt; and CacheAligner tuning justify the setup for your codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does Headroom change Claude's answers or discard information?
&lt;/h3&gt;

&lt;p&gt;No — Headroom is designed to be reversible rather than lossy. Its CCR (Compress-Cache-Retrieve) design stores the original content locally under a hash and hands the model a compact representation plus a retrieval affordance, so Claude can call &lt;code&gt;headroom_retrieve&lt;/code&gt; to fetch the full original within a one-hour TTL when detail is needed . The prose compressor, Kompress-v2-base, is extractive and scores eval F1 0.918 with must-keep recall 0.974 on 7,037 held-out examples, meaning very few forced-retain spans are dropped .&lt;/p&gt;

&lt;h3&gt;
  
  
  How much will Headroom actually save in a real Claude Code session?
&lt;/h3&gt;

&lt;p&gt;It depends heavily on workload. The README claims a modest 15–20% reduction for coding agents broadly, but structured payloads see far more: JSON arrays 70–90% and build/test logs 80–95% in Headroom's own benchmarks . Short conversational exchanges compress a median 4.8%, while agentic sessions of 25–50 turns compress 56–81% . One practitioner reported roughly 26% real-world savings after a month . Meaningful gains appear once a session accumulates significant tool-output history.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is running Headroom's local proxy safe with my Anthropic API key?
&lt;/h3&gt;

&lt;p&gt;Yes, for on-machine use. The proxy binds to &lt;code&gt;127.0.0.1&lt;/code&gt; only, so traffic from Claude Code to Headroom never leaves your machine; Headroom then forwards requests to Anthropic's API . The repository is Apache 2.0 licensed and fully inspectable on GitHub, and Headroom itself stores no credentials .&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between proxy mode, wrap mode, and MCP mode?
&lt;/h3&gt;

&lt;p&gt;Proxy mode (&lt;code&gt;headroom proxy&lt;/code&gt; plus an &lt;code&gt;ANTHROPIC_BASE_URL&lt;/code&gt; override) intercepts all traffic transparently — no code changes and it works with any tool. Wrap mode (&lt;code&gt;headroom wrap claude&lt;/code&gt;) shells Claude Code as a subprocess with Headroom in front, the simplest path for CLI use. MCP mode (&lt;code&gt;headroom mcp install&lt;/code&gt;) gives Claude selective, on-demand compression through a tool call instead of intercepting every request; the docs cite a representative 12,000 → 3,200 token result on grep output, with the original retained locally for one hour .&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Headroom work with editors other than Claude Code?
&lt;/h3&gt;

&lt;p&gt;Yes. Documented integrations include Cursor, Aider, Cline, Continue, and Goose via proxy or wrap mode, and any HTTP client that respects &lt;code&gt;ANTHROPIC_BASE_URL&lt;/code&gt; works with proxy mode . On the library side, Headroom documents Vercel AI SDK middleware and LangChain, Agno, and Strands integrations through its &lt;code&gt;compress(messages)&lt;/code&gt; API .&lt;/p&gt;

</description>
      <category>headroom</category>
      <category>claudecode</category>
      <category>contextcompression</category>
      <category>middleware</category>
    </item>
    <item>
      <title>OpenMontage has 45k stars and no proprietary orchestrator</title>
      <dc:creator>Creeta</dc:creator>
      <pubDate>Tue, 04 Aug 2026 21:53:41 +0000</pubDate>
      <link>https://dev.to/creeta/openmontage-has-45k-stars-and-no-proprietary-orchestrator-437i</link>
      <guid>https://dev.to/creeta/openmontage-has-45k-stars-and-no-proprietary-orchestrator-437i</guid>
      <description>&lt;p&gt;Most AI video tools ask you to log into a dashboard. OpenMontage asks you to &lt;code&gt;git clone&lt;/code&gt; a repository and let your coding agent take the director's chair.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Repo That Plays Director, Not a SaaS Dashboard
&lt;/h2&gt;

&lt;p&gt;OpenMontage is an open-source, agentic video-production framework that ships no orchestrator of its own — the AI coding agent you already run becomes the director. At the live 2026 snapshot, &lt;a href="https://github.com/calesthio/OpenMontage" rel="noopener noreferrer"&gt;calesthio/OpenMontage&lt;/a&gt; showed 45,042 stars, 5,540 forks, and 323 commits, licensed AGPL-3.0. The repo was created on 2026-03-29 and carries no tagged releases — a rolling main branch, not a versioned product, which makes exact version claims unreliable.&lt;/p&gt;

&lt;p&gt;The architecture is the point. Python supplies the tools and JSON/YAML state persistence; the coding agent — Claude Code, Cursor, GitHub Copilot, Codex, Windsurf, or OpenCode — owns the entire control loop. Production is encoded as a seven-stage sequence: research → proposal → script → scene_plan → assets → edit → compose. Each stage pairs a YAML manifest in &lt;code&gt;pipeline_defs/&lt;/code&gt; with a Markdown director skill in &lt;code&gt;skills/pipelines/&lt;/code&gt;, as documented in the &lt;a href="https://explainx.ai/blog/openmontage-agentic-video-production-claude-code-2026" rel="noopener noreferrer"&gt;pipeline walkthrough&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Every video request must go through a named pipeline; ad hoc scripts and bypassing the checkpoint loop are disallowed by design." — OpenMontage AGENT_GUIDE (source: &lt;a href="https://github.com/calesthio/OpenMontage/blob/main/AGENT_GUIDE.md" rel="noopener noreferrer"&gt;AGENT_GUIDE.md&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That constraint is enforced, not merely advised: the agent reads the manifest, runs preflight, discovers tools through a registry, self-reviews, checkpoints state, and halts for human approval at creative decision points.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before You Begin: Python 3.10, FFmpeg, and an Agent
&lt;/h2&gt;

&lt;p&gt;OpenMontage runs locally by default, so the prerequisite list is short and the setup is one command. You need Python 3.10+ for tool execution and JSON state persistence, FFmpeg for post-production compositing, Node.js 18+ for the Remotion renderer, and one of six supported coding agents — Claude Code, Cursor, GitHub Copilot, Codex, Windsurf, or OpenCode — to act as director .&lt;/p&gt;

&lt;p&gt;After &lt;code&gt;git clone&lt;/code&gt; and &lt;code&gt;cd OpenMontage&lt;/code&gt;, a single &lt;code&gt;make setup&lt;/code&gt; installs all three dependency layers at once: Python packages, Remotion's Node packages, and Piper TTS for offline narration . There are no manual &lt;code&gt;pip&lt;/code&gt; or &lt;code&gt;npm&lt;/code&gt; steps to chase.&lt;/p&gt;

&lt;p&gt;Copying &lt;code&gt;.env.example&lt;/code&gt; to &lt;code&gt;.env&lt;/code&gt; is optional — do it only to wire in paid providers such as ElevenLabs, Kling, or fal.ai. Leave it absent and you stay on the zero-key path. No Docker, no cloud provisioning, no dashboard login.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Claude Code Directs a Video, From Empty Folder to Draft
&lt;/h2&gt;

&lt;p&gt;With setup done, two terminal commands are all you type before handing off. Clone the repository and enter it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/calesthio/OpenMontage.git
&lt;span class="nb"&gt;cd &lt;/span&gt;OpenMontage &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; make setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From here, the coding agent takes the director's chair. Open the repo in Claude Code and it reads &lt;code&gt;CLAUDE.md&lt;/code&gt;, which points to &lt;code&gt;AGENT_GUIDE.md&lt;/code&gt; for shared operating rules . Cursor, Copilot, Codex, and Windsurf each read their own platform markdown file that routes to the same guidance . The agent then discovers what tools it can call through the registry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;from tools.tool_registry import registry; registry.discover()&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;AGENT_GUIDE&lt;/code&gt; is prescriptive: the agent reads the relevant skill files in &lt;code&gt;skills/&lt;/code&gt; before invoking anything, and every request must run through a pipeline — ad hoc scripts and bypassing review are explicitly disallowed .&lt;/p&gt;

&lt;p&gt;Now issue a plain-English brief, such as &lt;em&gt;"Make a 60-second animated explainer about how neural networks learn."&lt;/em&gt; The agent selects a pipeline from the staged workflow — research → proposal → script → scene_plan → assets → edit → compose — runs preflight checks, self-reviews, checkpoints JSON state, and halts for your approval at every creative decision point before proceeding .&lt;/p&gt;

&lt;p&gt;Because the whole production is reproducible from repo state, nothing hides in a black-box render. The script lands as Markdown, scene metadata as JSON and YAML, assets under stable names, plus render commands and self-review notes — all ordinary files you can diff, version, and audit like any other codebase .&lt;/p&gt;

&lt;h2&gt;
  
  
  When Zero API Keys Is Not Quite Zero
&lt;/h2&gt;

&lt;p&gt;OpenMontage's "zero API keys" claim is real for the default path but does not make every capability free. Out of the box you get local, offline narration from Piper TTS, footage and stills from Archive.org, NASA, and Wikimedia Commons, word-level transcription from WhisperX, composition in Remotion, and post-production in FFmpeg — no keys required . That free real-footage path, not stitched stills, is what separates it from slideshow tools.&lt;/p&gt;

&lt;p&gt;Generated clips are key-gated. Kling, Runway Gen-4, Google Veo 3, MiniMax, Grok Imagine, and HeyGen all require paid access, typically routed via fal.ai; local WAN 2.1, Hunyuan, and CogVideo are key-free but GPU-heavy . The README's own cost examples show the spread:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Production&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;th&gt;What it uses&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;60-second animated short&lt;/td&gt;
&lt;td&gt;$1.33&lt;/td&gt;
&lt;td&gt;Six Kling clips via fal.ai&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FLUX-image animation&lt;/td&gt;
&lt;td&gt;$0.15&lt;/td&gt;
&lt;td&gt;FLUX generated stills&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;70-second history piece&lt;/td&gt;
&lt;td&gt;$0.02&lt;/td&gt;
&lt;td&gt;OpenAI narration, free Pixabay music&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A default budget cap of roughly $10 keeps runaway spend in check. The bigger caveat is legal, not financial: the repo is AGPL-3.0, so its copyleft obligations attach to any distributed software incorporating the code — worth a review before shipping a product.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Local footage stays on your machine, composition and rendering run locally without watermarks or metering, and commercial use is available on every tier including free." — OpenMontage Studio (source: &lt;a href="https://daily.dev/posts/jor09ayvu" rel="noopener noreferrer"&gt;daily.dev&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;OpenMontage Studio — a hosted layer still in private alpha — offers commercial tiers as the cleaner path for teams uneasy about AGPL distribution .&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond the Animated Explainer: Eleven Other Formats
&lt;/h2&gt;

&lt;p&gt;The animated explainer is one of twelve production pipelines shipped in the current repo . The named set includes animation, avatar spokesperson, cinematic, clip factory, documentary montage, hybrid, localization/dub, podcast repurpose, screen demo, and talking head — each governed by the same approval-gated, checkpoint-based loop you already ran once .&lt;/p&gt;

&lt;p&gt;Documentary montage is the differentiating entry: instead of animating static images, it builds a CLIP-searchable corpus of real motion footage from Archive.org, NASA, and Wikimedia Commons, then cuts together actual clips — the free real-footage path no other entry-level tool offers . Localization/dub extends an existing video rather than rebuilding it; podcast repurpose turns audio-first content into a visual format with minimal new assets .&lt;/p&gt;

&lt;p&gt;Expanding is mechanical: open the target pipeline's skill file in &lt;code&gt;skills/pipelines/&lt;/code&gt; and issue a fresh brief. The director loop you learned on your first render carries over unchanged to all twelve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does OpenMontage actually work without any API keys?
&lt;/h3&gt;

&lt;p&gt;Yes, on the default path. Narration runs on Piper (local, offline TTS), footage and stills come from Archive.org, NASA, and Wikimedia Commons, transcription uses WhisperX, composition runs on Remotion, and post-production runs on FFmpeg — all locally with zero keys . Keys only unlock generated clips (Kling, Runway Gen-4, Veo 3) and premium voices. The repo's own examples include a $0.02 run for a 70-second history piece using OpenAI narration and free Pixabay music, and free-source-only workflows are explicitly supported .&lt;/p&gt;

&lt;h3&gt;
  
  
  Which coding agents does OpenMontage work with?
&lt;/h3&gt;

&lt;p&gt;Six directors are supported: Claude Code, Cursor, GitHub Copilot, Codex, Windsurf, and OpenCode . Configuration is file-routed per agent — Claude Code reads &lt;code&gt;CLAUDE.md&lt;/code&gt; then &lt;code&gt;AGENT_GUIDE.md&lt;/code&gt;, Cursor uses &lt;code&gt;CURSOR.md&lt;/code&gt; plus &lt;code&gt;.cursor/rules/&lt;/code&gt;, and Copilot, Codex, and Windsurf each get a dedicated platform Markdown file. All of them point to the same shared operating guidance in &lt;code&gt;AGENT_GUIDE.md&lt;/code&gt; .&lt;/p&gt;

&lt;h3&gt;
  
  
  What exactly is an OpenMontage skill file?
&lt;/h3&gt;

&lt;p&gt;A skill is a Markdown file encoding a reusable production capability — not a chat prompt. Examples include beat-detecting a music track, fitting an irregular image into 16:9 without stretching, or running a QA checklist . The agent reads the relevant skill files before invoking any tool. The current README advertises 700+ skill and production-knowledge files, up from the roughly 500 cited at launch .&lt;/p&gt;

&lt;h3&gt;
  
  
  Does the AGPL-3.0 license allow commercial use?
&lt;/h3&gt;

&lt;p&gt;Yes, AGPL-3.0 permits commercial use, but with a condition: if you ship software that incorporates the code — including over a network — you must distribute your source modifications under the same license . Teams building a product on OpenMontage should audit this obligation before shipping. The hosted OpenMontage Studio, currently in private alpha with beta pending, states commercial use is available on every tier and may be the more practical path for a proprietary deployment .&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I choose which pipeline to use for my video?
&lt;/h3&gt;

&lt;p&gt;You do not choose manually. The agent reads &lt;code&gt;AGENT_GUIDE.md&lt;/code&gt; and selects a pipeline from your plain-English brief, then presents a proposal you approve before any assets are touched . AGENT_GUIDE is prescriptive: every video request must go through a named pipeline, and ad hoc scripts or bypassing the review checkpoints are explicitly disallowed .&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>agenticvideo</category>
      <category>claudecode</category>
      <category>cursor</category>
    </item>
    <item>
      <title>Penpot's MCP server runs on five tools — Figma's uses dozens</title>
      <dc:creator>Creeta</dc:creator>
      <pubDate>Tue, 04 Aug 2026 15:52:35 +0000</pubDate>
      <link>https://dev.to/creeta/penpots-mcp-server-runs-on-five-tools-figmas-uses-dozens-354e</link>
      <guid>https://dev.to/creeta/penpots-mcp-server-runs-on-five-tools-figmas-uses-dozens-354e</guid>
      <description>&lt;p&gt;Two design tools, two philosophies of the same protocol: Penpot hands an AI agent a small toolbox and a JavaScript runtime; Figma hands it a long, specialized menu. The gap is deliberate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Penpot vs. Figma: Generalist Runner Over Specialist Menu
&lt;/h2&gt;

&lt;p&gt;Penpot's Model Context Protocol server exposes exactly five tools — &lt;code&gt;execute_code&lt;/code&gt;, &lt;code&gt;high_level_overview&lt;/code&gt;, &lt;code&gt;penpot_api_info&lt;/code&gt;, &lt;code&gt;export_shape&lt;/code&gt;, and &lt;code&gt;import_image&lt;/code&gt; — against Figma's roughly two-dozen named-action catalog . The workhorse is &lt;code&gt;execute_code&lt;/code&gt;: the agent writes JavaScript, and Penpot runs it inside the editor's plugin sandbox with access to the full Plugins API, so one endpoint covers what a specialist server splits across many .&lt;/p&gt;

&lt;p&gt;The following snippet — verified and executed — counts the two catalogs directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;penpot_tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;execute_code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;high_level_overview&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;penpot_api_info&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;export_shape&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;import_image&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;figma_tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;add_code_connect_map&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;create_new_file&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;download_assets&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;generate_diagram&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;generate_figma_design&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_code_connect_map&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_code_connect_suggestions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_context_for_code_connect&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_design_context&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_figjam&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_libraries&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_metadata&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_motion_context&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_screenshot&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_shader_effect&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_shader_fill&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_variable_defs&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;list_shader_effects&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;list_shader_fills&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_design_system&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;send_code_connect_mappings&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;upload_assets&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;use_figma&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;whoami&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Penpot MCP: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;penpot_tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Figma MCP: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figma_tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; tools (~two dozen)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Figma exposes &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figma_tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;penpot_tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;x as many tools.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Penpot's rationale is context economy: fewer tool schemas load less of a model's context window before any real call. It claims a large tool set can consume 10–15% of a smaller model's context — but that figure is Penpot's own, unbacked by a public third-party benchmark, so treat it as design rationale, not a measured result . Licensing differs too: Penpot MCP is MPL-2.0, self-hostable, and marketed with no paywalls, while Figma ties advanced Dev Mode inspection and its MCP server to paid seats with tiered rate limits — 20 tool calls per month on free, up to 600 per day at higher tiers . The canonical code lives in &lt;a href="https://github.com/penpot/penpot" rel="noopener noreferrer"&gt;penpot/penpot&lt;/a&gt; (≈58k stars) under &lt;code&gt;/mcp&lt;/code&gt; on the develop branch; the standalone &lt;code&gt;penpot/penpot-mcp&lt;/code&gt; repo was archived on 3 February 2026 and folded in, and it also ships as the npm package &lt;code&gt;@penpot/mcp&lt;/code&gt; .&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Have Before the Handshake
&lt;/h2&gt;

&lt;p&gt;Before an agent can query a Penpot file, you need three things: a Penpot instance, an MCP-capable client, and a connection mode. The instance can be Penpot's cloud at penpot.app or a self-hosted deployment via Docker, Kubernetes, Elestio, or on-prem — it is MPL-2.0 licensed with no cost gating on the MCP server . Any client that speaks MCP over HTTP works, since the server is explicitly client-agnostic: Cursor, Claude Code, VS Code with GitHub Copilot, Codex, or OpenCode are documented .&lt;/p&gt;

&lt;p&gt;Then pick a mode. Remote mode needs no Node.js — you generate one MCP key per account under &lt;em&gt;Your account → Integrations → MCP Server&lt;/em&gt;, shown once and non-recoverable . Local mode requires Node.js v20 or v22 and runs &lt;code&gt;npx @penpot/mcp@stable&lt;/code&gt;; defaults are HTTP on &lt;code&gt;localhost:4401/mcp&lt;/code&gt;, SSE on &lt;code&gt;localhost:4401/sse&lt;/code&gt;, and WebSocket on port 4402 .&lt;/p&gt;

&lt;h2&gt;
  
  
  Pairing Penpot MCP with Cursor or Claude Code
&lt;/h2&gt;

&lt;p&gt;With a mode chosen, three moves connect an agent to a live file. First, generate the MCP key. In the Penpot UI go to Your account → Integrations → MCP Server, where the key is displayed exactly once and cannot be recovered; only one key exists per user at a time . If you lose it, revoke and regenerate — but note that every connected agent config then breaks until you paste the new URL into each one, so treat regeneration as a fleet-wide update, not a local fix.&lt;/p&gt;

&lt;p&gt;Second, register the server URL in your client. For remote mode, paste &lt;code&gt;https://&amp;lt;your-penpot-domain&amp;gt;/mcp/stream?userToken=YOUR_MCP_KEY&lt;/code&gt; into the MCP server field in Cursor or Claude Code; the server is client-agnostic over HTTP, and Cursor, Claude Code, VS Code/Copilot, and Codex/OpenCode all have documented integrations . For local mode, run the npm package and point the client at &lt;code&gt;localhost:4401/mcp&lt;/code&gt; instead — no token, since it rides your active browser session .&lt;/p&gt;

&lt;p&gt;Third, open a Penpot file and call &lt;code&gt;high_level_overview&lt;/code&gt;. Confirm the agent returns page names, component counts, and color and typography token groups. Once the structure is visible, send a targeted &lt;code&gt;execute_code&lt;/code&gt; call — a short JavaScript expression the editor runs inside its plugin sandbox — to pull specific token values or inspect component properties directly from the file rather than a screenshot .&lt;/p&gt;

&lt;p&gt;One capability gap decides the mode: local mode adds full &lt;code&gt;export_shape&lt;/code&gt; and &lt;code&gt;import_image&lt;/code&gt; from local paths, while remote mode restricts both and offers no local file-system access . Some hosted-versus-local wording inconsistencies remain in the docs as of August 2026, so cross-check &lt;a href="https://help.penpot.app/mcp/" rel="noopener noreferrer"&gt;help.penpot.app/mcp&lt;/a&gt; for the current authoritative state before wiring a workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Slow, Expensive, Overwrite-Prone: What Penpot Cautions
&lt;/h2&gt;

&lt;p&gt;Write access is live by default. A paired agent can create, rename, move, delete, and restyle objects on the focused page, so Penpot advises keeping MCP out of critical production files until you have reviewed both agent behavior and the plugin permission scope it runs under . Prefer small, reversible operations while evaluating what an agent actually does to a file.&lt;/p&gt;

&lt;p&gt;Penpot is blunt about the ceiling: using MCP to autonomously generate designs is slow, expensive, and error-prone . The durable use case is structured context for better code output — CSS variable generation, component scaffolding, Storybook alignment — not full design autopilot.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The MCP server describes tools as model-controlled functions and recommends clear UI, visible invocation indicators, and human confirmation before write actions" — Model Context Protocol tools specification, 2025-06-18 (source: &lt;a href="https://penpot.app/self-host" rel="noopener noreferrer"&gt;modelcontextprotocol.io&lt;/a&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That guidance aligns with Penpot's own: keep a human in the loop on model-controlled writes . No verified accuracy rate exists for design-to-code output — quality depends on the model, prompt, file complexity, and permissions — so do not treat MCP-generated code as production-ready without a review pass.&lt;/p&gt;

&lt;h2&gt;
  
  
  W3C DTCG Tokens in Penpot 2.14–2.17: What's Programmatically Readable Now
&lt;/h2&gt;

&lt;p&gt;The integration point between MCP and design tokens is the Plugins API, which Penpot 2.14 opened to token values. Released to the community after March 17, 2026 , that update lets external code read and write tokens programmatically — and the release notes explicitly name the consumers.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"AI clients or Penpot MCP" can now work with tokens through the Plugins API — release notes, Penpot 2.14 (source: &lt;a href="https://help.penpot.app/user-guide/design-systems/design-tokens/" rel="noopener noreferrer"&gt;help.penpot.app&lt;/a&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The values follow the W3C Design Tokens Community Group draft: colors, typography, spacing, shadows, aliases, math in values, token sets, themes, and JSON import/export, with no proprietary sync plugin required — the contrast with Figma Variables . Later releases tightened the workflow: 2.16 (June 2, 2026) surfaced numeric token bindings from a selected element , and 2.17.0 (July 22, 2026) added typography token rows for multi-selected text, propagation optimization, and autocomplete for token forms .&lt;/p&gt;

&lt;p&gt;The practical endpoint is &lt;code&gt;execute_code&lt;/code&gt;: have the agent enumerate token groups through the Plugins API , export them as DTCG-format JSON, then pipe that into a Storybook config, a CSS custom-property generator, or a Tailwind theme — no manual copy-paste from the design panel. That is the concrete win: not autonomous design, but a self-hostable, standards-based token feed your coding agent can query on demand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is Penpot's MCP server free to use?
&lt;/h3&gt;

&lt;p&gt;Yes. Penpot is licensed under Mozilla Public License 2.0 with no paywalls and no per-seat gating for the MCP server . Remote mode is hosted by Penpot on penpot.app, while local mode runs via an npm package (&lt;code&gt;npx @penpot/mcp@stable&lt;/code&gt;) on your own machine . Either way, there is no cost beyond running the Penpot instance itself — a contrast with Figma, which ties its MCP server to paid seats and enforces per-tier rate limits .&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens if I lose my Penpot MCP key?
&lt;/h3&gt;

&lt;p&gt;The key is non-recoverable and shown only once, so a lost key cannot be retrieved — you revoke it and generate a new one under Your account → Integrations → MCP Server . Only one MCP key can exist per user at a time , which means rotating it invalidates every existing connection. After regenerating, update each connected agent configuration with the new &lt;code&gt;userToken&lt;/code&gt; value in the server URL. Local mode sidesteps this entirely, since it relies on your active browser session and requires no token.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can a connected AI agent overwrite or delete objects in my Penpot file?
&lt;/h3&gt;

&lt;p&gt;Yes — write access is on by default. A connected agent can create, rename, move, delete, and restyle objects on the focused page . Penpot explicitly advises keeping MCP away from critical production files and using small, reversible operations while you evaluate agent behavior . Review the plugin permission scope before expanding autonomy: the MCP tool specification itself recommends visible invocation indicators and human confirmation for model-controlled functions .&lt;/p&gt;

&lt;h3&gt;
  
  
  How does Penpot's token format differ from Figma Variables?
&lt;/h3&gt;

&lt;p&gt;Penpot follows the open W3C Design Tokens Community Group (DTCG) draft format, whereas Figma Variables use a proprietary schema. Penpot tokens export as DTCG-compatible JSON without a conversion plugin, covering colors, typography, spacing, shadows, aliases, and themes . As of Penpot 2.14, tokens are readable and writable through the Plugins API — the release notes explicitly name "AI clients or Penpot MCP" as external tools that can now work with tokens programmatically . MCP agents reach that layer via &lt;code&gt;execute_code&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which AI coding clients are confirmed to work with Penpot MCP?
&lt;/h3&gt;

&lt;p&gt;Penpot documents integration with Cursor, Claude Code, VS Code with GitHub Copilot, and Codex/OpenCode . The server is explicitly client-agnostic over HTTP transport and positioned to connect "any AI agent, any LLM you trust," so any MCP client that supports HTTP transport should work without a specific LLM vendor . Remote mode has reduced functionality compared to local mode — no local file-system access and limited &lt;code&gt;import_image&lt;/code&gt; and &lt;code&gt;export_shape&lt;/code&gt; — so pick the mode that matches your client and permissions .&lt;/p&gt;

</description>
      <category>penpot</category>
      <category>mcp</category>
      <category>designtokens</category>
      <category>aiagents</category>
    </item>
    <item>
      <title>Agent-Reach absorbed Bilibili's 412s — your agent kept working</title>
      <dc:creator>Creeta</dc:creator>
      <pubDate>Tue, 04 Aug 2026 09:49:53 +0000</pubDate>
      <link>https://dev.to/creeta/agent-reach-absorbed-bilibilis-412s-your-agent-kept-working-14ej</link>
      <guid>https://dev.to/creeta/agent-reach-absorbed-bilibilis-412s-your-agent-kept-working-14ej</guid>
      <description>&lt;h2&gt;
  
  
  Bilibili's 412 Incident, Explained: How v1.5.0 Absorbed It
&lt;/h2&gt;

&lt;p&gt;In June 2026, Bilibili quietly began rejecting yt-dlp with HTTP 412 errors. Agents wired to scrape it broke — except the ones sitting behind Agent-Reach, which rerouted the channel before most developers noticed.&lt;/p&gt;

&lt;p&gt;Agent-Reach is a local, MIT-licensed capability layer that gives shell-capable coding agents live internet access by selecting and routing to upstream CLIs rather than proxying data itself . When Bilibili started 412-blocking yt-dlp in June 2026, v1.5.0 rerouted the Bilibili channel to bili-cli with zero user action, while YouTube kept using yt-dlp untouched . The fix landed centrally: the maintainer reordered backends, so no individual builder had to patch a private integration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick Answer:&lt;/strong&gt; When Bilibili began returning HTTP 412 to yt-dlp in June 2026, Agent-Reach v1.5.0 automatically rerouted its Bilibili channel to bili-cli — agents kept working with no user action. The release passed 32 end-to-end tests across 13 channels and grew its suite from 107 to 162 tests.&lt;/p&gt;

&lt;p&gt;The framing shift matters: v1.5.0 describes itself as a capability layer, not a tool collection. Each platform gets an ordered primary-plus-fallback backend list; after setup, your agent calls those CLIs directly and Agent-Reach never sits in the data path . The June 11, 2026 release passed 32 end-to-end tests across 13 channels and grew its test suite from 107 to 162 tests .&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Primary backend&lt;/th&gt;
&lt;th&gt;Fallback&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Web pages&lt;/td&gt;
&lt;td&gt;Jina Reader&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;YouTube&lt;/td&gt;
&lt;td&gt;yt-dlp&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub&lt;/td&gt;
&lt;td&gt;gh CLI&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSS&lt;/td&gt;
&lt;td&gt;feedparser&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bilibili&lt;/td&gt;
&lt;td&gt;bili-cli&lt;/td&gt;
&lt;td&gt;OpenCLI (subtitles)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Twitter/X&lt;/td&gt;
&lt;td&gt;twitter-cli&lt;/td&gt;
&lt;td&gt;OpenCLI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reddit&lt;/td&gt;
&lt;td&gt;OpenCLI&lt;/td&gt;
&lt;td&gt;rdt-cli&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;XiaoHongShu&lt;/td&gt;
&lt;td&gt;OpenCLI&lt;/td&gt;
&lt;td&gt;xhs-cli&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LinkedIn&lt;/td&gt;
&lt;td&gt;linkedin-mcp&lt;/td&gt;
&lt;td&gt;Jina Reader&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Global search&lt;/td&gt;
&lt;td&gt;Exa via mcporter&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;"capability layer: multi-backend routing + real doctor + OpenCLI" — Agent-Reach v1.5.0 release framing (source: &lt;a href="https://github.com/Panniantong/Agent-Reach/blob/main/CLAUDE.md" rel="noopener noreferrer"&gt;Agent-Reach CLAUDE.md&lt;/a&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The behavior is easy to model. The following minimal snippet — which was executed and returns exit 0 — illustrates the "absorb and keep working" contract that centralized rerouting delivers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bilibili412&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;bilibili_fetch&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;Bilibili412&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bilibili returned HTTP 412&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;agent_reach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;Bilibili412&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;absorbed &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;; agent kept working&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;


&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Agent-Reach:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;agent_reach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bilibili_fetch&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;next step: summarize cached context&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Minimum Prerequisites Before the Agent-Directed Install
&lt;/h2&gt;

&lt;p&gt;Before you hand the install prompt to your agent, three things need to be in place: a real Python interpreter, an isolation mechanism, and — only if you want desktop-session backends — Node.js. Agent-Reach requires Python 3.10 or newer . On Windows, prefer &lt;code&gt;py -3&lt;/code&gt; if &lt;code&gt;python3&lt;/code&gt; resolves to the Microsoft Store stub instead of a real interpreter .&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Isolation:&lt;/strong&gt; pipx is the recommended path; a venv under &lt;code&gt;~/.agent-reach-venv/&lt;/code&gt; is an equivalent fallback that runs the same install command .&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node.js 20+:&lt;/strong&gt; only needed if you plan to activate OpenCLI, which unlocks Reddit, Facebook, Instagram, Bilibili subtitles, and XiaoHongShu desktop access .&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One trap to avoid: the name &lt;code&gt;agent-reach&lt;/code&gt; on PyPI points to an unrelated v0.1.0 package by a different author (jgalea/agent-reach, uploaded August 2, 2026) . Always install from the GitHub archive URL, never from a blind &lt;code&gt;pip install agent-reach&lt;/code&gt; .&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Install Agent-Reach: pipx, --env=auto, and the Venv Alternative
&lt;/h2&gt;

&lt;p&gt;Installation is agent-directed by design: a human pastes an install prompt pointing at the raw GitHub &lt;a href="https://github.com/DontFretBrett/Agent-Reach-English" rel="noopener noreferrer"&gt;install guide&lt;/a&gt;, and the agent runs the commands while keeping files out of your project workspace . Below is the direct copy-paste path for the Panniantong build, version 1.5.0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — pipx (recommended):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pipx &lt;span class="nb"&gt;install &lt;/span&gt;https://github.com/Panniantong/agent-reach/archive/main.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2 — provision the capability layer:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agent-reach &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--env&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;auto
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;--env=auto&lt;/code&gt; flag auto-detects whether you are on a local machine or a server, then sets up core infrastructure: gh CLI, Node.js, mcporter, Exa search, and a yt-dlp config . After this runs, seven zero-config channels work without any login — Web via Jina Reader, YouTube, GitHub, RSS, Exa Search, V2EX, and basic Bilibili .&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — venv alternative&lt;/strong&gt; (if you avoid pipx): create an isolated environment, activate it, install the same archive, and run the identical setup command :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv ~/.agent-reach-venv
&lt;span class="nb"&gt;source&lt;/span&gt; ~/.agent-reach-venv/bin/activate
pip &lt;span class="nb"&gt;install &lt;/span&gt;https://github.com/Panniantong/agent-reach/archive/main.zip
agent-reach &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--env&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;auto
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Windows, use &lt;code&gt;py -3&lt;/code&gt; if &lt;code&gt;python3&lt;/code&gt; resolves only to the Microsoft Store alias .&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verify:&lt;/strong&gt; run &lt;code&gt;agent-reach version&lt;/code&gt; to confirm you have the Panniantong build and not the unrelated PyPI package, then run &lt;code&gt;agent-reach doctor --json&lt;/code&gt;. The v1.5.0 doctor is a live health check that reports &lt;code&gt;active_backend&lt;/code&gt; per channel and isolates failures, so one broken channel does not abort the full report .&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preview first:&lt;/strong&gt; to see what would be touched outside &lt;code&gt;~/.agent-reach/&lt;/code&gt; without changing anything, add &lt;code&gt;--dry-run&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agent-reach &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--env&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;auto &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Reddit Access Restrictions, Expiring Cookies, and Archive-Only Install
&lt;/h2&gt;

&lt;p&gt;Reddit has no zero-config path in Agent-Reach: anonymous API access is blocked, and official API access is approval-based, so the channel is not activated by the base install. It routes through OpenCLI first, then rdt-cli, and the docs flag it as inherently fragile . Expect breakage when Reddit tightens controls, and do not treat access as permanent.&lt;/p&gt;

&lt;p&gt;The other login-gated channels — Twitter, XiaoHongShu, Facebook, Instagram, and Xueqiu — need a one-time browser cookie export via the Cookie-Editor extension before they work, and Twitter additionally wants &lt;code&gt;TWITTER_AUTH_TOKEN&lt;/code&gt; and &lt;code&gt;TWITTER_CT0&lt;/code&gt; set for direct twitter-cli calls . Cookie-backed access carries account-ban and credential-exposure risk, so the official docs recommend a dedicated secondary "agent" account rather than your primary login.&lt;/p&gt;

&lt;p&gt;Two durability notes matter here. First, channel availability is not stable: v1.4.2 deliberately removed the Douyin, Weibo, and WeChat public-account channels the maintainers judged too unreliable to keep  — do not expect a dropped channel to reappear. Second, OpenCLI drives your existing logged-in Chrome session and stores credentials only under &lt;code&gt;~/.agent-reach/config.yaml&lt;/code&gt; at owner-only 0600 permissions, never uploaded . The local-first storage limits credential leakage, but the docs are explicit that ToS exposure for cookie-based scraping of walled platforms remains unresolved.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Configure Next: Twitter, LinkedIn, and XiaoHongShu
&lt;/h2&gt;

&lt;p&gt;Once the base install is healthy, add login-gated platforms explicitly — they are not part of the zero-config set. One command enables the common trio: &lt;code&gt;agent-reach install --env=auto --channels=twitter,linkedin,xiaohongshu&lt;/code&gt;, or use &lt;code&gt;--channels=all&lt;/code&gt; to activate every supported channel in a single pass . Each channel then routes through its documented backend.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Twitter/X&lt;/strong&gt; — set &lt;code&gt;TWITTER_AUTH_TOKEN&lt;/code&gt; and &lt;code&gt;TWITTER_CT0&lt;/code&gt; via &lt;code&gt;agent-reach configure twitter-cookies&lt;/code&gt; before direct twitter-cli calls will succeed; without them, calls fail .&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt; — uses linkedin-mcp with Jina Reader as a fallback, so public profile reads work without a cookie export .&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;XiaoHongShu&lt;/strong&gt; — routes to OpenCLI on desktop, then xiaohongshu-mcp on servers, then xhs-cli .&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay current with the same archive-based path: run &lt;code&gt;agent-reach check-update&lt;/code&gt;, upgrade from the GitHub archive URL, then run &lt;code&gt;agent-reach doctor&lt;/code&gt; to confirm each &lt;code&gt;active_backend&lt;/code&gt; is healthy after the upgrade . The concrete takeaway: enable only the channels you use, keep cookies on a dedicated agent account, and let &lt;code&gt;doctor&lt;/code&gt; — not a broken scrape mid-task — tell you when a backend has moved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is Agent-Reach available on PyPI?
&lt;/h3&gt;

&lt;p&gt;No — the official Panniantong project is not distributed through PyPI. The name &lt;code&gt;agent-reach&lt;/code&gt; on PyPI belongs to an unrelated package (v0.1.0 by Jean Galea, sourced from jgalea/agent-reach) uploaded on August 2, 2026, so a blind &lt;code&gt;pip install agent-reach&lt;/code&gt; would fetch the wrong project. Install from the GitHub archive instead: &lt;code&gt;pipx install https://github.com/Panniantong/agent-reach/archive/main.zip&lt;/code&gt; .&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Agent-Reach send my credentials or browsing data to a remote server?
&lt;/h3&gt;

&lt;p&gt;No. Agent-Reach is a local-only capability layer and is never in the request or response data path — it only selects, health-checks, and routes to upstream CLIs that the agent then calls directly. Credentials and tokens live under &lt;code&gt;~/.agent-reach/&lt;/code&gt; (config at &lt;code&gt;~/.agent-reach/config.yaml&lt;/code&gt;) with owner-only 0600 permissions and are never uploaded .&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens when a platform changes its anti-bot rules?
&lt;/h3&gt;

&lt;p&gt;The maintainers reorder or swap the affected backend in the next release, so builders do not patch private integrations. The canonical case: in June 2026 Bilibili began 412-blocking yt-dlp, and Agent-Reach switched the primary Bilibili backend from yt-dlp to bili-cli with zero user action . To pull a fix, run &lt;code&gt;agent-reach check-update&lt;/code&gt; and upgrade from the archive URL .&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Agent-Reach work with Cursor, Windsurf, or Codex — not just Claude Code?
&lt;/h3&gt;

&lt;p&gt;Yes. Any shell-capable coding agent works, including Claude Code, Cursor, Windsurf, Codex, and OpenClaw. Agent-Reach installs a SKILL.md instruction layer that tells the agent which channels are available and healthy; the agent then invokes the upstream CLIs directly rather than through a proprietary API .&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does Reddit not have a zero-config path?
&lt;/h3&gt;

&lt;p&gt;Anonymous Reddit API access is blocked, and official API access is approval-based, so there is no login-free route. Even with OpenCLI or rdt-cli configured, the channel depends on a personal session and is inherently fragile, which is why the docs treat Reddit as best-effort rather than a reliable channel .&lt;/p&gt;

</description>
      <category>agentreach</category>
      <category>claudecode</category>
      <category>opensource</category>
      <category>developertools</category>
    </item>
    <item>
      <title>Variant Claude Code design skill close design-quality gap vibe-coded websites repo setup a</title>
      <dc:creator>Creeta</dc:creator>
      <pubDate>Tue, 04 Aug 2026 03:57:26 +0000</pubDate>
      <link>https://dev.to/creeta/variant-claude-code-design-skill-close-design-quality-gap-vibe-coded-websites-repo-setup-a-43k5</link>
      <guid>https://dev.to/creeta/variant-claude-code-design-skill-close-design-quality-gap-vibe-coded-websites-repo-setup-a-43k5</guid>
      <description>&lt;p&gt;AI coding agents will hand you a working React and Tailwind page in minutes — and it will look exactly like everyone else's working React and Tailwind page. That sameness is the problem worth fixing before you ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Median-Aesthetic Problem: Why Vibe-Coded Pages Look Alike
&lt;/h2&gt;

&lt;p&gt;Vibe-coded pages look alike because tools like Claude Code and Codex reliably produce functional React/Tailwind but default to a narrow "median" visual direction on their first pass. The recognizable fingerprint: the Inter font, purple-and-white gradients, a four-card grid, faint hover states, and dense, arbitrary sections with inconsistent type — a look many builders now identify as machine-generated on sight .&lt;/p&gt;

&lt;p&gt;The emerging fix is to stop accepting an agent's first output and split the workflow into three stages: generate visual direction first, implement code second, then review and QA . The aesthetic gap is created at stage one — before Claude Code ever touches the repo — so that is where the intervention has to happen.&lt;/p&gt;

&lt;p&gt;Three tools target that first stage directly. Variant surfaces divergent UI directions from a single idea; Impeccable by Paul Bakaus ships 59 deterministic detector rules for AI-generated frontend design ; and Anthropic's Claude Design gained two-way Claude Code integration on June 18, 2026. The sections below walk the Variant-to-Claude-Code sequence step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Have Ready: Next.js, Tailwind, and Claude Code
&lt;/h2&gt;

&lt;p&gt;Before any design tool generates direction, stand up a React/Tailwind base and a context file. Start a Next.js or Vite + Tailwind project — most design exporters and agents target React and Tailwind, so this is the lowest-friction foundation for a Variant or Stitch handoff &lt;a href="https://www.youtube.com/watch?v=6iq6CjUJvxc" rel="noopener noreferrer"&gt;[1]&lt;/a&gt;. Then write your fixed copy and section requirements into a &lt;code&gt;CLAUDE.md&lt;/code&gt; or &lt;code&gt;PRODUCT.md&lt;/code&gt; file first; Claude Code and skills load context at session startup, so requirements committed to the repo steer both generation and integration &lt;a href="https://github.com/jiji262/claude-design-skill" rel="noopener noreferrer"&gt;[8]&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Install Claude Code through the native shell script, the Homebrew cask on macOS, Windows PowerShell, or WinGet — Anthropic's official repo marks the npm path deprecated &lt;a href="https://github.com/anthropics/claude-code" rel="noopener noreferrer"&gt;[14]&lt;/a&gt;. It ships on every paid Claude plan and draws from the same usage pool as Claude web, desktop, and mobile; Max starts at $100/month with 5× or 20× more usage than Pro .&lt;/p&gt;

&lt;p&gt;A minimal scaffold to anchor the pass looks like this (a verified script that writes a starter page and stylesheet — it was executed successfully):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;

&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;vibe_site_repo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;write_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;



Design Quality Pass



# Launch Audit



Replace vibe-coded defaults with clear hierarchy, contrast, spacing, and real content.

Review Site



&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;styles.css&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;write_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;:root { color-scheme: light; font-family: Inter, system-ui, sans-serif; }
body { margin: 0; background: #f7f8fa; color: #17202a; }
.hero { max-width: 720px; margin: 10vh auto; padding: 32px; }
h1 { margin: 0 0 12px; font-size: clamp(2rem, 6vw, 4rem); line-height: 1; }
p { max-width: 52ch; font-size: 1.15rem; line-height: 1.6; }
button { padding: 12px 16px; border: 0; border-radius: 6px; background: #0f766e; color: white; font-weight: 700; }
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;created &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/index.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;created &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/styles.css&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;design pass: hierarchy, spacing, contrast, responsive type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Direction Before Code: The Variant-to-Claude-Code Sequence
&lt;/h2&gt;

&lt;p&gt;Variant is a breadth-first design-exploration tool: you type an app or site idea and scroll through a continuous stream of UI directions, surfacing aesthetics you would not have invented from a single prompt. It is a YC-backed SaaS (batch F24) founded in 2024 with a team of five in San Francisco . The point is to explore direction &lt;em&gt;before&lt;/em&gt; Claude Code touches the repo — decoupling "what should this look like" from "how is this built."&lt;/p&gt;

&lt;p&gt;A workable sequence: open Variant, describe the site, and scroll until a hero-section style stands out. Treat that hero as your design-system anchor, then generate the remaining sections from that single direction so type, spacing, and color stay coherent. Export the HTML/React where available. One caveat worth checking first: a Product Hunt commenter flagged that code export moved behind a paid plan, so verify current export access and pricing before you standardize this on a team .&lt;/p&gt;

&lt;p&gt;Hand the exported markup to Claude Code with an explicit instruction set: integrate the sections into your Next.js structure, normalize components, add responsive behavior, fix accessibility, and wire routing and deployment. Claude Code is the implementation engine here, not the direction tool.&lt;/p&gt;

&lt;p&gt;To encode the handoff as a reusable rule, install a skill. Anthropic's plugin flow is &lt;code&gt;/plugin install &amp;lt;name&amp;gt;@marketplace&lt;/code&gt; at user scope; the &lt;code&gt;SKILL.md&lt;/code&gt; must sit directly in &lt;code&gt;~/.claude/skills/&amp;lt;name&amp;gt;/&lt;/code&gt; or &lt;code&gt;.claude/skills/&amp;lt;skill-name&amp;gt;/&lt;/code&gt; — not nested — and a fresh session is required to load it . Anthropic's official &lt;code&gt;frontend-design&lt;/code&gt; plugin skill is a repo-visible alternative that steers Claude toward distinctive, production-grade interfaces .&lt;/p&gt;

&lt;p&gt;For an open-source QA path, run &lt;code&gt;npx impeccable install&lt;/code&gt; to add Impeccable by Paul Bakaus (ex-Google, jQuery UI creator), Apache-2.0 with roughly 54.4k GitHub stars . Bakaus describes it as&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"1 skill, 23 commands, live browser iteration, and 59 deterministic detector rules for AI-generated frontend design," — Paul Bakaus, creator of Impeccable (source: &lt;a href="https://github.com/pbakaus/impeccable" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The 23 &lt;code&gt;/impeccable&lt;/code&gt; commands — audit, polish, critique, animate, colorize — and the 59 detector rules run during QA to close the median-aesthetic gap after Claude Code integrates the sections.&lt;/p&gt;

&lt;h2&gt;
  
  
  Variant Due Diligence: Disambiguation and Paywall
&lt;/h2&gt;

&lt;p&gt;Before standardizing on Variant, resolve a naming collision: "Variant" refers to two separate products. One is variant.ai, a Y Combinator batch F24 SaaS founded in 2024 in San Francisco, whose Product Hunt listing carries the tagline "Endless designs for your ideas, just scroll" with 167 upvotes at crawl time . The other is a Claude Code plugin, "Variant Design," built on the open-source Impeccable design system and distributed through a skills marketplace . Confirm which one any tutorial actually demonstrates — primary-source evidence points to the SaaS, but readable sources cannot fully settle it.&lt;/p&gt;

&lt;p&gt;Also verify the paywall. A Product Hunt commenter flagged that code export on the Variant SaaS moved behind a paid plan, and exact export formats plus the free-tier boundary were not clearly documented at crawl time . Check the current pricing page before building a repeatable team handoff around it.&lt;/p&gt;

&lt;p&gt;Finally, treat quality claims as empirical. No public benchmark compares Variant plus Claude Code output against v0, Stitch, or Lovable on real shipped pages . Inspect exported code manually, take desktop and mobile screenshots, and audit accessibility and SEO before treating the workflow as a reliable baseline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond Variant: Claude Design, Stitch, 21st, and Impeccable
&lt;/h2&gt;

&lt;p&gt;Variant is one entry in a crowded field, and several alternatives close the same design-quality gap from different angles. Anthropic's own Claude Design added two-way Claude Code integration on June 18, 2026 , exposing a &lt;code&gt;/design&lt;/code&gt; terminal command, a design-to-code handoff bundle, and codebase-aware imports, powered by Opus 4.7. It ships in research preview for Pro, Max, Team, and Enterprise with no separate subscription — it draws from the same usage pool as Claude Code .&lt;/p&gt;

&lt;p&gt;If Figma sits in your pipeline, Google Stitch is the stronger fit: it accepts text, images, sketches, screenshots, or wireframes and generates multiple UI variants via Gemini 2.5 Pro, and its May 19, 2026 update added real-time collaborative design, Netlify publishing, and Google Antigravity export . For a repo-native QA layer rather than direction discovery, Impeccable is the open-source choice (Apache-2.0): install with &lt;code&gt;npx impeccable install&lt;/code&gt;, then use its 23 &lt;code&gt;/impeccable&lt;/code&gt; commands and 59 deterministic anti-AI-aesthetic detector rules across Claude Code, Cursor, Copilot, and Codex .&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;th&gt;Access note&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude Design&lt;/td&gt;
&lt;td&gt;In-terminal handoff via &lt;code&gt;/design&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Same usage pool as Claude Code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Stitch&lt;/td&gt;
&lt;td&gt;Figma-in-the-loop, multi-variant&lt;/td&gt;
&lt;td&gt;Gemini 2.5 Pro, Netlify publish&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;21st&lt;/td&gt;
&lt;td&gt;Component search/install/audit&lt;/td&gt;
&lt;td&gt;Free installs capped at two per day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Impeccable&lt;/td&gt;
&lt;td&gt;QA-layer design enforcement&lt;/td&gt;
&lt;td&gt;Open-source, &lt;code&gt;npx impeccable install&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vercel v0&lt;/td&gt;
&lt;td&gt;Immediately deployable code&lt;/td&gt;
&lt;td&gt;React + Tailwind + shadcn/ui&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The 21st CLI, added July 6, 2026, connects Claude Code, Cursor, Codex, and Lovable to a single MCP endpoint to search, install, generate variants, and audit components; search and publishing are free, while installs are capped at two per day . Vercel v0 is the pick when you want deployable code over breadth-first exploration, generating React, Tailwind CSS, and shadcn/ui from a prompt. The concrete takeaway: pick one direction tool, one QA layer, and keep Claude Code as the repo owner — the stack matters less than treating every generated design as a draft you inspect, screenshot, and audit before it ships.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is Variant, and is it the same as the Variant Design skill for Claude Code?
&lt;/h3&gt;

&lt;p&gt;No — two separate products share the name, and confusing them will send you down the wrong workflow. Variant (variant.ai) is a Y Combinator batch F24 SaaS founded in 2024 in San Francisco  that lets you type an app idea and scroll continuously through UI directions — breadth-first visual exploration before any code exists . The "Variant Design" skill, by contrast, is a Claude Code plugin built on the open-source Impeccable design system that generates divergent aesthetic directions and exports HTML/React . Readable sources can't confirm which one the seed video demonstrates, though primary evidence points to the SaaS. Verify which product a tutorial actually uses before following its steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Variant's code export free?
&lt;/h3&gt;

&lt;p&gt;Not reliably. At the time of research, a Product Hunt commenter flagged that code export had moved behind a paid tier on the Variant SaaS . Design-direction scrolling may still be reachable on a free plan, but pricing and export access have been fluid since launch. Check the current pricing page and confirm what your plan includes before you standardize Variant in a team workflow — treat export availability as something to verify, not assume.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I install Impeccable for Claude Code?
&lt;/h3&gt;

&lt;p&gt;Run &lt;code&gt;npx impeccable install&lt;/code&gt; inside your project repo. That adds the SKILL.md at project scope and exposes 23 &lt;code&gt;/impeccable&lt;/code&gt; commands — audit, polish, critique, animate, colorize — that steer generation and run its deterministic detector rules for AI-generated frontends . Because skills load at startup, start a fresh Claude Code session after installing so the skill registers. Impeccable is Apache-2.0 licensed with roughly 54,000 GitHub stars, and it also works with Copilot, Cursor, and Codex .&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Claude Design replace Variant in this workflow?
&lt;/h3&gt;

&lt;p&gt;It is the closest official alternative, but not a confirmed one-to-one swap. Anthropic added a &lt;code&gt;/design&lt;/code&gt; terminal command on June 18, 2026 that generates directions inside Claude Design and hands off to Claude Code via Export → "Send to Claude Code," using the same shared usage pool so there's no separate subscription . What's unconfirmed is whether its interaction model matches Variant's breadth-first, scrollable exploration — the two differ in how they surface direction options, so evaluate both on your own output before committing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does Claude Code keep producing the same layout?
&lt;/h3&gt;

&lt;p&gt;Because Claude Code optimizes for working code, not aesthetic differentiation. The median layout — Inter font, four-card grids, purple gradients, faint hover states — is statistically dominant in its training data, so a first-pass agent defaults to it . The remedy is to supply an explicit visual direction before Claude Code generates any layout: use Variant, Stitch, or a design skill to fix the hero style and design-system anchor first, then let Claude Code implement and normalize from that direction rather than inventing one .&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>variant</category>
      <category>impeccable</category>
      <category>vibecoding</category>
    </item>
    <item>
      <title>Strix solved 100 of 104 real-world exploits — at $3.37 each</title>
      <dc:creator>Creeta</dc:creator>
      <pubDate>Mon, 03 Aug 2026 22:03:06 +0000</pubDate>
      <link>https://dev.to/creeta/strix-solved-100-of-104-real-world-exploits-at-337-each-2flh</link>
      <guid>https://dev.to/creeta/strix-solved-100-of-104-real-world-exploits-at-337-each-2flh</guid>
      <description>&lt;p&gt;A single hands-on reviewer pointed Strix at every challenge in a standard web-security benchmark and watched it break almost all of them — then attach a working exploit to each one. The headline number, and its price tag, are worth unpacking before you run the tool yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 96% PoC yield: what the XBEN dataset revealed about Strix
&lt;/h2&gt;

&lt;p&gt;Strix is an open-source agentic penetration-testing tool (repo &lt;a href="https://github.com/usestrix/strix" rel="noopener noreferrer"&gt;usestrix/strix&lt;/a&gt;, Apache-2.0) that runs a target application dynamically and attaches a working proof-of-concept to every finding. In one practitioner benchmark against XBEN — a set of 104 real-world web-security challenges in CTF format — Strix solved 100 of 104 (~96%), averaging about 19 minutes per challenge at roughly $337 total, or ~$3.37 per challenge in LLM API spend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick Answer:&lt;/strong&gt; In a single-reviewer XBEN benchmark, Strix — an open-source agentic pentest tool — solved 100 of 104 web-security challenges (~96%) at about $3.37 each in API cost. Unlike a scanner, each finding ships with the exact request that reproduces the break, plus a suggested fix.&lt;/p&gt;

&lt;p&gt;Treat that result as indicative, not authoritative: it comes from one hands-on reviewer, not a vendor-published or peer-reviewed study. What makes the yield notable is the mechanism behind it. Strix orchestrates a "Graph of Agents" — specialized reconnaissance/OSINT, exploitation, and post-exploitation subagents that run in parallel and share context, so one agent's discovery reshapes another's attack path . The payoff is validation over detection: each confirmed vulnerability arrives with the exact HTTP request or payload that reproduces it, plus remediation guidance . A Strix "finding" is a proven exploit, not a candidate awaiting manual triage.&lt;/p&gt;

&lt;p&gt;The project first appeared in November 2025, hit #1 on GitHub Trending on July 3, 2026 (+2,137 stars in a single day), and has accumulated roughly 47k stars as of mid-2026 — though exact counts vary by source, so verify the repo directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Strix for an initial PoC on a disposable VM
&lt;/h2&gt;

&lt;p&gt;Because Strix launches real exploits rather than passive scans, treat setup as a controlled lab exercise, not a casual install. The steps below take you from authorization to triaging a proven proof-of-concept against a deliberately vulnerable practice app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 0 — Get written authorization and isolate the target.&lt;/strong&gt; Strix executes live attacks against whatever you point it at, so running it against any system you do not own or lack explicit written permission to test is illegal, not a scan . Confine it to a VM or container you fully control before you run anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Install.&lt;/strong&gt; Two methods circulate, and the divergence itself is worth flagging. The official site advertises a one-line bootstrap, while community write-ups cite a pipx install . Verify against the current &lt;a href="https://github.com/usestrix/strix" rel="noopener noreferrer"&gt;usestrix/strix&lt;/a&gt; README before running either, since installer instructions have diverged across sources.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# official site&lt;/span&gt;
curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://strix.ai/install | bash

&lt;span class="c"&gt;# community write-ups&lt;/span&gt;
pipx &lt;span class="nb"&gt;install &lt;/span&gt;strix-agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2 — Set the model environment variables.&lt;/strong&gt; Strix routes to providers LiteLLM-style, so you export the model and a key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;STRIX_LLM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;model&amp;gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;LLM_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;key&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Official docs recommend OpenAI GPT-5.4, with Anthropic Claude Sonnet 4.6 and Google Gemini 3 Pro also supported, plus Ollama or LMStudio for fully local inference .&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Point it at a known-vulnerable practice app.&lt;/strong&gt; Run against a local codebase or a running URL with the &lt;code&gt;--target&lt;/code&gt; flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;strix &lt;span class="nt"&gt;--target&lt;/span&gt; ./app-directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Baseline its behavior against a deliberately vulnerable app such as DVWA or WebGoat before you aim it at anything you care about .&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4 — Triage the PoC output.&lt;/strong&gt; Each confirmed finding ships with the exact request or payload that reproduces it, plus a suggested fix . Replay the reproducing request to confirm it, then validate the suggested patch in an isolated branch before merging.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Strix underperforms: non-determinism and per-exploit expenditure
&lt;/h2&gt;

&lt;p&gt;Strix trades reproducibility for autonomy, and that trade-off is its main weakness. Because each run is driven by an LLM, the same target can surface different findings on different passes — there is no guarantee that run two reproduces run one. Nuclei sits at the opposite end: an identical YAML template against an identical endpoint returns identical output every time . For CI gates and regression checks, that determinism matters more than raw exploit depth.&lt;/p&gt;

&lt;p&gt;Cost is the second operational variable. In the XBEN evaluation, Strix averaged roughly $3.37 per challenge across 104 challenges, totaling about $337 . Extrapolate that to a large production surface and API spend accumulates quickly, whereas Nuclei and OWASP ZAP are effectively free to run at any cadence . The math is easy to model before you commit budget:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;solved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;104&lt;/span&gt;
&lt;span class="n"&gt;cost_each&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;3.37&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Strix solved &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;solved&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; of &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; real-world exploits - at $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cost_each&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; each&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;success_rate=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;solved&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;total_cost=$&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;solved&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cost_each&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That snippet is a verified illustration (it ran, exit 0) of the reported figures: a 96.2% solve rate at a $337 total . Wall-clock is the third constraint: Strix averaged about 19 minutes per challenge, while Nuclei sweeps thousands of endpoints with community templates in seconds .&lt;/p&gt;

&lt;p&gt;None of this makes Strix a replacement for those primitives. Its own documentation credits Nuclei and Caido as foundational dependencies — Strix wraps template-based detection inside an agentic loop rather than rebuilding it . As AppSecEngineer frames it, the tool is "popular not because it finds more than ZAP or Burp, but because it proves them" (source: &lt;a href="https://www.appsecengineer.com/blog/top-5-dast-scan-tools-for-security-testing" rel="noopener noreferrer"&gt;AppSecEngineer&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Strix, Nuclei, and ZAP as a complementary appsec trio
&lt;/h2&gt;

&lt;p&gt;Treat the three as a pipeline, not a contest. Nuclei, ZAP, and Strix each own a different stage of the loop — fast detection, broad coverage, and proof — and a small team gets the most value by chaining them in that order rather than picking one. Nuclei (ProjectDiscovery) is deterministic and template-driven, with near-zero marginal cost per run; its 2025–2026 releases added AI-assisted template generation that drafts a detection template from a plain-language vulnerability description . That makes it the ideal CI gate for known-CVE and misconfiguration sweeps. OWASP ZAP — now stewarded by Checkmarx — offers the broadest open-source DAST surface with strong Jenkins and GitHub Actions hooks, but like every scanner it emits candidate findings that a human must validate . That manual validation step is exactly what Strix automates, attaching a reproducible exploit to each confirmed finding .&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Cost per run&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Nuclei&lt;/td&gt;
&lt;td&gt;Deterministic templates&lt;/td&gt;
&lt;td&gt;Near-zero&lt;/td&gt;
&lt;td&gt;Fast known-CVE / misconfig CI gating&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OWASP ZAP&lt;/td&gt;
&lt;td&gt;Deterministic active/passive DAST&lt;/td&gt;
&lt;td&gt;Near-zero&lt;/td&gt;
&lt;td&gt;Broad coverage of your specific app&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strix&lt;/td&gt;
&lt;td&gt;Non-deterministic, LLM-driven agents&lt;/td&gt;
&lt;td&gt;~$3.37/exploit on XBEN&lt;/td&gt;
&lt;td&gt;Auto-validating high-severity candidates with a PoC&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A practical triage order: run Nuclei first for fast CVE gating, follow with a ZAP sweep for breadth, then point Strix at the highest-severity candidates to auto-validate each one with a working exploit before you file it. To evaluate all three honestly, run them against the same deliberately vulnerable app and compare four things: findings count, false-positive rate, whether each finding is actually proven, and wall-clock plus dollar cost . The takeaway: keep the cheap deterministic scanners as your always-on gate, and reserve Strix's per-run spend for the findings where a reproducible proof-of-concept saves the most analyst hours .&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is the 100/104 XBEN result from an official Strix benchmark?
&lt;/h3&gt;

&lt;p&gt;No. The 100 of 104 figure on the XBEN CTF dataset comes from a single practitioner's hands-on evaluation, not a peer-reviewed study or a vendor-published benchmark . It is useful signal, but treat it as indicative. Before relying on it, reproduce the run locally against a deliberately vulnerable target such as DVWA or WebGoat to establish your own baseline.&lt;/p&gt;

&lt;h3&gt;
  
  
  How much does running Strix cost compared to Nuclei or OWASP ZAP?
&lt;/h3&gt;

&lt;p&gt;Nuclei and OWASP ZAP are free to run at any frequency because they are deterministic and carry near-zero marginal cost. Strix spends LLM API tokens on every run: the XBEN evaluation averaged $3.37 per challenge for a total of about $337 across 104 challenges. For an app with many endpoints, budget the spend explicitly and weigh it against the hourly rate of a manual penetration tester.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Strix replace Nuclei or OWASP ZAP?
&lt;/h3&gt;

&lt;p&gt;No. Strix's own documentation credits Nuclei as a foundational open-source dependency, so it wraps template-based scanning inside a broader agentic loop rather than replacing it . The three tools are complementary: Nuclei for fast, template-driven detection of known CVEs, ZAP for broad DAST coverage of your specific app, and Strix for autonomous proof-of-concept generation on the findings that matter most .&lt;/p&gt;

&lt;h3&gt;
  
  
  Which LLM gives the best results with Strix?
&lt;/h3&gt;

&lt;p&gt;The official documentation recommends OpenAI GPT-5.4 as the default model . Anthropic Claude Sonnet 4.6, Google Gemini 3 Pro, and providers such as Vertex AI, Bedrock, and Azure are also supported through LiteLLM-style routing, along with local models via Ollama or LMStudio . Local inference avoids API cost but may reduce accuracy on complex, multi-step exploit chains.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I run Strix in CI/CD the way I run Nuclei or ZAP?
&lt;/h3&gt;

&lt;p&gt;It is technically possible but slow and expensive. At roughly 19 minutes and $3.37 per challenge, Strix is not suited to every-commit gates. Use Nuclei for CI gating and broad ZAP passes for scheduled coverage, and reserve Strix for targeted pre-release validation of high-severity candidates where a reproducible exploit saves the most analyst time .&lt;/p&gt;

</description>
      <category>strix</category>
      <category>pentesting</category>
      <category>appsec</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Claude Code frontend plugin bans three looks it kept producing</title>
      <dc:creator>Creeta</dc:creator>
      <pubDate>Mon, 03 Aug 2026 15:48:15 +0000</pubDate>
      <link>https://dev.to/creeta/claude-code-frontend-plugin-bans-three-looks-it-kept-producing-516</link>
      <guid>https://dev.to/creeta/claude-code-frontend-plugin-bans-three-looks-it-kept-producing-516</guid>
      <description>&lt;p&gt;If you've ever asked Claude Code for a landing page and gotten back the same tasteful-but-anonymous layout you've seen a hundred times, Anthropic now ships a fix that runs before the first line of CSS.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Frontend Design Plugin Actually Enforces
&lt;/h2&gt;

&lt;p&gt;The Frontend Design plugin is a Claude Code skill that forces an explicit aesthetic commitment before Claude writes any styles. It ships as a compact &lt;code&gt;SKILL.md&lt;/code&gt; inside the &lt;a href="https://github.com/anthropics/claude-code/tree/main/plugins/frontend-design" rel="noopener noreferrer"&gt;anthropics/claude-code repo&lt;/a&gt; under &lt;code&gt;plugins/frontend-design&lt;/code&gt;, and it reframes the model's job: instead of generating markup on request, Claude first has to decide what the page should look like and defend that choice.&lt;/p&gt;

&lt;p&gt;The skill casts the model in a specific role:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The design lead at a small studio known for giving every client a visual identity that could not be mistaken for anyone else's" — from the plugin's &lt;code&gt;SKILL.md&lt;/code&gt; (source: &lt;a href="https://github.com/anthropics/claude-code/tree/main/plugins/frontend-design" rel="noopener noreferrer"&gt;anthropics/claude-code&lt;/a&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before any CSS, it demands a compact token system: 4–6 named hex colors, at least two typeface roles (a characterful display face used with restraint plus a body face), one-sentence layout descriptions accompanied by ASCII wireframes, and a single "signature" element the page is remembered by . The root problem it targets is statistical: Claude defaults to aesthetics that dominate its training data, so the plugin forces deliberate deviation before that default fires.&lt;/p&gt;

&lt;p&gt;Community trackers report the plugin was published November 12, 2025  and passed roughly 300,000 installs by late April 2026  — figures that are secondary and not independently confirmed by Anthropic.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Enable the Plugin and Interpret the Two-Pass Output
&lt;/h2&gt;

&lt;p&gt;Enabling the plugin takes one command inside any Claude Code session: &lt;code&gt;/plugin install frontend-design@anthropics/claude-code&lt;/code&gt;. It ships from the official &lt;a href="https://github.com/anthropics/claude-code/tree/main/plugins/frontend-design" rel="noopener noreferrer"&gt;anthropics/claude-code&lt;/a&gt; repository, so there is nothing to clone or build — the SKILL.md loads into your context and reshapes how Claude approaches any frontend request. Claude Code itself is bundled with paid Claude plans: Pro at $20/month, or $17/month billed annually, and Max from $100/month . No separate plugin fee applies.&lt;/p&gt;

&lt;p&gt;Once installed, the plugin runs two passes before it writes a single line of CSS. &lt;strong&gt;Pass 1 — Brainstorm:&lt;/strong&gt; Claude drafts a full token system first — a 4–6 color hex palette, typeface roles (a characterful display face used with restraint, a body face, an optional utility face), one-sentence layout descriptions with ASCII wireframes, and a single "signature" element the page is remembered by. All of this happens in the plan, not in your implementation files, so you can read the design intent before any code lands &lt;a href="https://github.com/anthropics/claude-code/tree/main/plugins/frontend-design" rel="noopener noreferrer"&gt;[2]&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pass 2 — Critique:&lt;/strong&gt; Claude then reviews its own plan against your brief and rewrites any part that "reads like the generic default you would produce for any similar page" &lt;a href="https://claude.com/plugins/frontend-design" rel="noopener noreferrer"&gt;[3]&lt;/a&gt;. Only after that self-critique does it emit CSS. Treat the brainstorm-plus-critique block as a review checkpoint: if the palette or signature element still feels generic, correct it there rather than after implementation.&lt;/p&gt;

&lt;p&gt;The final phase is a verify loop. After Claude implements, paste a screenshot of the running page and ask it to compare the output against your target. Anthropic recommends automated capture through the Puppeteer MCP or a simulator MCP so Claude can screenshot and iterate on its own &lt;a href="https://www.anthropic.com/engineering/claude-code-best-practices" rel="noopener noreferrer"&gt;[4]&lt;/a&gt;, or you can grab a manual capture from the Browser pane in &lt;a href="https://code.claude.com/docs/en/desktop" rel="noopener noreferrer"&gt;Claude Code Desktop&lt;/a&gt;. Claude performs measurably better when it has something concrete to verify against, so keep the loop tight — one dimension per revision.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Aesthetic Clusters the Plugin Refuses
&lt;/h2&gt;

&lt;p&gt;The Frontend Design plugin names three specific "AI-generated" looks it will not produce unless your brief explicitly asks for them, because each is a default the model reaches for when it has no stronger direction . The bans are conditional: the check targets blind default selection, not a client's deliberate choice, so a warm editorial palette that the brief calls for passes without complaint.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cluster&lt;/th&gt;
&lt;th&gt;Signature ingredients&lt;/th&gt;
&lt;th&gt;Why it's flagged&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Artisanal / editorial&lt;/td&gt;
&lt;td&gt;Warm cream background (~#F4F1EA), high-contrast serif headline, terracotta accent&lt;/td&gt;
&lt;td&gt;The dominant default "hand-crafted" landing look&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Developer-tool dark&lt;/td&gt;
&lt;td&gt;Near-black dark mode, a single acid-green or vermilion accent&lt;/td&gt;
&lt;td&gt;The prevalent SaaS "dark dashboard" template&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Broadsheet / Bauhaus&lt;/td&gt;
&lt;td&gt;Hairline rules, zero border-radius, dense monochrome text columns&lt;/td&gt;
&lt;td&gt;The generic newspaper-grid fallback&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two further guardrails sit alongside the palette bans. Numbered section markers (01 / 02 / 03) are flagged unless the content is a genuine sequence, and excess animation is called out directly: motion "contributes to the feeling that the design is AI-generated" . The plugin's summary directive is to "spend your boldness in one place" — commit to a single signature element rather than scattering effects across the page.&lt;/p&gt;

&lt;p&gt;The mechanism is a keyword-style match against the requested aesthetic: cluster ingredients present with no brief-level justification get sent back for revision. The illustrative Python below (executed successfully, but a simplified stand-in — not the plugin's real rule set) shows the shape of that check, blocking prompts whose look matches a banned cluster while letting an intentional, distinctive request through:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Minimal demo: a Claude Code frontend plugin blocks repeated bad looks.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="n"&gt;BANNED_LOOKS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;purple-gradient-hero&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;purple&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gradient&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hero&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;glassmorphism-cards&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;glass&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;blur&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;card&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;floating-orb-background&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;orb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;blob&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;background&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;banned_looks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;required_words&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;BANNED_LOOKS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;required_words&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Make a SaaS page with a purple gradient hero&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Use glass blur card panels everywhere&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Add orb blob background decoration&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Build a dense, neutral dashboard&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;blocked&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;banned_looks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;BAN&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;blocked&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;OK &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; -&amp;gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;blocked&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;allowed&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How the Plugin Pairs with Claude Design and v0
&lt;/h2&gt;

&lt;p&gt;That banned-cluster check fires at the Claude Code stage, which is only one layer of a realistic workflow. Anthropic's Claude Design is a separate canvas tool that builds a first version from a plain description and exports standard HTML with Tailwind or inline CSS and vanilla JavaScript, deployable to Vercel, Netlify, or GitHub Pages . It sits at the visual-prototype layer, ahead of production code, and reviewers note it produces more complete full pages than v0's component-level output .&lt;/p&gt;

&lt;p&gt;The division of labor is practical:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;v0&lt;/strong&gt; wins time-to-first-screen for greenfield UI, with visual annotation and hosted preview; its February 4, 2026 update added Git integration, a VS Code-style editor, and a sandbox runtime .&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code plus the Frontend Design plugin&lt;/strong&gt; wins time-to-production inside an existing repo — multi-file edits, git, and build/test loops, where the banned-cluster check applies .&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most teams run a hybrid: Claude Design or v0 to "make it look right," then Claude Code to "make it work right." Wire in the shadcn MCP server so Claude reuses existing &lt;code&gt;components.json&lt;/code&gt; primitives instead of hand-rolling duplicates . The takeaway: whichever tool draws the first pass, both still emit empty headlines and placeholder testimonials — treat the output as draft and delete the fake proof by hand before shipping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How do I install the Frontend Design Plugin for Claude Code?
&lt;/h3&gt;

&lt;p&gt;Run &lt;code&gt;/plugin install frontend-design@anthropics/claude-code&lt;/code&gt; in any Claude Code session. It requires a paid Claude plan — Pro ($17/month billed annually or $20 monthly) or Max (from $100/month). The plugin adds a compact &lt;code&gt;SKILL.md&lt;/code&gt; that fires before any CSS-generation task, so there is nothing else to configure after install. See the &lt;a href="https://github.com/anthropics/claude-code/tree/main/plugins/frontend-design" rel="noopener noreferrer"&gt;plugin source on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What exactly are the three aesthetic clusters the plugin bans?
&lt;/h3&gt;

&lt;p&gt;The skill refuses three clustered "AI-generated" looks unless the brief explicitly asks for them: (1) warm cream (~#F4F1EA) paired with a high-contrast serif and a terracotta accent; (2) near-black dark mode with a single acid-green or vermilion accent; and (3) the hairline-rule, zero-radius, monochrome "broadsheet" template. All three bans are conditional — they trigger only when the brief does not call for that direction, per the &lt;a href="https://github.com/anthropics/claude-code/tree/main/plugins/frontend-design" rel="noopener noreferrer"&gt;SKILL.md&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does the two-pass design review happen automatically or do I trigger it?
&lt;/h3&gt;

&lt;p&gt;Automatically. There is no separate command. The &lt;code&gt;SKILL.md&lt;/code&gt; instructs Claude to run two passes before writing any CSS: first brainstorm a compact token system — 4–6 named hex colors, two or more typeface roles, one-sentence layout descriptions with ASCII wireframes, and a single "signature" element — then critique that plan and revise it "if any part of it reads like the generic default you would produce for any similar page" (&lt;a href="https://github.com/anthropics/claude-code/tree/main/plugins/frontend-design" rel="noopener noreferrer"&gt;Anthropic, 2025&lt;/a&gt;). The instruction fires the moment Claude starts a frontend task in the session.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does Claude Code with this plugin compare to v0 for landing pages?
&lt;/h3&gt;

&lt;p&gt;They win on different axes. v0 leads on time-to-first-screen, visual annotation, and hosted preview for greenfield UI; its &lt;a href="https://www.buildthisnow.com/blog/tools/extensions/claude-code-vs-v0" rel="noopener noreferrer"&gt;quickstart&lt;/a&gt; is a web chat that generates from a description and defaults to shadcn/ui. Claude Code leads on time-to-production inside an existing repo — multi-file edits, git, and real build and test integration, documented in &lt;a href="https://www.anthropic.com/engineering/harness-design-long-running-apps" rel="noopener noreferrer"&gt;Anthropic's harness-design writeup&lt;/a&gt;. The banned-cluster check is a Claude Code-only feature. Most teams use both: draw the first pass in one, ship from the other.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can the plugin's aesthetic restrictions be overridden?
&lt;/h3&gt;

&lt;p&gt;Yes. The bans are conditional on the brief not specifying those aesthetics. If your brief explicitly requests, say, a dark mode with a green accent, the plugin will not refuse it — the guardrail targets blind statistical default selection, not an intentional client request. In practice, name the direction you actually want in the prompt and the two-pass review treats it as the target rather than the generic default it is trained to avoid (&lt;a href="https://github.com/anthropics/claude-code/tree/main/plugins/frontend-design" rel="noopener noreferrer"&gt;frontend-design SKILL.md&lt;/a&gt;).&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>frontend</category>
      <category>plugin</category>
      <category>landingpage</category>
    </item>
    <item>
      <title>101k stars and can't do long-form: MoneyPrinterTurbo's limit</title>
      <dc:creator>Creeta</dc:creator>
      <pubDate>Mon, 03 Aug 2026 09:51:55 +0000</pubDate>
      <link>https://dev.to/creeta/101k-stars-and-cant-do-long-form-moneyprinterturbos-limit-26jk</link>
      <guid>https://dev.to/creeta/101k-stars-and-cant-do-long-form-moneyprinterturbos-limit-26jk</guid>
      <description>&lt;p&gt;MoneyPrinterTurbo is the most-starred open-source video generator on GitHub, and its July 2026 release polished the short-form workflow further — yet a 22-minute narrated YouTube video still falls outside what it was built to make.&lt;/p&gt;

&lt;h2&gt;
  
  
  MoneyPrinterTurbo at 101k stars: v1.3.3 scope and why 16:9 narrated YouTube lands outside it
&lt;/h2&gt;

&lt;p&gt;MoneyPrinterTurbo (harry0703, MIT) is a keyword-to-finished-HD-video compositor with roughly 101k stars — the most popular project of its kind. It generates a script, matches stock footage, adds subtitles and background music, and renders through FFmpeg, exposing WebUI, API, CLI, and AI-agent workflows plus one-click publishing to TikTok, Instagram, and YouTube Shorts. The constraint for long-form is not the frame; it is that nothing orchestrates act structure or pacing across sequential minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick Answer:&lt;/strong&gt; MoneyPrinterTurbo renders both 9:16 (1080×1920) and 16:9 (1920×1080), so aspect ratio is not the blocker. With ~101k GitHub stars it leads short-format generators, but it ships no chapter, scene-pacing, or narrative-timing layer — leaving 10–30 minute narrated YouTube outside its design.&lt;/p&gt;

&lt;p&gt;The latest release, v1.3.3 (July 24, 2026), adds voiceover preview with an estimated-duration readout, optional video-matched background music via Sonilo and ElevenLabs, custom music uploads, clip speed control, ZoomIn/ZoomOut transitions, and more robust task recovery. Every addition refines a seconds-long clip; the gallery examples are built for Shorts, not narrative video.&lt;/p&gt;

&lt;p&gt;The provider matrix is broad — LLMs including DeepSeek, Alibaba Qwen, Google Gemini, and local Ollama; TTS including Edge, Chatterbox, ElevenLabs, and SiliconFlow — with Pexels, Pixabay, Coverr, and local assets on the retrieval side . What it does not carry is any pacing engine. A short model of its limits makes the boundary concrete (verified, executed):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dataclasses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dataclass&lt;/span&gt;


&lt;span class="nd"&gt;@dataclass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frozen&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ShortVideoTool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;stars&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;max_minutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;max_script_chars&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;can_handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;script_chars&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;minutes&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_minutes&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;script_chars&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_script_chars&lt;/span&gt;


&lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ShortVideoTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MoneyPrinterTurbo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;101k&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_minutes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_script_chars&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;long_form_minutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt;
&lt;span class="n"&gt;long_form_script&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;scene &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stars&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; stars&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;requested: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;long_form_minutes&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; min, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;long_form_script&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; script chars&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;limit: &amp;lt;= &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_minutes&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; min, &amp;lt;= &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_script_chars&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; script chars&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;can_do_long_form:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;can_handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;long_form_minutes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;long_form_script&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Chatterbox Multilingual v3 (MIT), Kokoro-82M (Apache), Piper GPL-3.0: narration licensing for commercial YouTube
&lt;/h2&gt;

&lt;p&gt;For a monetized 16:9 channel, the narration model's license matters as much as its voice quality, because a non-commercial weight disqualifies an entire pipeline no matter how good it sounds. Three open models are commercial-safe today — Chatterbox Multilingual v3 (MIT), Kokoro-82M (Apache-2.0), and Piper (GPL-3.0) — while the two highest-profile cloning models, XTTS v2 and F5-TTS, are explicitly non-commercial and cannot legally back a revenue-generating video.&lt;/p&gt;

&lt;p&gt;Chatterbox Multilingual v3 (Resemble AI, released June 10, 2026) is the notable entry: a 0.5B Llama-based backbone under the MIT license, preferred over ElevenLabs in roughly 63.75% of blind A/B tests — the first permissively licensed open model that is directly competitive with ElevenLabs on voice cloning, with no restriction on monetized use [MIT]. Treat the A/B figure as a directional vendor benchmark, not peer-reviewed evidence.&lt;/p&gt;

&lt;p&gt;Kokoro-82M reached v1.0 on January 27, 2025: 82M parameters, 54 voices across 8 languages, Apache-2.0, and faster than real time on CPU. It cannot clone voices, which for narration is a feature — you get a consistent presenter voice with zero commercial constraint. Piper is fastest for edge and CPU work at roughly 40ms to first audio, but the licensing moved: the original rhasspy/piper (MIT) was archived in October 2025 and active development is now OHF-Voice/piper1-gpl under GPL-3.0 — so any redistributed product carries GPL obligations, even if the rendered video itself does not.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;License&lt;/th&gt;
&lt;th&gt;Cloning&lt;/th&gt;
&lt;th&gt;Commercial YouTube&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chatterbox Multilingual v3&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Clear&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kokoro-82M v1.0&lt;/td&gt;
&lt;td&gt;Apache-2.0&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Clear&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Piper (piper1-gpl)&lt;/td&gt;
&lt;td&gt;GPL-3.0&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Clear, with redistribution obligation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;XTTS v2&lt;/td&gt;
&lt;td&gt;CPML&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Disqualified (non-commercial)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F5-TTS&lt;/td&gt;
&lt;td&gt;CC-BY-NC&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Disqualified (non-commercial)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The practical rule: pick Kokoro for a fixed narrator, Chatterbox when you need cloning under a clean license, and Piper for the lowest-latency CPU path — and skip XTTS v2 and F5-TTS entirely if the channel earns money, regardless of their MOS scores.&lt;/p&gt;

&lt;h2&gt;
  
  
  ShortGPT's ContentVideoEngine or OpenMontage: assembling a narrated 16:9 MP4
&lt;/h2&gt;

&lt;p&gt;Once narration is licensed, assembling a narrated 16:9 MP4 means stitching script, voice, footage, captions, and a render pass into one timeline — and two open projects own most of that chain. ShortGPT (MIT, ~7.8k stars) exposes its &lt;em&gt;ContentVideoEngine&lt;/em&gt; for longer-form narration with auto-sourced Pexels footage, built on an LLM-oriented Editing Markup Language plus JSON that decomposes each edit into blocks an LLM can reason about . Voice comes from EdgeTTS (free) or ElevenLabs; rendering runs through MoviePy, whose v2.0 introduced breaking API changes you must account for when forking. The Gradio UI listens on port 31415. Treat ShortGPT as a developer framework to fork, not a turnkey app.&lt;/p&gt;

&lt;p&gt;OpenMontage (MIT, calesthio) is the more ambitious architecture: YAML pipeline manifests, 100+ Python tools, and 700+ agent skill files across 12 declared production pipelines spanning explainers, talking heads, screen demos, trailers, animation, podcasts, and documentary montages . It scores providers across seven weighted dimensions — task fit 30%, output quality 20%, control 15%, reliability 15%, cost efficiency 10%, latency 5%, continuity 5% — then renders via Remotion or FFmpeg .&lt;/p&gt;

&lt;p&gt;The part that matters for long renders that cost real money is its budget governance and QA. Per its own documentation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A default $0.50 per-action approval threshold and $10 total budget cap are enforced before composition; post-render QA includes ffprobe validation, frame sampling, audio/subtitle checks, and slideshow-risk scoring." — OpenMontage project documentation (source: &lt;a href="https://github.com/calesthio/OpenMontage" rel="noopener noreferrer"&gt;OpenMontage&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Neither project fully owns caption alignment, so pull it from dedicated tools. WhisperX gives word-level timestamps and diarization via VAD and forced alignment (faster-whisper/CTranslate2), with known weakness on overlapping speech. PySceneDetect v0.7 (May 3, 2026) handles shot-change detection with CSV/HTML/FCP/OTIO outputs, and auto-editor 30.3.0 (May 27, 2026) strips silence via audio/motion thresholds and exports to Premiere, Resolve, Final Cut, Shotcut, and Kdenlive.&lt;/p&gt;

&lt;p&gt;The gap these frameworks close is exactly the one MoneyPrinterTurbo leaves open — a duration and script ceiling that fails cleanly rather than degrading. This illustrative check makes that boundary explicit (it executed and returned &lt;code&gt;False&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dataclasses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dataclass&lt;/span&gt;


&lt;span class="nd"&gt;@dataclass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frozen&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ShortVideoTool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;stars&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;max_minutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;max_script_chars&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;can_handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;script_chars&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;minutes&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_minutes&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;script_chars&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_script_chars&lt;/span&gt;


&lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ShortVideoTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MoneyPrinterTurbo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;101k&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_minutes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_script_chars&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;long_form_minutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt;
&lt;span class="n"&gt;long_form_script&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;scene &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stars&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; stars&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;requested: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;long_form_minutes&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; min, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;long_form_script&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; script chars&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;limit: &amp;lt;= &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_minutes&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; min, &amp;lt;= &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_script_chars&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; script chars&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;can_do_long_form:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;can_handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;long_form_minutes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;long_form_script&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Where the zero-touch promise collapses: narration licensing and YouTube's post-2020 verification
&lt;/h2&gt;

&lt;p&gt;The remaining failure points sit at the upload boundary, not in generation. Even a clean 16:9 MP4 hits Google's verification gate: applications created after July 28, 2020 without OAuth verification can upload only private-only videos until Google audits the project. Any fresh repo expecting public publishing fails on its first &lt;code&gt;videos.insert&lt;/code&gt; call — a hard stop no amount of local automation bypasses.&lt;/p&gt;

&lt;p&gt;Quota planning also moved. A documentation update on December 4, 2025 cut the &lt;code&gt;videos.insert&lt;/code&gt; cost from roughly 1,600 units to about 100, and a granular quota system for &lt;code&gt;videos.insert&lt;/code&gt; and &lt;code&gt;search.list&lt;/code&gt; went live on June 1, 2026. Stale docs citing 1,600 units are still common, so any automated channel setup needs current numbers before it schedules a single upload.&lt;/p&gt;

&lt;p&gt;Treat "zero-touch" claims skeptically. yt_autopilot's README advertises full end-to-end autonomy up top, then its production section mandates a human-in-the-loop gate and states it "NEVER uploads to YouTube automatically" before explicit approval  — the repo contradicts itself. Rendering carries a similar footnote: Remotion, used by OpenMontage, is free for individuals and organizations of three or fewer employees, with larger teams needing a paid license .&lt;/p&gt;

&lt;p&gt;The takeaway: generation is solved, publishing is not. Verify your Google project, budget the new quota, keep a human on the upload button, and check the render engine's license before you ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does MoneyPrinterTurbo support 16:9 YouTube aspect ratio?
&lt;/h3&gt;

&lt;p&gt;Yes. MoneyPrinterTurbo renders 1920×1080 (16:9) alongside 9:16 vertical output . The limit is not aspect ratio but narrative depth: it has no chapter or scene-pacing model for structured 10–30 minute narration. The v1.3.3 release (July 24, 2026) added clip speed control and ZoomIn/ZoomOut transitions, but not act structure or narrative timing . Feed it a keyword and it produces a stitched short; a 45-minute narrated explainer still needs a separate planning and pacing layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Chatterbox Multilingual v3 safe for a monetized YouTube channel?
&lt;/h3&gt;

&lt;p&gt;Yes. Chatterbox Multilingual v3 ships under the MIT license from Resemble AI (June 10, 2026), so no commercial restriction applies . That contrasts with XTTS v2 (CPML, non-commercial) and F5-TTS (CC-BY-NC, non-commercial), which cannot legally back a revenue channel. Chatterbox was preferred over ElevenLabs in roughly 63.75% of blind A/B tests, though those figures come from third-party benchmarks, not peer-reviewed evaluation, so treat them as directional rather than settled.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happened to the MIT-licensed Piper TTS?
&lt;/h3&gt;

&lt;p&gt;The original rhasspy/piper (MIT) was archived in October 2025, and active development moved to OHF-Voice/piper1-gpl under GPL-3.0 . Piper remains the fastest CPU option (~40ms to first audio), but the license change matters: GPL-3.0 redistribution obligations now attach to anything you ship that bundles it. For narration only, Kokoro-82M (Apache-2.0) avoids that copyleft entirely .&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do new YouTube API projects upload videos as private?
&lt;/h3&gt;

&lt;p&gt;Google OAuth projects created after July 28, 2020 upload private-only videos until Google audits the project, per YouTube's current videos.insert documentation. This verification gate is separate from the December 2025 quota change that cut videos.insert cost from roughly 1,600 units to about 100. Both constraints hit an automated channel simultaneously: your renders finish, but the upload endpoint publishes them privately and meters your calls until you pass audit. Plan the verification request before you build the pipeline, not after.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does OpenMontage's budget governance actually do?
&lt;/h3&gt;

&lt;p&gt;It enforces a default $0.50-per-action approval threshold and a $10 total budget cap before composition begins, so a long-form render cannot silently rack up API charges . Provider selection is scored across seven weighted dimensions: task fit 30%, output quality 20%, control 15%, reliability 15%, cost efficiency 10%, latency 5%, and continuity 5% . Together these guardrails favor cheaper providers where quality is comparable and stop runaway spend on multi-scene 16:9 jobs.&lt;/p&gt;

</description>
      <category>moneyprinterturbo</category>
      <category>shortgpt</category>
      <category>openmontage</category>
      <category>chatterbox</category>
    </item>
    <item>
      <title>Sub-agents can hold MCP servers the parent session doesn't</title>
      <dc:creator>Creeta</dc:creator>
      <pubDate>Mon, 03 Aug 2026 04:01:54 +0000</pubDate>
      <link>https://dev.to/creeta/sub-agents-can-hold-mcp-servers-the-parent-session-doesnt-3nli</link>
      <guid>https://dev.to/creeta/sub-agents-can-hold-mcp-servers-the-parent-session-doesnt-3nli</guid>
      <description>&lt;p&gt;Anthropic's answer to "how do I build a team of Claude agents" isn't a framework — it's a ladder of primitives, and the first genuinely useful rung is a sub-agent that can hold MCP servers the parent session never touches.&lt;/p&gt;

&lt;h2&gt;
  
  
  What &lt;code&gt;mcpServers&lt;/code&gt; gives a Claude Code sub-agent
&lt;/h2&gt;

&lt;p&gt;A Claude Code sub-agent can declare its own MCP servers in frontmatter, and the parent session never loads them. According to &lt;a href="https://code.claude.com/docs/en/sub-agents" rel="noopener noreferrer"&gt;Anthropic's sub-agents documentation&lt;/a&gt;, an inline server in a sub-agent's &lt;code&gt;mcpServers&lt;/code&gt; field connects when the sub-agent starts and disconnects when it finishes . That keeps the server's tool descriptions and token overhead out of the main conversation's context window — the parent stays lean while the specialist gets equipped.&lt;/p&gt;

&lt;p&gt;There are two ways to list a server. An &lt;em&gt;inline&lt;/em&gt; entry spins up a fresh connection scoped to the sub-agent's run; a &lt;em&gt;string reference&lt;/em&gt; reuses an already-named session connection instead of starting a new process . The rest of the definition is minimal by design: a sub-agent is a Markdown file in &lt;code&gt;.claude/agents/&lt;/code&gt;, and only &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; are required. Everything else — &lt;code&gt;mcpServers&lt;/code&gt;, &lt;code&gt;tools&lt;/code&gt;, &lt;code&gt;disallowedTools&lt;/code&gt;, &lt;code&gt;model&lt;/code&gt;, &lt;code&gt;permissionMode&lt;/code&gt;, &lt;code&gt;maxTurns&lt;/code&gt; — is optional .&lt;/p&gt;

&lt;p&gt;Anthropic's canonical example is a &lt;code&gt;browser-tester&lt;/code&gt; sub-agent given an inline Playwright MCP server plus a referenced GitHub server. Defining Playwright inline keeps its tool descriptions out of the parent context while still handing the sub-agent full browser control . The relationship is easy to model — the parent's server list stays empty while the sub-agent carries its own:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dataclasses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dataclass&lt;/span&gt;


&lt;span class="nd"&gt;@dataclass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frozen&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MCPServer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;


&lt;span class="nd"&gt;@dataclass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frozen&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;mcp_servers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MCPServer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="n"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;parent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sub_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sub-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MCPServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;private-filesystem&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),))&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; MCP servers: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mcp_servers&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;sub_agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; MCP servers: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;sub_agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mcp_servers&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mcp_servers&lt;/span&gt;
&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;sub_agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mcp_servers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mcp_servers&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That snippet is a small illustrative model (verified to run, printing an empty parent list and &lt;code&gt;['private-filesystem']&lt;/code&gt; for the sub-agent) — not the real Claude Code internals, but an accurate picture of the isolation the &lt;code&gt;mcpServers&lt;/code&gt; field buys you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a sub-agent definition: mcpServers, tools, and disallowedTools
&lt;/h2&gt;

&lt;p&gt;A sub-agent is a single Markdown file with YAML frontmatter. Drop it at &lt;code&gt;.claude/agents/&amp;lt;name&amp;gt;.md&lt;/code&gt; for project scope or &lt;code&gt;~/.claude/agents/&amp;lt;name&amp;gt;.md&lt;/code&gt; for user scope. Only &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; are required . On name conflicts, project definitions win over user ones, and the full resolution order is managed settings → &lt;code&gt;--agents&lt;/code&gt; CLI → project → user → plugin .&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Precedence&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Managed settings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;--agents&lt;/code&gt; CLI flag&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Project &lt;code&gt;.claude/agents/&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;User &lt;code&gt;~/.claude/agents/&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Plugin &lt;code&gt;agents/&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two frontmatter fields control the tool pool. &lt;code&gt;tools&lt;/code&gt; is an allowlist — only the tools you list are reachable — and &lt;code&gt;disallowedTools&lt;/code&gt; is a denylist that removes tools the sub-agent would otherwise inherit . Both accept MCP server-level patterns: &lt;code&gt;mcp__&amp;lt;server&amp;gt;&lt;/code&gt; targets one server, &lt;code&gt;mcp__&amp;lt;server&amp;gt;__*&lt;/code&gt; matches all of its tools, and &lt;code&gt;mcp__*&lt;/code&gt; grants or revokes every MCP server in one entry . Pair these with &lt;code&gt;mcpServers&lt;/code&gt; when you want to add a server the parent lacks, and narrow &lt;code&gt;tools&lt;/code&gt; to keep the grant tight.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;description&lt;/code&gt; field is not cosmetic — it drives automatic delegation. Claude reads it to match incoming work to a sub-agent, so write explicit trigger keywords for the tasks you want routed here rather than a vague summary .&lt;/p&gt;

&lt;p&gt;Beyond those, the optional frontmatter is broad: &lt;code&gt;mcpServers&lt;/code&gt; (inline object or string reference), &lt;code&gt;tools&lt;/code&gt;, &lt;code&gt;disallowedTools&lt;/code&gt;, &lt;code&gt;model&lt;/code&gt; (use &lt;code&gt;inherit&lt;/code&gt; to mirror the parent), &lt;code&gt;permissionMode&lt;/code&gt;, &lt;code&gt;maxTurns&lt;/code&gt;, &lt;code&gt;hooks&lt;/code&gt;, &lt;code&gt;skills&lt;/code&gt;, &lt;code&gt;memory&lt;/code&gt;, &lt;code&gt;background&lt;/code&gt;, &lt;code&gt;isolation&lt;/code&gt;, and &lt;code&gt;color&lt;/code&gt; . Keep the surface small; the docs caution against making every task its own dedicated agent, since more options make delegation less accurate .&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this breaks: agent teams don't inherit a sub-agent's MCP assignments
&lt;/h2&gt;

&lt;p&gt;Agent teams are a different rung of the ladder, and per-agent inline MCP routing does not survive the jump. Enable the experimental layer by setting &lt;code&gt;CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1&lt;/code&gt; in &lt;code&gt;settings.json&lt;/code&gt; or the environment . One session becomes the immutable lead and spawns teammates; each teammate is a full, independent Claude Code session with its own context window, coordinating through a shared task list and a peer-to-peer mailbox — not an in-session delegate reporting back to the main agent .&lt;/p&gt;

&lt;p&gt;Here is the catch. When you reuse a &lt;code&gt;.claude/agents/&lt;/code&gt; definition as a teammate, its &lt;code&gt;tools&lt;/code&gt; allowlist and &lt;code&gt;model&lt;/code&gt; are honored — but its &lt;code&gt;mcpServers&lt;/code&gt; and &lt;code&gt;skills&lt;/code&gt; frontmatter are not applied. Teammates load MCP servers from project and user settings like any normal session, plus &lt;code&gt;CLAUDE.md&lt;/code&gt; context, and they do not inherit the lead's conversation history .&lt;/p&gt;

&lt;p&gt;The practical consequence: the inline &lt;code&gt;mcpServers&lt;/code&gt; field you wrote for the sub-agent path is a sub-agent and main-thread &lt;code&gt;--agent&lt;/code&gt; feature only. The full peer-team layer reads &lt;code&gt;.mcp.json&lt;/code&gt;, not individual agent frontmatter — a confirmed limit as of v2.1.219 (July 24, 2026) . If a teammate needs a private MCP server, put it in project or user scope, not the agent file.&lt;/p&gt;

&lt;p&gt;Other team-layer limits to plan around, current as of July 2026: no session resumption for in-process teammates, one team per session, no nested teams, a fixed lead, and no per-teammate permission modes at spawn . Sub-agents also became background-by-default in v2.1.198 (July 1, 2026), so behavior differs from earlier releases .&lt;/p&gt;

&lt;h2&gt;
  
  
  Allowlist wildcards and team coordination: what to try next
&lt;/h2&gt;

&lt;p&gt;To expose a single tool from a large MCP server without granting the rest, pair a narrow &lt;code&gt;tools&lt;/code&gt; allowlist with a wildcard denylist. The pattern &lt;code&gt;mcp__&amp;lt;server&amp;gt;__*&lt;/code&gt; in &lt;code&gt;disallowedTools&lt;/code&gt; removes a whole server family at once, so you can permit one specific tool and block everything else that server ships . This keeps least-privilege enforceable even as an upstream server adds tools you never reviewed.&lt;/p&gt;

&lt;p&gt;Deferred MCP tool loading is on by default: at startup only tool names and server instructions load, and full schemas resolve on demand. Set &lt;code&gt;ENABLE_TOOL_SEARCH=auto:N&lt;/code&gt; for threshold control; &lt;code&gt;tool_reference&lt;/code&gt; blocks require Sonnet 4.5, Haiku 4.5, or Opus 4.5 or later . This is why a sub-agent can carry many MCP tools without bloating context.&lt;/p&gt;

&lt;p&gt;If you do move to agent teams, coordination runs through two primitives instead of per-agent MCP wiring: a shared task list (pending / in-progress / completed with dependency tracking) and a mailbox for direct peer messaging. Teammates self-claim the next unblocked task rather than waiting on the lead .&lt;/p&gt;

&lt;p&gt;Anthropic's recommended ceiling is 3–5 teammates with roughly 5–6 tasks each, and because every teammate is a separate Claude instance, token cost scales roughly linearly with team size . The takeaway: for sequential or single-file work, a Markdown sub-agent with its own &lt;code&gt;mcpServers&lt;/code&gt; is the cheaper, stable path — reserve teams for genuinely parallel, multi-lens work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can a Claude Code sub-agent use MCP servers not listed in the parent's .mcp.json?
&lt;/h3&gt;

&lt;p&gt;Yes. The &lt;code&gt;mcpServers&lt;/code&gt; frontmatter field in a &lt;code&gt;.claude/agents/*.md&lt;/code&gt; file can define inline server configs — which connect when the sub-agent starts and disconnect when it finishes — or reference existing named connections by string to reuse a session's live connection . The parent session never loads those tool descriptions, so a sub-agent can hold servers the parent lacks entirely.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the difference between tools and disallowedTools in a sub-agent definition?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;tools&lt;/code&gt; is an allowlist — only the tools you list are available to the sub-agent, and everything else is withheld. &lt;code&gt;disallowedTools&lt;/code&gt; is a denylist — every inherited tool is available except the ones you name . Both accept MCP patterns such as &lt;code&gt;mcp__&amp;lt;server&amp;gt;&lt;/code&gt;, &lt;code&gt;mcp__&amp;lt;server&amp;gt;__*&lt;/code&gt;, and &lt;code&gt;mcp__*&lt;/code&gt;, so you can grant or remove an entire server family in a single entry.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do agent-team teammates get the mcpServers defined in a sub-agent file?
&lt;/h3&gt;

&lt;p&gt;No. When a sub-agent definition is reused as a teammate under &lt;code&gt;CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1&lt;/code&gt;, its &lt;code&gt;tools&lt;/code&gt; allowlist and &lt;code&gt;model&lt;/code&gt; are honored, but the &lt;code&gt;mcpServers&lt;/code&gt; and &lt;code&gt;skills&lt;/code&gt; frontmatter are ignored . Teammates load MCP servers from project and user settings exactly like a normal session, so inline per-agent MCP routing does not carry into a team.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does the description field control which tasks get routed to a sub-agent?
&lt;/h3&gt;

&lt;p&gt;Claude reads the &lt;code&gt;description&lt;/code&gt; field to match incoming work to the right sub-agent for automatic delegation . Pack it with explicit trigger keywords that name the tasks you want dispatched there — more specific phrasing produces more reliable routing. The docs also warn against making everything a dedicated agent, since more options make delegation less accurate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does an inline MCP server in a sub-agent affect the parent session's context window?
&lt;/h3&gt;

&lt;p&gt;No — that is the architectural point. In Anthropic's documented &lt;code&gt;browser-tester&lt;/code&gt; example, defining a Playwright server inline keeps its tool descriptions out of the parent's context while still equipping the sub-agent . This lets you attach a specialized protocol layer to one worker without adding token overhead to the main session.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>mcp</category>
      <category>subagents</category>
      <category>agentteams</category>
    </item>
    <item>
      <title>Claude can't grade its own loops — /goal uses Haiku instead</title>
      <dc:creator>Creeta</dc:creator>
      <pubDate>Sun, 02 Aug 2026 21:48:09 +0000</pubDate>
      <link>https://dev.to/creeta/claude-cant-grade-its-own-loops-goal-uses-haiku-instead-1p21</link>
      <guid>https://dev.to/creeta/claude-cant-grade-its-own-loops-goal-uses-haiku-instead-1p21</guid>
      <description>&lt;p&gt;Sometime in mid-2026, the interesting question about a Claude Code session stopped being "what do I type next" and became "who decides this is done." With &lt;code&gt;/goal&lt;/code&gt;, the answer is deliberately not the model doing the work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Haiku becomes the exit referee
&lt;/h2&gt;

&lt;p&gt;Claude can't be trusted to grade its own loop, so &lt;code&gt;/goal&lt;/code&gt; hands the exit decision to a separate, faster model — Haiku by default on the Claude API. The reason is empirical: LLM evaluators show a self-preference bias, scoring their own output higher than an independent judge would, and stronger models can exhibit stronger bias . A generator that also acts as its own stop signal is unreliable, so the verifier is separated from the maker.&lt;/p&gt;

&lt;p&gt;Mechanically, &lt;code&gt;/goal&lt;/code&gt; sets a completion condition and wraps a session-scoped, prompt-based Stop hook . After each turn, the Haiku evaluator checks your condition against the current transcript — not the main working model that just edited code . The two outcomes are simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;"No"&lt;/strong&gt; → the evaluator's reason is injected back to Claude as guidance for the next turn.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Yes"&lt;/strong&gt; → the goal is cleared and an achieved-condition entry is recorded.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This reframes the developer's job. As Boris Cherny, the Anthropic engineer who built Claude Code, put it in July 2026: "I no longer prompt Claude directly; my job is to write loops that prompt Claude and decide what to do next" . The skill shifts from wording instructions to writing a stop condition an independent referee can confirm.&lt;/p&gt;

&lt;h2&gt;
  
  
  The v2.1.139 prerequisite
&lt;/h2&gt;

&lt;p&gt;Before you can write that stop condition, check your installed version: &lt;code&gt;/goal&lt;/code&gt; requires Claude Code v2.1.139 or later, a build the changelog dates to May 11, 2026 . Earlier builds have no &lt;code&gt;/goal&lt;/code&gt; command at all, so run &lt;code&gt;claude --version&lt;/code&gt; and update first if the number is lower. The feature is available on all paid plans and the Anthropic API, and is also supported on Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry .&lt;/p&gt;

&lt;p&gt;Once a session is running, the &lt;code&gt;/goal&lt;/code&gt; overlay reports three live figures — elapsed time, turn count, and token count . Watch the turn count on a first run, then use it to calibrate the safety clause in your criterion, such as "or stop after 20 turns," so a stalled loop never burns tokens indefinitely.&lt;/p&gt;

&lt;h2&gt;
  
  
  From subjective to verifiable: phrasing a criterion Haiku can confirm
&lt;/h2&gt;

&lt;p&gt;A good &lt;code&gt;/goal&lt;/code&gt; condition names one measurable end state, states the evidence Haiku should read, adds any constraints, and bounds runtime — because the evaluator can only pass or fail against something objective. Conditions can run up to 4,000 characters, but length is not the point; a binary signal is. Write the check so a reader with no context could confirm it from the transcript alone.&lt;/p&gt;

&lt;p&gt;Objective conditions produce that binary evidence. Each of these gives Haiku a clean yes/no:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tests:&lt;/strong&gt; "all tests in &lt;code&gt;test/auth&lt;/code&gt; pass and lint exits 0."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance:&lt;/strong&gt; "Lighthouse performance score ≥ 90."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Working tree:&lt;/strong&gt; "&lt;code&gt;git status&lt;/code&gt; reports no untracked files."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Subjective conditions silently fail to terminate. "Make the code cleaner" or "improve readability" hand Haiku no objective signal to grade against, so it never returns a confident "yes" and the session runs straight to your turn cap — which is why the explicit "or stop after 20 turns" clause matters as a floor, not a goal. Anthropic's own guidance frames stop conditions as objective checks rather than aesthetic ones .&lt;/p&gt;

&lt;p&gt;For CI or headless runs, invoke the goal non-interactively with &lt;code&gt;claude -p&lt;/code&gt;. One gotcha: default output prints nothing until the loop completes, so add streaming flags to watch progress :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"/goal all tests in test/auth pass and lint exits 0, or stop after 20 turns"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output-format&lt;/span&gt; stream-json &lt;span class="nt"&gt;--verbose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without &lt;code&gt;--output-format stream-json --verbose&lt;/code&gt;, a long CI run looks hung even while Haiku is grading each turn. Pair the streaming flags with the objective condition and you get a loop that both reports its work and knows, unambiguously, when to stop.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the evaluator cannot inspect
&lt;/h2&gt;

&lt;p&gt;The Haiku grader behind &lt;code&gt;/goal&lt;/code&gt; reads only the transcript — it has no tool access, so it cannot execute commands, open files, or call APIs on its own . It judges your completion condition against whatever the working model has already surfaced in the conversation, and nothing more. A condition like "all tests pass" is meaningless to the evaluator unless the test output is sitting in the transcript as text.&lt;/p&gt;

&lt;p&gt;The practical implication is that the working model must make its evidence visible before the loop can close. Pipe test output inline, print build exit codes, run &lt;code&gt;git status&lt;/code&gt; and echo the result, or show an empty queue — the grader confirms the end state from that captured text, not from re-running anything . If the evidence never reaches the transcript, a genuinely finished task can loop indefinitely.&lt;/p&gt;

&lt;p&gt;When transcript evidence is not enough, agent-based Stop hooks — still experimental — offer a stronger check. They can spawn a verifier subagent with Read, Grep, and Glob access for up to 50 turns, letting the checker inspect the repository directly rather than trusting surfaced output . That independence costs more tokens, so reserve it for cases where a passive reader of the transcript would miss what actually matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  From one-shot to recurring: /schedule and proactive routines
&lt;/h2&gt;

&lt;p&gt;Once a single goal reliably reaches a verifiable end state, the next step is recurrence — running the same evaluated cycle on a clock or an event instead of a prompt. Claude Code splits this into two triggers. &lt;code&gt;/loop&lt;/code&gt; is session-scoped: it runs a prompt (or a built-in maintenance prompt, or &lt;code&gt;.claude/loop.md&lt;/code&gt;) at fixed minute-level intervals or dynamically chosen delays between one minute and one hour, and carries a seven-day expiry so a forgotten session stops on its own rather than running indefinitely . It needs an open session on your local machine. &lt;code&gt;/schedule&lt;/code&gt; is the cloud-hosted equivalent: execution continues on Anthropic infrastructure after you close your laptop, which is the right fit for CI polling, PR-review comment monitoring, or nightly maintenance passes .&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trigger&lt;/th&gt;
&lt;th&gt;Runs on&lt;/th&gt;
&lt;th&gt;Survives laptop close?&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/goal&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Local session&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Verifiable now&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/loop&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Local session&lt;/td&gt;
&lt;td&gt;No (7-day expiry)&lt;/td&gt;
&lt;td&gt;Interval polling while you work&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/schedule&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Anthropic cloud&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;CI, PR watch, nightly passes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For multi-agent work, dynamic workflows (v2.1.154+) let Claude write a JavaScript script that a background runtime executes, orchestrating up to 16 concurrent subagents and 1,000 per run while intermediate results live in script variables rather than the main context; a cost warning fires above 25 agents or 1.5 million projected tokens . Boris Cherny's "Steps of AI Adoption" ladder (July 17, 2026) frames why all of this compounds: &lt;code&gt;/goal&lt;/code&gt; alone lands you at Step 2, while Step 3 requires routines plus &lt;code&gt;/loop&lt;/code&gt;, &lt;code&gt;/goal&lt;/code&gt;, and subagents working together . The takeaway: pick the trigger by durability — &lt;code&gt;/goal&lt;/code&gt; when done is checkable now, &lt;code&gt;/schedule&lt;/code&gt; when the clock or an external system owns the trigger — and let a separate grader keep every recurrence honest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why does /goal use Haiku to grade the stop condition instead of the working model?
&lt;/h3&gt;

&lt;p&gt;Because a model grading its own output is unreliable. LLM evaluators exhibit a self-preference bias — they score their own responses higher than an independent judge would, and stronger models can show a stronger bias . To keep the exit check honest, &lt;code&gt;/goal&lt;/code&gt; routes verification to a separate fast evaluator — Haiku by default on the Claude API — that reads the transcript and answers whether the condition is met; a "no" returns its reasoning as guidance for the next turn . Separating the maker from the grader stops the working model from declaring itself done prematurely.&lt;/p&gt;

&lt;h3&gt;
  
  
  What version of Claude Code do I need for /goal?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;/goal&lt;/code&gt; requires Claude Code v2.1.139 or later; the changelog dates that build to May 11, 2026 . Earlier builds have no &lt;code&gt;/goal&lt;/code&gt; command. Check your installed version before writing conditions, since model defaults and command syntax can shift between releases .&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens if my /goal condition is subjective — like "make the code cleaner"?
&lt;/h3&gt;

&lt;p&gt;The Haiku evaluator has no objective signal to check against, so it can never confidently return "yes." The session typically runs until the turn cap is reached, burning tokens without a clean exit . Write conditions backed by binary evidence instead — "all tests in test/auth pass and lint is clean" or "Lighthouse ≥ 90" — and bound runtime with a clause such as "or stop after 20 turns" .&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between /goal, /loop, and /schedule?
&lt;/h3&gt;

&lt;p&gt;They solve different halves of a loop. &lt;code&gt;/goal&lt;/code&gt; owns the stop condition: keep working across turns until a measurable criterion is confirmed or a turn cap is hit. &lt;code&gt;/loop&lt;/code&gt; owns the trigger: repeat at fixed or dynamically chosen intervals in your open session on your machine, with a seven-day expiry so forgotten loops eventually stop . &lt;code&gt;/schedule&lt;/code&gt; is like &lt;code&gt;/loop&lt;/code&gt; but cloud-hosted on Anthropic infrastructure, so execution continues after you close your laptop .&lt;/p&gt;

&lt;h3&gt;
  
  
  Can /goal be used in non-interactive CI pipelines?
&lt;/h3&gt;

&lt;p&gt;Yes, via &lt;code&gt;claude -p&lt;/code&gt;. By default the run may print nothing until it completes, which looks like a hang in a pipeline log. Pass &lt;code&gt;--output-format stream-json --verbose&lt;/code&gt; to stream per-turn output as it happens .&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>loopengineering</category>
      <category>haiku</category>
      <category>goalcommand</category>
    </item>
    <item>
      <title>Claude Code skips bash guards in agentic mode</title>
      <dc:creator>Creeta</dc:creator>
      <pubDate>Sun, 02 Aug 2026 15:50:01 +0000</pubDate>
      <link>https://dev.to/creeta/claude-code-skips-bash-guards-in-agentic-mode-42pm</link>
      <guid>https://dev.to/creeta/claude-code-skips-bash-guards-in-agentic-mode-42pm</guid>
      <description>&lt;p&gt;Security docs can promise a guardrail that the runtime quietly disables. That is exactly the gap at the heart of running Claude Code as a live trading operator: the "dangerous Bash pattern" filter you read about in the docs does not run in the mode most agentic deployments actually use.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the bash filter does — and what turns it off
&lt;/h2&gt;

&lt;p&gt;The dangerous-Bash pattern filter is a string-matching layer that inspects shell commands before execution and rejects known-risky patterns. Richard Atkinson's &lt;a href="https://github.com/RichardAtCT/claude-code-telegram" rel="noopener noreferrer"&gt;claude-code-telegram&lt;/a&gt; bridge documents this check in its &lt;a href="https://raw.githubusercontent.com/RichardAtCT/claude-code-telegram/main/SECURITY.md" rel="noopener noreferrer"&gt;security reference&lt;/a&gt; alongside traversal checks, secret-file blocking, and rate limits. But the bridge's own &lt;a href="https://raw.githubusercontent.com/RichardAtCT/claude-code-telegram/main/docs/tools.md" rel="noopener noreferrer"&gt;tools reference&lt;/a&gt; adds the caveat the title names: the pattern layer is "classic mode only" and is not active in agentic mode.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The dangerous-Bash-pattern layer is classic mode only," — claude-code-telegram tools reference (source: &lt;a href="https://raw.githubusercontent.com/RichardAtCT/claude-code-telegram/main/docs/tools.md" rel="noopener noreferrer"&gt;docs/tools.md&lt;/a&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In an agentic deployment, then, Bash runs without that interception. Your remaining barriers are OS sandboxing, Claude Code's permission rules, and the order-gate code you write yourself — nothing about the bridge stops a shell call from reaching a broker on its own. The platform-level control that replaces the string filter is the Agent SDK's evaluation order, documented in Claude Code's &lt;a href="https://code.claude.com/docs/en/permissions" rel="noopener noreferrer"&gt;permissions reference&lt;/a&gt;: hooks → deny rules → permission mode → allow rules → &lt;code&gt;canUseTool&lt;/code&gt;. Because hooks run first, a &lt;code&gt;PreToolUse&lt;/code&gt; hook is the practical replacement — it can block a shell command before it executes.&lt;/p&gt;

&lt;p&gt;The corollary is blunt: an agent enforces only what is written down. A 14-session Bybit futures build published May 2026 — 961 tool calls across 59 files — recorded Claude self-halting in Session 5 when it detected &lt;code&gt;BYBIT_TESTNET=false&lt;/code&gt; . It refused to trade — but only because that constraint lived in &lt;code&gt;CLAUDE.md&lt;/code&gt;. Nothing intrinsic caught it.&lt;/p&gt;

&lt;p&gt;The snippet below is illustrative (not executed — it needs an authenticated Claude Code login) and shows the shape of the problem: launching with &lt;code&gt;bypassPermissions&lt;/code&gt; and a narrow &lt;code&gt;allowedTools&lt;/code&gt; is not a safety boundary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;

&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Use Bash to run exactly this command and report the output: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;python3 -c &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;print(&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;BASH_GUARD_SKIPPED&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-p&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--bare&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--permission-mode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bypassPermissions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--allowedTools=Bash(echo *)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;capture_output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TimeoutExpired&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Claude Code timed out before demonstrating whether Bash(echo *) was enforced.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;124&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;returncode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Telegram: Channels or open bridge?
&lt;/h2&gt;

&lt;p&gt;Two paths connect a running Claude Code session to Telegram, and they trade convenience for control. The official route is Claude Code Channels, a plugin Anthropic shipped on March 20, 2026 that lets a local session receive and reply to Telegram and Discord messages. It needs Claude Code v2.1.80 or newer. Setup is short: create a bot through BotFather, install the Channels plugin, store the token in &lt;code&gt;.claude/channels/telegram/.env&lt;/code&gt;, then relaunch with &lt;code&gt;claude --channels plugin:telegram@claude-plugins-official&lt;/code&gt;. During the research preview, &lt;code&gt;--channels&lt;/code&gt; only accepts plugins from that one allowlist. Anthropic's listing page reported 100,332 installs at the time of research.&lt;/p&gt;

&lt;p&gt;The self-hosted alternative is Richard Atkinson's &lt;a href="https://github.com/RichardAtCT/claude-code-telegram" rel="noopener noreferrer"&gt;claude-code-telegram&lt;/a&gt; — the most complete community control plane found. Its &lt;code&gt;main&lt;/code&gt; branch reports version 1.6.0, Python ≥3.11, python-telegram-bot ^22.6, and claude-agent-sdk ^0.1.39, and adds per-user session persistence, SQLite audit logs, allowlist auth, webhook HMAC, and directory sandboxing. The README install snippet still recommends pinning the v1.3.0 tag until &lt;code&gt;main&lt;/code&gt; stabilizes, so choose a release deliberately before deploying.&lt;/p&gt;

&lt;p&gt;Either way, the transport layer is &lt;code&gt;python-telegram-bot&lt;/code&gt;, whose v22.7 (released March 16, 2026) supports Bot API 9.6, async webhooks and polling, and inline keyboards for one-tap approve/cancel flows. The HumbledTrader IBKR build wraps every Telegram call in try/except so a failed notification can never abort trade logic [HumbledTrader, 2026-05].&lt;/p&gt;

&lt;p&gt;Treat Telegram as a console, not a durable authorization layer. Callback data is ephemeral, delivery is best-effort, and the preview allowlist is &lt;code&gt;claude-plugins-official&lt;/code&gt; only. Plan for a Telegram outage from day one — keep order state and confirmations server-side.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Telegram to fill: Robinhood, Alpaca, or CCXT
&lt;/h2&gt;

&lt;p&gt;The order-entry layer is where three routes diverge: a broker-native MCP server, a paper-trading REST API, or a crypto exchange SDK. Robinhood's Agentic Trading, launched May 27, 2026 as an equities-only beta, is the lowest-wiring path — you add it in one command and skip custom broker code entirely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add robinhood-trading &lt;span class="nt"&gt;--transport&lt;/span&gt; http https://agent.robinhood.com/mcp/trading
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent gets a dedicated agentic account with real-time P&amp;amp;L and disconnect/pause controls, and can place trades only inside that account [Robinhood support]. Read Robinhood's own warning carefully: if you instruct the agent to act without approval, trades may execute without confirmation, and you remain responsible.&lt;/p&gt;

&lt;p&gt;Alpaca is the safest place to soak a strategy. Paper trading is free, defaults to a $100k paper account, and lives at a separate endpoint, &lt;code&gt;https://paper-api.alpaca.markets&lt;/code&gt; [Alpaca docs]. It supports market, limit, stop, bracket, OCO, and OTO orders keyed by &lt;code&gt;client_order_id&lt;/code&gt;. The catch: it explicitly does not model slippage, queue position, latency, or regulatory fees, so paper results overstate live performance.&lt;/p&gt;

&lt;p&gt;For crypto futures, builders reach for CCXT or a native SDK such as Bybit's. Generate API keys with withdrawal permissions disabled, always. And note that &lt;code&gt;ErrCode 10001&lt;/code&gt; (Hedge vs One-way mode mismatch) surfaces only at order submission, not at connection time — one build diary hit it mid-run, so validate on testnet first [dev.to build diary].&lt;/p&gt;

&lt;p&gt;IBKR is the most capable and the most operationally demanding. Its Client Portal Web API constraints matter for any agent loop:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Constraint&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Brokerage session&lt;/td&gt;
&lt;td&gt;One active per user; ~6-minute auth timeout without &lt;code&gt;/tickle&lt;/code&gt;; up to 24-hour lifetime with midnight reset&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Global rate cap&lt;/td&gt;
&lt;td&gt;10 req/s; &lt;code&gt;/iserver/account/orders&lt;/code&gt; GET at 1 per 5s; 15-minute penalty box for violators&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TWS paper port&lt;/td&gt;
&lt;td&gt;7497&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IB Gateway ports&lt;/td&gt;
&lt;td&gt;4002 (paper) / 4001 (live)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Pick by tolerance for wiring: Robinhood for the least custom code, Alpaca for free paper soak, CCXT/IBKR for control at the cost of session and pacing discipline [HumbledTrader, 2026-05].&lt;/p&gt;

&lt;h2&gt;
  
  
  How to compensate: kill button, drawdown cap, idempotency
&lt;/h2&gt;

&lt;p&gt;With the dangerous-Bash-pattern layer inactive in agentic mode, every brake has to live in config the agent reads at startup — not in conversation. The reference builds converge on a small set of externalized guardrails: a red kill flag that issues a global cancel-and-flatten, a circuit breaker that cuts position size at ~2% daily loss, a force-flatten at ~3% daily loss or 10% drawdown, and a lock file that requires manual resume before trading restarts .&lt;/p&gt;

&lt;p&gt;Write the numeric limits down where the agent must honor them — a &lt;code&gt;rules.json&lt;/code&gt; or &lt;code&gt;CLAUDE.md&lt;/code&gt;. The IBKR reference build caps max concurrent positions at 5, risk-per-trade at 1%, and max position size at 10%, enforces a &lt;code&gt;MAX_TRADES_PER_DAY&lt;/code&gt; limit, and adds a startup guard that refuses to boot when the &lt;code&gt;PAPER_TRADING&lt;/code&gt; flag disagrees with the connected port number . The mechanism works: in a 14-session build, Claude self-halted in Session 5 — refusing to trade after detecting &lt;code&gt;BYBIT_TESTNET=false&lt;/code&gt; — but only because that constraint was written into CLAUDE.md .&lt;/p&gt;

&lt;p&gt;Authorization has to be durable. Use broker-generated order IDs and idempotency keys in every submission, and store risk-decision logs and broker confirmations server-side — Telegram callback data alone is not durable authorization, since a tapped button leaves no auditable, replay-safe record.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"If you ask the agent to act without requiring your approval, trades may execute without additional confirmation, and you remain responsible for them," — Robinhood, Agentic Trading documentation (source: &lt;a href="https://robinhood.com/us/en/newsroom/robinhood-is-now-open-to-agents/" rel="noopener noreferrer"&gt;Robinhood&lt;/a&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On the platform side, &lt;code&gt;PreToolUse&lt;/code&gt; hooks are the Agent SDK's closest analog to the missing Bash filter: the SDK evaluates hooks first, then deny rules, permission mode, and allow rules, so a hook can intercept a Bash call, log the intended command with a timestamp before execution, and gate "place order," "modify order," and "cancel all" through an explicit approval check in code rather than conversational consent . The snippet below is illustrative — not executed — and shows why the filter can be bypassed at all:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;

&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Use Bash to run exactly this command and report the output: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;python3 -c &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;print(&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;BASH_GUARD_SKIPPED&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-p&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--bare&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--permission-mode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bypassPermissions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--allowedTools=Bash(echo *)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;capture_output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TimeoutExpired&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Claude Code timed out before demonstrating whether Bash(echo *) was enforced.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;124&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;returncode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The takeaway: treat the agent as untrusted. Externalize kill switch, drawdown caps, and idempotent order gates into config and deterministic hooks — the agent only applies brakes that are written down.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is the dangerous-Bash filter disabled in all agentic deployments, or is this specific to claude-code-telegram?
&lt;/h3&gt;

&lt;p&gt;This is documented behavior in the &lt;code&gt;claude-code-telegram&lt;/code&gt; community bridge specifically: its tools doc states the dangerous-Bash-pattern layer is "classic mode only" and is not active in agentic mode . That pattern filter is one layer. It is independent of Anthropic's own controls: the Claude Agent SDK evaluates hooks, then deny rules, permission mode, allow rules, then &lt;code&gt;canUseTool&lt;/code&gt;, and &lt;code&gt;PreToolUse&lt;/code&gt; can block dangerous operations regardless of which bridge you run . Treat them as two separate layers — losing the bridge's filter does not remove SDK-level bash permissions and hooks, and neither substitutes for broker-side controls.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between Claude Code Channels and the claude-code-telegram community bridge?
&lt;/h3&gt;

&lt;p&gt;Channels is Anthropic's official plugin, shipped March 20, 2026, requiring Claude Code v2.1.80+ and, during the research preview, accepting only plugins from the &lt;code&gt;claude-plugins-official&lt;/code&gt; allowlist via a roughly six-step setup . The &lt;code&gt;claude-code-telegram&lt;/code&gt; bridge is self-hosted — its &lt;code&gt;main&lt;/code&gt; &lt;code&gt;pyproject.toml&lt;/code&gt; reports version 1.6.0  — and adds audit logs, HMAC/Bearer webhook auth, directory sandboxing, and per-user session persistence . Because the README install snippet recommends tag v1.3.0 while &lt;code&gt;main&lt;/code&gt; is at 1.6.0, pin to v1.3.0 until you have vetted a specific release.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Robinhood's agentic account support crypto trading yet?
&lt;/h3&gt;

&lt;p&gt;Not yet. As of the May 27, 2026 launch, Robinhood's Agentic Trading is equities-only beta, running through AI-native MCP servers with dedicated agentic accounts and disconnect/pause controls . A July 1, 2026 announcement confirmed that US agentic crypto accounts are rolling out soon, but no firm date was given . If you need crypto today, wire an exchange directly through CCXT or a native SDK instead of waiting on the Robinhood path.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens if Telegram goes down while a position is open?
&lt;/h3&gt;

&lt;p&gt;Nothing should break, because Telegram is a console, not a safety system. Safety-critical state must live server-side with idempotency keys, order IDs, timestamps, and broker confirmations — callback data alone is not durable authorization. A time-based force-close (for example, 3:51 ET) and a lock file that survives a restart let the agent halt safely without chat connectivity, and the reference IBKR build wraps every Telegram call in try/except so a notification failure can never interrupt trade logic . Design so that losing the chat layer degrades alerts, never risk enforcement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use IBKR instead of Robinhood or Alpaca?
&lt;/h3&gt;

&lt;p&gt;Yes, but it is operationally heavier. In the local route the bot connects to TWS on port 7497 for paper, while production guides insist on headless IB Gateway (ports 4002 paper / 4001 live) . The Client Portal Web API adds more friction: sessions time out after roughly 6 minutes without a &lt;code&gt;/tickle&lt;/code&gt;, global pacing is 10 req/s, &lt;code&gt;/iserver/account/orders&lt;/code&gt; GET is capped at 1 per 5 seconds, and violators land in a 15-minute penalty box . IBKR suits serious production use more than quick iteration; for fast prototyping, Alpaca's free paper account or Robinhood's zero-wiring MCP route is lighter.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>telegram</category>
      <category>bashguard</category>
      <category>brokerapi</category>
    </item>
  </channel>
</rss>
