<?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: anthony papoti</title>
    <description>The latest articles on DEV Community by anthony papoti (@anthony_builds).</description>
    <link>https://dev.to/anthony_builds</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%2F4085352%2Feb14361d-b624-43c3-8ab6-f19dbde36eb7.jpg</url>
      <title>DEV Community: anthony papoti</title>
      <link>https://dev.to/anthony_builds</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anthony_builds"/>
    <language>en</language>
    <item>
      <title>The Cloudflare KV race that broke our MCP OAuth at random (and how we killed it)</title>
      <dc:creator>anthony papoti</dc:creator>
      <pubDate>Tue, 08 Sep 2026 14:35:38 +0000</pubDate>
      <link>https://dev.to/anthony_builds/the-cloudflare-kv-race-that-broke-our-mcp-oauth-at-random-and-how-we-killed-it-a1g</link>
      <guid>https://dev.to/anthony_builds/the-cloudflare-kv-race-that-broke-our-mcp-oauth-at-random-and-how-we-killed-it-a1g</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published on the Katto blog: &lt;a href="https://katto.tech/blog/mcp-oauth-cloudflare-kv-race" rel="noopener noreferrer"&gt;https://katto.tech/blog/mcp-oauth-cloudflare-kv-race&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Katto is an AI video clipper. You give it a long video, it finds the best moments and cuts them into captioned vertical clips, and you can drive the whole thing from an AI agent through our official hosted MCP server at mcp.katto.tech. I build Katto on my own, in public, so here is a bug that cost me an evening and the fix that actually ended it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The symptom
&lt;/h2&gt;

&lt;p&gt;Connecting Katto to Claude over MCP sometimes failed with "Authorization expired or was not approved. Please start over." The confusing part: the consent page had already shown "Connecting your MCP client...", which only happens after the user approves and the key is minted. So the approval clearly worked, yet the final step claimed it had not. And it was intermittent. Some connections went through cleanly, others died on the same account minutes apart.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the flow is built, and why
&lt;/h2&gt;

&lt;p&gt;The security rule for our hosted MCP is that the API key must never travel through the browser. So the OAuth handoff is server to server:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The worker's &lt;code&gt;/authorize&lt;/code&gt; stores the OAuth request in Cloudflare KV under a transaction id.&lt;/li&gt;
&lt;li&gt;The consent page on katto.tech authenticates the user, mints a scoped key, and POSTs it to the worker's &lt;code&gt;/oauth/deposit&lt;/code&gt; over an HMAC-signed channel.&lt;/li&gt;
&lt;li&gt;The browser is then bounced to the worker's &lt;code&gt;/oauth/callback&lt;/code&gt;, which reads that deposit back and completes the grant.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The false lead
&lt;/h2&gt;

&lt;p&gt;My first guess was an HMAC secret mismatch between the app and the worker. It was not. A bad signature makes &lt;code&gt;/oauth/deposit&lt;/code&gt; reject with a visible error, and the user would have seen that. Instead they saw "Connecting...", which means the deposit POST returned 200. The key was minted and deposited fine. The failure came one hop later, at the callback.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real cause: eventually consistent KV
&lt;/h2&gt;

&lt;p&gt;Cloudflare Workers KV is eventually consistent. &lt;code&gt;/oauth/deposit&lt;/code&gt; writes the deposit on whichever edge location served that request. The browser is then meta-refreshed, with zero delay, to &lt;code&gt;/oauth/callback&lt;/code&gt;, which is a separate request that can land on a different edge location and read that key before it has propagated. It reads null, and the callback declares the transaction dead. When the two requests happen to hit the same location, it works. When they do not, you get "Authorization expired." It is a read-after-write across two requests, which KV explicitly does not guarantee.&lt;/p&gt;

&lt;p&gt;That is why it looked random. It was random, in the sense that it depended on which edge served each of the two requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  The mitigations that reduced it but did not fix it
&lt;/h2&gt;

&lt;p&gt;The first patches were the obvious ones: retry the callback read a few times (ten attempts, 500ms apart) and add a one second delay to the meta-refresh so KV gets a head start. That cut the failure rate sharply. It did not remove it. As long as the callback reads a key that another request just wrote, propagation can always take longer than your retry budget. Those were band-aids on a design flaw.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix: stop reading a fresh key in a second request
&lt;/h2&gt;

&lt;p&gt;The real fix was to remove the cross-request read entirely. The &lt;code&gt;/oauth/deposit&lt;/code&gt; request already holds everything it needs: the OAuth request (written at &lt;code&gt;/authorize&lt;/code&gt;, long since propagated) and the freshly minted key, in hand, in memory. So it completes the grant right there and returns the final redirect URL. The browser goes straight to the client with the authorization code. It never round-trips through the callback to re-read a key that was written moments ago.&lt;/p&gt;

&lt;p&gt;We kept the old callback as a fallback and shipped it backward compatible: the consent page uses the returned redirect URL when the worker provides one, and otherwise falls back to the callback, so an old and a new deploy can never break each other during a rollout. After the change, fresh connections stopped failing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The lesson
&lt;/h2&gt;

&lt;p&gt;If a value has to be available to the very next step, do not write it to eventually consistent storage and read it back in a separate request. Complete the work in the request that already holds the data, or use a strongly consistent store. Retries and delays hide the race; removing the cross-request read is what ends it. We found this by dogfooding our own MCP the way a reviewer would, before a reviewer did.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>oauth</category>
      <category>serverless</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Connect Katto to Claude in 60 Seconds (Official MCP Server)</title>
      <dc:creator>anthony papoti</dc:creator>
      <pubDate>Sat, 05 Sep 2026 08:33:02 +0000</pubDate>
      <link>https://dev.to/anthony_builds/connect-katto-to-claude-in-60-seconds-official-mcp-server-2ihc</link>
      <guid>https://dev.to/anthony_builds/connect-katto-to-claude-in-60-seconds-official-mcp-server-2ihc</guid>
      <description>&lt;p&gt;Katto is an AI video clipper, and it ships an &lt;strong&gt;official MCP server&lt;/strong&gt;. That means you don't have to open the app to use it: connect it to Claude once, then ask in plain English — &lt;em&gt;"clip the best moments of this YouTube video"&lt;/em&gt; — and Katto downloads, transcribes, scores and renders vertical captioned clips, then hands them back ranked by a virality score.&lt;/p&gt;

&lt;p&gt;No install, no API key pasted into a config file. Here is the whole thing, start to finish.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://katto.tech/mcp" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F94natinpd57yg6ymvg5m.png" alt="Katto MCP running inside Claude: a completed job with the top clips ranked by score" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;▶ &lt;a href="https://katto.tech/mcp" rel="noopener noreferrer"&gt;Watch the 60-second demo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect in 60 seconds
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;In Claude, open &lt;strong&gt;Settings → Connectors&lt;/strong&gt; and choose &lt;strong&gt;Add connector&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Paste the hosted endpoint: &lt;code&gt;https://mcp.katto.tech/mcp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Allow&lt;/strong&gt; to sign in with your Katto account (OAuth). That's it — no key to copy, nothing stored on disk.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Prefer a local setup, or using Cursor, VS Code, Windsurf or ChatGPT? The &lt;a href="https://katto.tech/mcp" rel="noopener noreferrer"&gt;per-client guides&lt;/a&gt; cover each one, including the &lt;code&gt;npx&lt;/code&gt; command and the API-key header if you'd rather not use OAuth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then just ask
&lt;/h2&gt;

&lt;p&gt;Once it's connected, you talk to Katto in normal language. A first prompt to try:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Clip the best 3 moments of https://www.youtube.com/watch?v=YOUR_VIDEO
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude calls Katto, you get back a job id, and you can poll it until the clips are ready:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What's the status of that job? Show me the clips with their scores.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each clip comes with its MP4 url, an SRT caption file, a title, and a 0–100 virality score, ranked highest first. When a clip's &lt;code&gt;hd&lt;/code&gt; field turns true, its 1080p render is final; the job-level &lt;code&gt;hd_ready&lt;/code&gt; flag tells an agent when every clip is done, so it never caches a link that's about to change.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you can do (16 tools)
&lt;/h2&gt;

&lt;p&gt;The connector is not a single "make clips" button — it exposes the whole pipeline as tools an agent can compose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Create &amp;amp; control jobs&lt;/strong&gt; — submit a video URL, list your jobs, cancel a running job (and get the video credit refunded instantly).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read the output&lt;/strong&gt; — job status and progress, the finished clips, the timestamped transcript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Re-render, free&lt;/strong&gt; — re-render a clip with a different reframe layout or caption style, or dub it into any of 8 languages, without spending quota.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Discover &amp;amp; configure&lt;/strong&gt; — list the supported sources, the clip-length buckets, and the caption-style presets, plus your plan, quota and saved brand kit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  It works from your own code, too
&lt;/h2&gt;

&lt;p&gt;The MCP server is a thin layer over Katto's &lt;a href="https://katto.tech/docs/api" rel="noopener noreferrer"&gt;public REST API&lt;/a&gt; — same endpoints, same responses. So whether you drive it from Claude, from Cursor, or from a script with a &lt;code&gt;sk_live_&lt;/code&gt; key, you get the same jobs, the same scored clips, idempotent retries and signed webhooks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Connect Katto to Claude at &lt;code&gt;https://mcp.katto.tech/mcp&lt;/code&gt;, read the &lt;a href="https://katto.tech/mcp" rel="noopener noreferrer"&gt;MCP overview&lt;/a&gt; and the &lt;a href="https://katto.tech/docs/api" rel="noopener noreferrer"&gt;API docs&lt;/a&gt;, or &lt;a href="https://katto.tech/signup" rel="noopener noreferrer"&gt;start with a free account&lt;/a&gt;. If you kick the tires and something surprises you, tell us — we read every reply.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>api</category>
      <category>marketing</category>
    </item>
    <item>
      <title>I shipped a second render engine to make preview match export. It made things worse.</title>
      <dc:creator>anthony papoti</dc:creator>
      <pubDate>Thu, 03 Sep 2026 17:04:58 +0000</pubDate>
      <link>https://dev.to/anthony_builds/i-shipped-a-second-render-engine-to-make-preview-match-export-it-made-things-worse-23p0</link>
      <guid>https://dev.to/anthony_builds/i-shipped-a-second-render-engine-to-make-preview-match-export-it-made-things-worse-23p0</guid>
      <description>&lt;p&gt;Katto is an AI video clipper. You drop in a long video, it cuts the good moments into vertical shorts, and an editor lets you fix the framing, captions and layout before you export. I build it on my own, in public. This is the story of a mistake I made in that editor, and what fixing it taught me about "what you see is what you get."&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem I was solving
&lt;/h2&gt;

&lt;p&gt;A clip editor lives or dies on one promise. What you see in the preview is exactly what you download. If the caption sits a pixel higher in the export, if the crop drifts, if a color is off, the user stops trusting the tool. And trust is the whole product.&lt;/p&gt;

&lt;p&gt;My preview is a React composition rendered in the browser. My exports were rendered on the server with FFmpeg. Two different renderers drawing the same clip. They drifted, as you would expect. Caption fonts, emoji rendering, the exact crop on a split screen. The classic "preview does not match export."&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix that felt right (and wasn't)
&lt;/h2&gt;

&lt;p&gt;So I did the obvious thing. I made the same React composition that draws the browser preview also render the export on the server, through a headless Chromium (Remotion). One component, one source of truth. Preview equals export, guaranteed.&lt;/p&gt;

&lt;p&gt;This is not a knock on Remotion. It is excellent at what it is built for. The mistake was mine. I bolted it on as a second export engine next to an existing FFmpeg pipeline.&lt;/p&gt;

&lt;p&gt;My initial clips, the ones the AI generates before you ever open the editor, were still rendered by FFmpeg. It is fast, it is proven, it runs the whole pipeline. I was not going to rip that out.&lt;/p&gt;

&lt;p&gt;So now I had two engines producing files. FFmpeg for the generated clip, Chromium and Remotion for the edited re-export. The exact divergence I set out to kill was now worse. The clip you saw in your results list (FFmpeg) and the same clip re-exported after a tiny edit (Remotion) could come out subtly different. I had turned one renderer into two and called it parity.&lt;/p&gt;

&lt;p&gt;On top of that, the Chromium render was slow. Three to four minutes per clip, against roughly 30 seconds for FFmpeg. And it failed now and then. When it failed, it silently fell back to FFmpeg and handed the user a file with their edits quietly dropped. The worst possible failure. Wrong, and quiet.&lt;/p&gt;

&lt;h2&gt;
  
  
  The realization
&lt;/h2&gt;

&lt;p&gt;"Preview equals export" is not achieved by making the preview be the renderer. It is achieved by having one source of truth for the render, and letting the preview be a faithful approximation of it.&lt;/p&gt;

&lt;p&gt;A browser Player is a great preview. It should never have become a second export engine. The moment it did, I had two implementations of the same geometry, drifting on every change.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I did
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;FFmpeg is the one engine that produces files.&lt;/strong&gt; Generation and re-export run through the same pipeline. Exports for a typical sub-60s clip dropped to about 30 seconds (I measured 32s), down from the three to four minutes the Chromium path took.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The browser Player is back to what it is good at,&lt;/strong&gt; the interactive preview. It renders nothing that ships.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;I ported the flourishes only the browser could do&lt;/strong&gt; into FFmpeg, the per-word color-cycling captions and the stacked layout's adjustable split ratio, so the fast path covers the common cases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The silent fallback is dead.&lt;/strong&gt; If a render cannot be produced faithfully, the user gets a visible error, never a quietly wrong file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;One coordinate set, the last piece I am finishing.&lt;/strong&gt; When you drag a crop in the preview, those exact rectangles should be what FFmpeg uses, not a second geometry the server recomputes on its own. This is the subtle one. Even after unifying the engine, the preview computed crop rects one way and the export computed them another. I am closing it now, making FFmpeg consume the exact rects from the editor state, because the lesson is the same one level down. Any second computation of the same thing is a source of drift.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The lessons
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"Make the preview the renderer" is seductive and usually wrong.&lt;/strong&gt; You end up with two renderers the day you have any other render path. One source of truth for the output. The preview approximates it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A second engine "for parity" becomes a hidden third source of divergence.&lt;/strong&gt; If two code paths compute the same geometry or format, they will drift. The only question is when.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Silent fallbacks are the cardinal sin.&lt;/strong&gt; A slightly wrong file with no warning costs more trust than an honest error. Fail loud.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Verify the artifact, not the logs.&lt;/strong&gt; My logs said "rendered stacked layout." I only found the real bug by pulling the actual exported MP4 off storage and looking at a frame. The pixels are the truth.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I am a solo founder shipping fast, in public. This one cost me a well-intentioned detour. If you are building any editor with a preview and an export, the shortest path to trust is boring. One renderer, honest errors, and check the frames.&lt;/p&gt;

&lt;p&gt;Katto is at &lt;a href="https://katto.tech" rel="noopener noreferrer"&gt;katto.tech&lt;/a&gt;. If you build video tooling, I would genuinely love to compare notes on preview and export parity.&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>ffmpeg</category>
      <category>webdev</category>
      <category>marketing</category>
    </item>
    <item>
      <title>You can now clip video from inside your AI agent: the state of MCP for video in 2026</title>
      <dc:creator>anthony papoti</dc:creator>
      <pubDate>Sat, 22 Aug 2026 07:03:41 +0000</pubDate>
      <link>https://dev.to/anthony_builds/you-can-now-clip-video-from-inside-your-ai-agent-the-state-of-mcp-for-video-in-2026-2jek</link>
      <guid>https://dev.to/anthony_builds/you-can-now-clip-video-from-inside-your-ai-agent-the-state-of-mcp-for-video-in-2026-2jek</guid>
      <description>&lt;p&gt;Six months ago, "AI video editing" meant opening a web app, pasting a link, and clicking around. Today you can stay in the tool you already talk to (Claude, Cursor, ChatGPT) and just say: "clip the best moments from this podcast and reframe them for TikTok." The clips come back. No tab-switching, no dashboard.&lt;/p&gt;

&lt;p&gt;The thing that made this possible is the &lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt;. If you have heard the acronym but tuned out, here is the one-line version: MCP is a standard way for an AI agent to call a real tool. The agent does not guess how your API works. It reads a list of typed tools, picks one, fills in the arguments, and gets structured data back.&lt;/p&gt;

&lt;p&gt;I have been building a video clipper (&lt;a href="https://katto.tech" rel="noopener noreferrer"&gt;Katto&lt;/a&gt;) with an MCP server as a first-class surface, not an afterthought, so I went and looked at where the whole clipping category actually stands on this. Here is what I found, honestly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why video clipping is a near-perfect MCP use case
&lt;/h2&gt;

&lt;p&gt;Most SaaS features are awkward to expose to an agent because they need a lot of back-and-forth UI. Clipping is the opposite. The whole job is: &lt;strong&gt;input a long video, get short clips out.&lt;/strong&gt; That maps cleanly to a handful of tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create a clip job from a URL or an upload&lt;/li&gt;
&lt;li&gt;poll it&lt;/li&gt;
&lt;li&gt;fetch the finished clips (the MP4s, the captions, the virality score)&lt;/li&gt;
&lt;li&gt;optionally re-render one with a different layout, or dub it into another language&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is a workflow an agent can drive end to end. You give it a YouTube link in a sentence, it hands you back five captioned vertical clips.&lt;/p&gt;

&lt;h2&gt;
  
  
  The landscape (as of August 2026)
&lt;/h2&gt;

&lt;p&gt;MCP is becoming surprisingly common among clipping tools. OpusClip ships a hosted server with OAuth. Reap and Submagic expose MCP endpoints. Even smaller players like Whipscribe (more transcription-and-clip-search focused) run a public MCP with a local install option.&lt;/p&gt;

&lt;p&gt;So I do not think "we have an MCP server" is much of a differentiator anymore, at least for tools targeting developers and agent workflows. What still varies a lot is &lt;em&gt;how&lt;/em&gt; it is done. Here is the factual picture, checked against each vendor's own docs:&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;Hosted endpoint&lt;/th&gt;
&lt;th&gt;Auth&lt;/th&gt;
&lt;th&gt;Local option&lt;/th&gt;
&lt;th&gt;MCP access tier&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OpusClip&lt;/td&gt;
&lt;td&gt;mcp.opus.pro/mcp&lt;/td&gt;
&lt;td&gt;OAuth, no API key&lt;/td&gt;
&lt;td&gt;hosted (mcp-remote for stdio)&lt;/td&gt;
&lt;td&gt;free trial, then Pro (metered per-minute)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reap&lt;/td&gt;
&lt;td&gt;mcp.reap.video/mcp&lt;/td&gt;
&lt;td&gt;OAuth, workspace-scoped&lt;/td&gt;
&lt;td&gt;hosted (mcp-remote for stdio)&lt;/td&gt;
&lt;td&gt;paid plan with API access (from ~$9.99/mo)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Submagic&lt;/td&gt;
&lt;td&gt;api.submagic.co/mcp&lt;/td&gt;
&lt;td&gt;Bearer key&lt;/td&gt;
&lt;td&gt;via mcp-remote bridge&lt;/td&gt;
&lt;td&gt;shares REST API credits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Whipscribe&lt;/td&gt;
&lt;td&gt;whipscribe.com/mcp&lt;/td&gt;
&lt;td&gt;Bearer key (guest tier allowed)&lt;/td&gt;
&lt;td&gt;open-source stdio client&lt;/td&gt;
&lt;td&gt;free tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Katto&lt;/td&gt;
&lt;td&gt;mcp.katto.tech/mcp&lt;/td&gt;
&lt;td&gt;OAuth 2.1 + DCR, or bearer&lt;/td&gt;
&lt;td&gt;npx katto-mcp&lt;/td&gt;
&lt;td&gt;all paid plans, shared quota&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Checked 2026-08-22 against vendor documentation. Things move fast in this space, if a cell is out of date, tell me and I will fix it.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually differs between video clipping MCPs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Access and pricing
&lt;/h3&gt;

&lt;p&gt;This is where implementations diverge the most. Some tools meter agent usage: OpusClip offers a free trial and then a Pro plan priced per render-minute, and Submagic's MCP draws from the same credit pool as their metered REST API. Others include it lower down: Reap ships theirs on a paid plan with API access, and Whipscribe's works from a free tier.&lt;/p&gt;

&lt;p&gt;On Katto, the MCP and API are included on &lt;a href="https://katto.tech/pricing" rel="noopener noreferrer"&gt;every paid plan&lt;/a&gt;, and calls draw from the same monthly video quota with no per-minute surcharge. I did that on purpose, and I am not the only one who thinks agent access should not be a tax. But check the table against your own budget; "included" means different things at different price points.&lt;/p&gt;

&lt;h3&gt;
  
  
  Authentication
&lt;/h3&gt;

&lt;p&gt;In practice, I have seen two useful authentication patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hosted, zero-install:&lt;/strong&gt; point an OAuth client (Claude web or desktop, or any client that supports OAuth) at the server URL and sign in. No key stored on disk.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local key:&lt;/strong&gt; a one-line npx install with an API key, for Cursor, CI, and scripts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not everyone offers both. OpusClip and Reap are OAuth through their hosted endpoints; Submagic and Whipscribe authenticate with Bearer keys. Katto's hosted endpoint (&lt;code&gt;https://mcp.katto.tech/mcp&lt;/code&gt;) does OAuth 2.1 with Dynamic Client Registration so the key never touches your machine, and the same endpoint also accepts a bearer key for automation. That is why I wanted Katto to support both patterns rather than forcing one authentication model on every use case.&lt;/p&gt;

&lt;p&gt;One note on safety, because it applies to every server in the table: an MCP gives your agent real capabilities on your account. Before connecting any of them, look at what the tools can actually do, and prefer servers that keep secrets and destructive actions out of the agent's reach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tool coverage
&lt;/h3&gt;

&lt;p&gt;A lot of MCP servers stop at "create job / get job." The more useful ones expose the whole pipeline. Katto currently exposes &lt;a href="https://katto.tech/mcp" rel="noopener noreferrer"&gt;15 tools&lt;/a&gt;, covering the full workflow from creating a job to transcripts, re-rendering with a different layout or caption style, dubbing into eight languages, and quota checks. The point is not the number, though. I wanted an agent to be able to do something useful &lt;em&gt;after&lt;/em&gt; the first render instead of stopping at "job complete."&lt;/p&gt;

&lt;p&gt;OpusClip goes wider still: their catalog is larger than mine and includes things Katto's MCP does not do today, like scheduling posts to connected social accounts.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the MCP cannot tell you
&lt;/h3&gt;

&lt;p&gt;Nothing in that table tells you whether the clips are any good. That is the part that actually matters, and it is the part a tool list cannot show.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Katto is still behind
&lt;/h2&gt;

&lt;p&gt;Honesty cuts both ways, so here is the other side. OpusClip has a much more mature product around its MCP: a bigger tool catalog, social scheduling from inside the agent, and a growing pile of third-party tutorials. Katto is younger and much smaller, and some of the polish that comes from years of users banging on a product simply is not there yet. If you want the most established end-to-end agent workflow today, that is a fair reason to pick OpusClip.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part I actually care about
&lt;/h2&gt;

&lt;p&gt;Here is the honest bit. The MCP is not the product. It is a doorway to the product. What matters is what happens behind the tool call.&lt;/p&gt;

&lt;p&gt;For Katto specifically, I have spent most of my time on videos where the interesting moment is not spoken: sports, gameplay, trailers, b-roll. Many clipping pipelines still rely heavily on transcript signals to decide what matters. That works well for podcasts and interviews, but it gets much harder when the hook is visual rather than verbal. So Katto reads the pixels too: scene cuts, faces, motion, on-screen text, instead of relying only on the transcript. That is the capability the MCP exposes; the MCP is just how an agent reaches it.&lt;/p&gt;

&lt;p&gt;So my advice, whether you use Katto or not: do not pick a clipping tool by its MCP tool count. Pick it by what the clips actually look like on &lt;em&gt;your&lt;/em&gt; kind of footage, then check that it has a clean, ungated, OAuth-capable MCP so your agents can drive it. Both matter. But only one is the reason someone keeps using the product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it in one line
&lt;/h2&gt;

&lt;p&gt;If you already have an MCP client, point it at &lt;code&gt;https://mcp.katto.tech/mcp&lt;/code&gt; and sign in with Katto (no key on disk). Or run it locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"katto"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"katto-mcp"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"KATTO_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sk_live_your_key"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then just ask your agent to clip something. That is the whole point.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I am building Katto in public. If you are doing anything with agents and media, I would genuinely like to hear what tools you wish existed. Find me at &lt;a href="https://katto.tech" rel="noopener noreferrer"&gt;katto.tech&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>buildinpublic</category>
      <category>video</category>
    </item>
    <item>
      <title>I Built a SaaS. Then I Asked ChatGPT to Recommend It. It Had Never Heard of Me.</title>
      <dc:creator>anthony papoti</dc:creator>
      <pubDate>Thu, 20 Aug 2026 02:56:47 +0000</pubDate>
      <link>https://dev.to/anthony_builds/i-built-a-saas-then-i-asked-chatgpt-to-recommend-it-it-had-never-heard-of-me-1dfc</link>
      <guid>https://dev.to/anthony_builds/i-built-a-saas-then-i-asked-chatgpt-to-recommend-it-it-had-never-heard-of-me-1dfc</guid>
      <description>&lt;p&gt;&lt;em&gt;A solo founder's distribution reckoning, in real numbers.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This morning I opened my analytics dashboard already convinced my product was dead. Nobody's signing up, I told myself. I'd been refreshing the same screen for an hour, watching a number that barely moved, feeling the whole thing slip away.&lt;/p&gt;

&lt;p&gt;Then I did the one thing I'd been avoiding: I stopped staring at the realtime counter and actually read the data.&lt;/p&gt;

&lt;p&gt;I build &lt;a href="https://katto.tech" rel="noopener noreferrer"&gt;Katto&lt;/a&gt;, an AI tool that turns long videos into short vertical clips. It's pre-launch, no ad spend, no marketing budget, just me. And here is what the database actually said, once I looked past a slow Tuesday morning:&lt;/p&gt;

&lt;p&gt;129 users. 58 of them in the last seven days. All organic.&lt;/p&gt;

&lt;p&gt;That is not a dead product. So why did it feel like one? Because I'd been judging a half-empty morning instead of the trend, and because two silent leaks were quietly undoing everything the traffic brought me. Finding those two leaks was the real work of the day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leak one: the first run was failing
&lt;/h2&gt;

&lt;p&gt;The first gut punch was the failure rate. On one recent day, close to six out of ten jobs failed.&lt;/p&gt;

&lt;p&gt;I dug into the actual reasons instead of panicking, and the picture split cleanly in two. About half the failures were the download step choking on YouTube's bot wall: a user pastes a link, and the video never comes down. The other half were free-plan users bringing videos longer than the plan allows and hitting a hard cap.&lt;/p&gt;

&lt;p&gt;The first half is a bug. The second half is a signal (people are showing up with real long-form content and getting a wall instead of an upsell), but that is a story for another post.&lt;/p&gt;

&lt;p&gt;The download failures are the ones that hurt, because they are invisible to me and fatal to the user. Someone hears about your tool, signs up, brings their video, and the very first thing they try just dies. They don't file a bug. They don't email you. They leave, and they never come back, and they certainly never pay.&lt;/p&gt;

&lt;p&gt;So I spent the day on unglamorous infrastructure: I migrated the backend to new infra and the download failures stopped. I did not take that on faith. I pulled the exact timestamps to make sure I wasn't fooling myself, and the last failure was the day before, with zero since the fix. Boring work. But the gap between a user who stays and one who's gone often lives in exactly this kind of boring work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leak two: even when it works, nobody finds it
&lt;/h2&gt;

&lt;p&gt;The second gut punch was bigger, and no infrastructure fix touches it.&lt;/p&gt;

&lt;p&gt;I opened Google Search Console. I rank on page two or three for basically everything. My own brand name ranks around position 28, because "katto" is a common word and I haven't earned the right to own it yet. (Curiously, "katto ai" ranks near the top, which tells me something about which name to lean on.)&lt;/p&gt;

&lt;p&gt;Then I ran the test that actually matters in 2026. I asked ChatGPT, "best AI clipping tools 2026." It confidently listed ten tools. I was not one of them. I tried again with a few phrasings. Same result. The AI that a growing share of my potential users now ask for recommendations has no idea I exist.&lt;/p&gt;

&lt;p&gt;That stung more than the failure rate. My product is good. People who try it mostly like it. And it does not matter, because the people who would try it never hear the name.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's not an indexing problem, it's a penetration problem
&lt;/h2&gt;

&lt;p&gt;Here is the reframe that turned the despair into a plan.&lt;/p&gt;

&lt;p&gt;I am fully indexed. Google has my pages. The problem is not that &lt;a href="https://katto.tech" rel="noopener noreferrer"&gt;Katto&lt;/a&gt; is hidden. The problem is that &lt;a href="https://katto.tech" rel="noopener noreferrer"&gt;Katto&lt;/a&gt; is not written about anywhere that counts.&lt;/p&gt;

&lt;p&gt;The tools an AI recommends, and the tools that rank, are the ones that appear across third-party pages: the "best OpusClip alternative" roundups, the review blogs, the directories, the creators who mention them. That is what a search engine and a language model both read as "this thing is real and people vouch for it."&lt;/p&gt;

&lt;p&gt;A competitor I had genuinely never heard of has something like 1,300 referring domains pointing at it. I have maybe three. That single gap explains almost everything about why they surface in a generic answer and I don't.&lt;/p&gt;

&lt;h2&gt;
  
  
  The plan: 3 to 10 to 25 to 50
&lt;/h2&gt;

&lt;p&gt;The mistake would be to look at 1,300 and try to chase it. That way lies buying garbage links off Fiverr and torching whatever trust I've built.&lt;/p&gt;

&lt;p&gt;The honest target for a young product is not 1,300. It's 3 to 10 to 25 to 50 real referring domains. The rule of thumb people repeat is that somewhere around 25 to 50 genuine domains a new site stops looking new. I can't prove that exact number, but the direction is obviously right, and the first ten are gettable by hand, without paying anyone:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A handful of honest directory listings (a few done, a few to go). The first concrete one on my list is AlternativeTo, where the OpusClip alternatives page lists over fifty tools, submissions are free and community-driven, and there's even an "EU-based" filter with almost nothing in it. French founder, euro pricing: I'd be nearly alone in a niche no competitor can claim.&lt;/li&gt;
&lt;li&gt;Two or three real reviews from people who actually use the tool.&lt;/li&gt;
&lt;li&gt;A link in a genuinely neutral "best AI clipping tools" article. This one is harder than it looks, because most of those roundups turn out to be a competitor quietly ranking itself first. The truly neutral ones are rarer (a few independent blogs, community sites). So the other half of this move is writing my own honest roundup, which, awkwardly, is exactly what every tool that ranks already does, and exactly what the language models read.&lt;/li&gt;
&lt;li&gt;My own founder presence, building in public, generating mentions over time.&lt;/li&gt;
&lt;li&gt;One or two creators who try it and talk about it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I am deliberately not doing: buying backlink packages, and paying a hundred dollars a month for an SEO tool to confirm a problem I already understand. That money goes into outreach and into getting the product in front of real creators instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually learned today
&lt;/h2&gt;

&lt;p&gt;Three things, mostly about myself.&lt;/p&gt;

&lt;p&gt;Your product being good is rarely the problem. Being found is. I spent months polishing features when the real gap was that almost nobody was arriving to see them.&lt;/p&gt;

&lt;p&gt;Stop staring at the realtime counter. It is noise. A slow morning is not a trend, and doom-refreshing a dashboard is a way to feel productive while learning nothing. Look at the weekly number, once a day, and get back to work.&lt;/p&gt;

&lt;p&gt;And distribution is not a thing you do after the product. For an indie founder with no budget, it is the product's twin, and it starts at three referring domains and a lot of unglamorous outreach.&lt;/p&gt;

&lt;p&gt;The traffic is already coming, quietly, on its own. My job now is to stop losing the people who arrive, and to slowly earn my way onto the pages that decide who gets recommended.&lt;/p&gt;

&lt;p&gt;I'll report back at ten domains.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>buildinpublic</category>
      <category>saas</category>
      <category>indiehackers</category>
    </item>
  </channel>
</rss>
