<?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: Tomas Grasl</title>
    <description>The latest articles on DEV Community by Tomas Grasl (@freema).</description>
    <link>https://dev.to/freema</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%2F3961521%2F1f52971d-ed17-4ad8-840e-bb48c43c9860.jpeg</url>
      <title>DEV Community: Tomas Grasl</title>
      <link>https://dev.to/freema</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/freema"/>
    <language>en</language>
    <item>
      <title>I'm writing my own game engine. Not to make games in it, as it turns out.</title>
      <dc:creator>Tomas Grasl</dc:creator>
      <pubDate>Thu, 20 Aug 2026 06:34:54 +0000</pubDate>
      <link>https://dev.to/freema/im-writing-my-own-game-engine-not-to-make-games-in-it-as-it-turns-out-1ban</link>
      <guid>https://dev.to/freema/im-writing-my-own-game-engine-not-to-make-games-in-it-as-it-turns-out-1ban</guid>
      <description>&lt;p&gt;I recently wrote here about how Anthropic's pending acquisition of Decart isn't only about cheaper inference it's also about robotics. The argument in short: you can't train a control loop on internet text, because control needs consequences. It needs an environment that responds to actions, cheaply and a million times over. And that is structurally what Oasis is. A frame predictor conditioned on actions is a simulator nobody had to write physics for.&lt;/p&gt;

&lt;p&gt;This is the more personal follow-up. About why the topic actually got to me — and why I'd been crawling toward it from a completely different direction the whole time, without planning to.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Firefox bridge
&lt;/h2&gt;

&lt;p&gt;Making games has been my hobby for a long time. Never professionally, never for money it just never wore off.&lt;/p&gt;

&lt;p&gt;At some point it started overlapping with the other thing I do: agents and MCP. I contributed to Godot MCP, which has since become a sort of de facto standard for connecting Godot to agents. And before that, I wrote a bridge between Firefox and MCP agents.&lt;/p&gt;

&lt;p&gt;I wanted a simple thing: for a model to actually work with the browser, not write about it.&lt;/p&gt;

&lt;p&gt;That turned out to be the smaller part of the problem. At the time, Firefox's approach to external control was badly outdated — a protocol built for testing, not for something acting autonomously inside the browser. Most of the work in the end wasn't about the agent at all. It was about working around or translating an interface that never anticipated this kind of use.&lt;/p&gt;

&lt;p&gt;I wrote it, put it out there, and moved on. Mozilla later adopted it and took it their own way: &lt;a href="https://github.com/mozilla/firefox-devtools-mcp" rel="noopener noreferrer"&gt;https://github.com/mozilla/firefox-devtools-mcp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This happens to me a lot with my own projects: I start something because the question is interesting, and somebody else finishes it. It used to bother me. These days it strikes me as a fair enough division of labour — the part I enjoy is the part where it isn't yet clear whether the thing makes any sense at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  My own engine, because it's fun
&lt;/h2&gt;

&lt;p&gt;Alongside that, I write my own game engines. Not in Unity, not in Unreal, not because it's the sensible thing to do.&lt;/p&gt;

&lt;p&gt;The reason is mundane: when you write the engine yourself, you know what happens in every single frame. There aren't twenty layers underneath that already decided something for you. You have state, you have input, you have a rule for how one produces the other.&lt;/p&gt;

&lt;p&gt;And that's exactly the property I started wanting for a different reason.&lt;/p&gt;

&lt;p&gt;Worth saying plainly, because it's the part that usually gets misread: the engine is the work. I'm not training anything, I'm not building a model, and I have no ambition to. Models are something other people make and I'm happy to leave it that way. What I'm building is the instrument you point at one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually want
&lt;/h2&gt;

&lt;p&gt;I want a model to play my game. And then to design it itself.&lt;/p&gt;

&lt;p&gt;Not in the "generate me a level" sense. That's content generation and everybody can do that by now. I mean: let the agent play, let it lose, let it change the rules and try again and watch what comes out.&lt;/p&gt;

&lt;p&gt;This is where it meets the distinction I wrote about in the previous post, and the thing I think the whole conversation keeps glossing over:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model as the control loop&lt;/strong&gt; — perceive, decide, act. Every tick, inside a latency budget.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model as the author of the control loop&lt;/strong&gt; — read the docs, write code, test, iterate. At human timescales.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Almost every number you see about LLMs and robotics measures the second and gets reported as the first. Models today are good at writing code for robots. They are not yet good at being that code.&lt;/p&gt;

&lt;p&gt;Your own engine is a pretty good instrument for that distinction. I can open it from both ends. I can hand the agent inputs and let it play in real time. And I can hand it the source and let it change the rules of the world. Same world, same consequences.&lt;/p&gt;

&lt;h2&gt;
  
  
  The side effect this is really about now
&lt;/h2&gt;

&lt;p&gt;It was supposed to be a nice experiment about games. Gradually it turned into something else, and the next step has almost nothing to do with games anymore.&lt;/p&gt;

&lt;p&gt;I don't want to use the engine to generate games. I want it to be a place where you can put a model in a loop with consequences and see what it does. Not to make the model better — to be able to watch it at all.&lt;/p&gt;

&lt;p&gt;Because a game is a cheap environment with consequences. It has state, it has time, it has physics dumb physics, but physics — it has object permanence, and it has a cost for being wrong. It's the cheapest thing you can use to check whether a model understands that actions have consequences, or whether it's just good at describing frames.&lt;/p&gt;

&lt;p&gt;And because I wrote it myself, I can break that physics at will. Crank up gravity, remove inertia, invert causality. That's hard to do in an off-the-shelf engine and impossible in recorded video. A test harness where you can't change the rules isn't much of a test harness.&lt;/p&gt;

&lt;p&gt;It's the exact opposite direction from Decart. They learn the dynamics of the world from video in order to generate frames conditioned on actions. I have a hand-written world I know absolutely everything about, and I'm curious how much of it a model can work out. Smaller, dumber, but fully legible and legible is the whole point when the thing you're building is an instrument.&lt;/p&gt;

&lt;p&gt;Where this ends up, I have no idea. It's entirely possible I'll find out only that a model can play my game and nothing further follows. I'll take that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why any of this
&lt;/h2&gt;

&lt;p&gt;This is where I'd normally write a sentence about the market opportunity.&lt;/p&gt;

&lt;p&gt;I don't have one. I make no money from this and probably never will. There's no startup behind it, no pitch deck, no plan. I'm not competing with anyone building models, because I'm not building one. I do it because I like exactly the stage where it isn't clear yet what it's for and because the things I make this way have a habit of turning out useful somewhere else entirely.&lt;/p&gt;

&lt;p&gt;I wrote the Firefox bridge out of curiosity. A year later I was building production MCP infrastructure at work, and that experience saved me a lot of dead ends. The engines started as pure nostalgia for a kind of game nobody makes anymore. Now one of them is turning into a test environment for agents.&lt;/p&gt;

&lt;p&gt;I don't think that's a recipe. More of an observation: the most useful things I've made came out as a side effect of something I was doing purely for fun. And I never knew in advance which ones.&lt;/p&gt;

&lt;p&gt;So: for fun. And if something interesting falls out of it, all the better.&lt;/p&gt;




&lt;p&gt;If any of you are running similar experiments your own engines, agents in simulation, anything on this boundary I'd be glad to compare notes. Especially if you've found where exactly a model breaks once you put it in a loop with consequences.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>gamedev</category>
      <category>mcp</category>
      <category>agents</category>
    </item>
    <item>
      <title>Anthropic's $6B Decart deal is a robotics play disguised as a compute play</title>
      <dc:creator>Tomas Grasl</dc:creator>
      <pubDate>Thu, 13 Aug 2026 15:25:58 +0000</pubDate>
      <link>https://dev.to/freema/anthropics-6b-decart-deal-is-a-robotics-play-disguised-as-a-compute-play-5fek</link>
      <guid>https://dev.to/freema/anthropics-6b-decart-deal-is-a-robotics-play-disguised-as-a-compute-play-5fek</guid>
      <description>&lt;p&gt;Bloomberg reported this morning, August 13, that Anthropic is in talks to buy Decart AI for around $6 billion. Talks, not a signed deal. That distinction matters and I will come back to it.&lt;/p&gt;

&lt;p&gt;What caught my attention is not the number. It is where Decart came from.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Minecraft thing
&lt;/h2&gt;

&lt;p&gt;Decart got famous for Oasis: a playable Minecraft-looking world that no game engine was rendering. The model predicted every next frame based on what you pressed on the keyboard. 20 FPS, interactive, no scene graph, no collision system, no assets. Just a model hallucinating a consistent world fast enough that your hands believed it.&lt;/p&gt;

&lt;p&gt;In late 2024 that read as an impressive demo with no obvious business behind it.&lt;/p&gt;

&lt;p&gt;The company was founded in 2023. It has raised over $450M, was valued at $3.1B before this year's round, and its current &lt;a href="https://decart.ai/research" rel="noopener noreferrer"&gt;research page&lt;/a&gt; describes three product lines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Oasis&lt;/strong&gt;, a world model, now explicitly positioned for physical AI and robotics rather than gaming&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lucy&lt;/strong&gt;, a real-time video model running live at 30 FPS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DOS&lt;/strong&gt;, the Decart Optimization Stack: hardware-aware model design, custom kernels, proprietary compilers, inference optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The demo was the marketing. DOS is the engineering.&lt;/p&gt;

&lt;h2&gt;
  
  
  The reported reason is not robotics
&lt;/h2&gt;

&lt;p&gt;Read the actual reporting carefully. &lt;a href="https://fortune.com/2026/08/13/anthropic-said-in-talks-to-buy-startup-decart-for-6-billion/" rel="noopener noreferrer"&gt;Fortune&lt;/a&gt; says a deal would bring Decart's video-simulation and chip-efficiency technology into Anthropic's inference team. Bloomberg's sources point at the same thing: the chip efficiency work could help existing infrastructure absorb more demand.&lt;/p&gt;

&lt;p&gt;So the sourced story is compute economics. Anthropic is compute constrained, spending enormously on capacity, and DOS is a margin lever that applies to every single Claude request on day one.&lt;/p&gt;

&lt;p&gt;That is a boring, completely rational reason to spend $6B. It does not need a robotics narrative at all.&lt;/p&gt;

&lt;p&gt;I still think the robotics reading is in there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;Two things sit underneath.&lt;/p&gt;

&lt;p&gt;First, Anthropic held acquisition talks with Physical Intelligence this spring. The Information reported it, the CEO denied the specific weekend rumor that blew up on X in July, but the talks happened. That is a robot foundation model company, valued around $11B, whose pi0.5 is one of the more widely used robot brains in research labs. You do not open that conversation by accident.&lt;/p&gt;

&lt;p&gt;Second, and this is the constraint people skip: &lt;a href="https://techcrunch.com/2026/07/21/the-anthropic-physical-intelligence-rumor-roiling-ai-twitter/" rel="noopener noreferrer"&gt;OpenAI is already a shareholder in Physical Intelligence&lt;/a&gt;. Founders Fund and Thrive are in there too. If a bidding contest for the robotics foundation model layer is happening, Anthropic may simply not be allowed to win that particular one.&lt;/p&gt;

&lt;p&gt;If you cannot buy the robot brain, buy the world the brain gets trained in. And take the inference savings as immediate return while the option matures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three different bets on physical AI
&lt;/h2&gt;

&lt;p&gt;This is the part I find genuinely useful, because "everyone is going into robotics" is a lazy summary. There are three distinct strategies running right now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vertical model (Mistral).&lt;/strong&gt; On July 8 they shipped &lt;a href="https://www.siliconrepublic.com/machines/mistral-expands-physical-ai-first-robotics-launch" rel="noopener noreferrer"&gt;Robostral Navigate&lt;/a&gt;, an 8B navigation model. Single RGB camera, plain language instructions, hardware agnostic, trained entirely in simulation, 76.6% on the R2R-CE benchmark. They are hiring a robotics team and selling into Airbus and BMW. Narrow scope, deployed now, revenue this year.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;World model (Decart).&lt;/strong&gt; Learn the dynamics of the world from video, generate frames conditioned on actions. You are not building a robot. You are building the environment the robot learns in, plus the synthetic data to train on. Slower, more general, much bigger if it works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;General scaling (Anthropic).&lt;/strong&gt; Do not build robotics at all. Measure whether the capability falls out of the general model on its own.&lt;/p&gt;

&lt;p&gt;That third one sounds like a joke until you read &lt;a href="https://www.anthropic.com/research/project-fetch-phase-two" rel="noopener noreferrer"&gt;Project Fetch Phase Two&lt;/a&gt;. In August 2025 their model could not connect to a robot dog's sensors. By June 2026 a newer model finished the whole task set in under ten minutes, roughly 20x faster than the best human-plus-Claude team from the year before. Anthropic states plainly that this did not come from any deliberate effort to improve robotics. It came from general scaling.&lt;/p&gt;

&lt;p&gt;Read as strategy, that paper argues against founding a robotics division. It argues for more compute and better simulation. Which is exactly what Decart sells.&lt;/p&gt;

&lt;h2&gt;
  
  
  The distinction nobody is making
&lt;/h2&gt;

&lt;p&gt;Here is the part I keep waiting to see in the coverage and do not.&lt;/p&gt;

&lt;p&gt;In Project Fetch, Claude was not the control policy. Claude was the programmer. It wrote and debugged the code that drove the robot. The loop running at 50Hz on the hardware was ordinary software that a model happened to author.&lt;/p&gt;

&lt;p&gt;Those are completely different capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model as control loop&lt;/strong&gt;: perceive, decide, actuate, every tick, under latency budget&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model as author of the control loop&lt;/strong&gt;: read docs, write code, test, iterate, at human timescales&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Almost every headline number about LLMs and robotics is measuring the second one and getting reported as the first. And Anthropic's own follow-up work, &lt;a href="https://www.anthropic.com/research/claude-plays-robotics" rel="noopener noreferrer"&gt;Claude plays robotics&lt;/a&gt;, is explicit that precise physical manipulation and closed-loop control remain a hard limit. The models are good at writing robot code. They are not yet good at being robot code.&lt;/p&gt;

&lt;p&gt;This is precisely where a world model changes the picture. You cannot scale a control policy on internet text, because control policies need consequences. They need an environment that responds to actions, cheaply, millions of times. That is what Oasis is, structurally. A frame predictor conditioned on actions is a simulator you did not have to write physics for.&lt;/p&gt;

&lt;p&gt;So the Minecraft demo and the robot training environment were never two different products. They were the same artifact with two different customers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I do not know
&lt;/h2&gt;

&lt;p&gt;Being honest about the limits of this, since it is a story that is hours old:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;These are talks. They can fall apart. Nothing is signed.&lt;/li&gt;
&lt;li&gt;The Project Fetch numbers are self-reported and have not been independently replicated.&lt;/li&gt;
&lt;li&gt;The compute reading and the robotics reading are both fully consistent with the available reporting. I am arguing the second is present, not that the first is wrong. Most large acquisitions are over-determined.&lt;/li&gt;
&lt;li&gt;Disclosure: I use Claude Code daily and run a good chunk of my own tooling on Anthropic's models. I am not a neutral observer here.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The thing I will be watching is not whether the deal closes. It is whether Oasis stays a product with an API, or quietly turns into internal training infrastructure nobody outside gets to touch.&lt;/p&gt;

&lt;p&gt;That would tell you which of the two readings was right.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>news</category>
      <category>claude</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Token prices dropped 90%. My AI bill did not. Here is what I changed.</title>
      <dc:creator>Tomas Grasl</dc:creator>
      <pubDate>Thu, 13 Aug 2026 15:10:09 +0000</pubDate>
      <link>https://dev.to/freema/token-prices-dropped-90-my-ai-bill-did-not-here-is-what-i-changed-1jih</link>
      <guid>https://dev.to/freema/token-prices-dropped-90-my-ai-bill-did-not-here-is-what-i-changed-1jih</guid>
      <description>&lt;p&gt;Token prices fell around 90% since 2023. Corporate spending on AI went up about 320%.&lt;/p&gt;

&lt;p&gt;Both numbers are true at the same time, and if you run any kind of agent loop, you already feel it. 😅&lt;/p&gt;

&lt;p&gt;This is not a billing bug. It is Jevons paradox, and it has been running in the background of every AI budget for the last two years.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 160-year-old explanation
&lt;/h2&gt;

&lt;p&gt;In 1865 William Stanley Jevons noticed that as steam engines got more efficient, Britain did not burn less coal. It burned more. Cheaper energy made new uses viable, new uses drove consumption, total spend went up while unit cost went down.&lt;/p&gt;

&lt;p&gt;Tokens work exactly the same way. Except with tokens the effect is stronger, because cheap tokens did not just make existing work cheaper. They made a whole class of architectures possible that nobody would have paid for two years ago.&lt;/p&gt;

&lt;p&gt;Nobody was running a 20-step autonomous loop when a million output tokens cost real money. Now everybody is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why agents multiply the bill
&lt;/h2&gt;

&lt;p&gt;A chat call is one shot. You ask, the model answers, done. Maybe a few thousand tokens.&lt;/p&gt;

&lt;p&gt;An agent does not work like that. It runs in a loop: think, act, observe, adjust, repeat. And on every single step it reloads the entire conversation so far, because the model has no memory between calls. Step 12 is paying for steps 1 through 11 again.&lt;/p&gt;

&lt;p&gt;So consumption does not scale linearly with the result. It scales more like rocket fuel: to go a bit further you need a lot more of it.&lt;/p&gt;

&lt;p&gt;Goldman Sachs projects roughly a 24x increase in global token consumption by 2030, driven mostly by agents. That number sounds absurd until you count the reloads in one of your own sessions.&lt;/p&gt;

&lt;p&gt;Btw this is also why context bloat is not a cosmetic problem. Every unnecessary file you dump into context gets paid for once per loop iteration, not once per task. I built a small plugin for this in Claude Code specifically because the default behaviour of resending everything each turn was quietly the most expensive thing in my setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reasoning models on trivial tasks
&lt;/h2&gt;

&lt;p&gt;The second multiplier is the thinking part. Reasoning models generate thousands of internal tokens before they emit a single visible character. On a hard problem that is exactly what you want, and it is genuinely better output.&lt;/p&gt;

&lt;p&gt;On "rename this variable" it is money set on fire.&lt;/p&gt;

&lt;p&gt;The failure mode here is not the model. It is that most setups have one model configured for everything, so the expensive one handles the trivial work too. You do not notice per call. You notice at the end of the month.&lt;/p&gt;

&lt;h2&gt;
  
  
  The number managers actually look at is the wrong one
&lt;/h2&gt;

&lt;p&gt;Acceptance rate for AI-generated code sits somewhere around 80 to 90%. It looks fantastic on a slide.&lt;/p&gt;

&lt;p&gt;It also does not mean the code shipped.&lt;/p&gt;

&lt;p&gt;GitClear's longitudinal study across 211 million changed lines found code churn, meaning lines reverted or rewritten within two weeks, went from a stable ~3.3% before AI assistants to roughly double that now. Copy-pasted lines overtook refactored lines for the first time in the dataset's history. AI-authored PRs carry noticeably more issues per PR.&lt;/p&gt;

&lt;p&gt;There are more dramatic numbers going around, like the chart claiming only $0.18 of every AI coding dollar becomes shipped value. I would treat that one carefully. It comes from a single platform's own data, not an audited benchmark. The direction is right, the precision is not something I would put in a board deck.&lt;/p&gt;

&lt;p&gt;But the underlying point holds and matches what I see: the expensive part is not generation. It is the loop after generation. Fixing edge cases. Rewriting half the diff. Reviewing a change that touched three files nobody asked about.&lt;/p&gt;

&lt;p&gt;Tokens spent on code that gets rewritten next sprint are not cheaper because tokens are cheap. They are pure loss with an invoice attached.&lt;/p&gt;

&lt;h2&gt;
  
  
  So the actual lever is routing
&lt;/h2&gt;

&lt;p&gt;Not discipline. Not "use AI less". Telling your team to use less AI just gives back the productivity you were trying to buy.&lt;/p&gt;

&lt;p&gt;The lever is which model handles which step.&lt;/p&gt;

&lt;p&gt;Here is my current &lt;code&gt;/implement&lt;/code&gt; loop, the one that pulls a task from Linear and drives it to Done:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Opus&lt;/strong&gt; plans and writes production code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cursor Composer 2&lt;/strong&gt; writes tests and does the first review pass&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sonnet&lt;/strong&gt; clicks through the result in a browser to verify it works&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Codex&lt;/strong&gt; does the milestone review&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rule behind it is simple. The expensive model runs where a mistake costs more than tokens. Everywhere else, something cheaper runs.&lt;/p&gt;

&lt;p&gt;Planning and production code are where a bad decision propagates into everything downstream, so that is where I pay. Test scaffolding, mechanical refactors, browser verification: none of those need the frontier tier, and using it there buys nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What did not work
&lt;/h2&gt;

&lt;p&gt;Giving the planning step to a cheap model.&lt;/p&gt;

&lt;p&gt;I tried it, because on paper it is the biggest single line item. It came out more expensive, not less. A weak plan means you rewrite the implementation, and rewriting is precisely the part that burns money. You save on one call and pay for it across the next twelve.&lt;/p&gt;

&lt;p&gt;Same lesson in a different shape: a frontier model that solves a task in three turns can genuinely cost less in total than a budget model that needs twelve, because every extra turn resends the whole context. The cheap model is only cheap per call.&lt;/p&gt;

&lt;p&gt;The other thing that did not work was doing the model switching by hand. Two terminals, copy diffs between them, lose track of which one has the current state. I ended up writing a plugin to bridge Claude Code and Cursor Composer 2 so the handoff happens in one place. Heavily inspired by openai/codex-plugin-cc, which does the same trick with GPT. Credit where due.&lt;/p&gt;

&lt;h2&gt;
  
  
  The boring part nobody posts about
&lt;/h2&gt;

&lt;p&gt;Knowing when to stop the agent.&lt;/p&gt;

&lt;p&gt;Knowing when to take autonomy away from it and hand it a narrower task.&lt;/p&gt;

&lt;p&gt;Knowing when writing it yourself is just faster.&lt;/p&gt;

&lt;p&gt;None of that is impressive on a demo. All of it is the difference between an AI setup that pays for itself and one that produces the same output at a higher price.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually track
&lt;/h2&gt;

&lt;p&gt;Not tokens consumed. That metric has already been tested at scale by companies much larger than mine, and the result was Goodhart's law in production: the moment consumption became the target, it stopped measuring productivity and started measuring nothing except the invoice.&lt;/p&gt;

&lt;p&gt;What I care about is how much of what the agent produced survived review and made it to deploy. That number is harder to get, and it is the only one that answers whether any of this is working.&lt;/p&gt;

&lt;p&gt;The value of a developer right now is not lines produced. It is the architecture of control around what generates those lines.&lt;/p&gt;




&lt;p&gt;If you run agents in production: are you measuring token spend, or what actually ships out of it? Curious how other teams attribute this, because I do not think anyone has a clean answer yet.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I didn't want to build one game, so I built a whole portal, and the pixel-art pipeline to feed it</title>
      <dc:creator>Tomas Grasl</dc:creator>
      <pubDate>Tue, 11 Aug 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/freema/i-didnt-want-to-build-one-game-so-i-built-a-whole-portal-and-the-pixel-art-pipeline-to-feed-it-223k</link>
      <guid>https://dev.to/freema/i-didnt-want-to-build-one-game-so-i-built-a-whole-portal-and-the-pixel-art-pipeline-to-feed-it-223k</guid>
      <description>&lt;p&gt;Instead of building one game, I built a portal to hold &lt;em&gt;many&lt;/em&gt; of them. All at once. I know how that sounds.&lt;/p&gt;

&lt;p&gt;I like games, not just playing them, but taking them apart to see how they work, and I've built my own little engines over the years to mess around. So when AI turned into a real force multiplier, I pointed it at the whole idea of a game portal instead of a single game.&lt;/p&gt;

&lt;p&gt;It's called &lt;strong&gt;&lt;a href="https://www.pixelden.io" rel="noopener noreferrer"&gt;PixelDen&lt;/a&gt;&lt;/strong&gt;, and the interesting part isn't any single game. It's the machinery underneath.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phaser 4, plus a 2.5D layer I bolted on
&lt;/h2&gt;

&lt;p&gt;I run the games on Phaser. I've got good history with it, and version 4 took real leaps. It's a serious framework now, small and flexible, no giant UI full of buttons to learn. On top of it I built an extra layer that handles 2.5D, because I wanted more than flat sprites without dragging in a full 3D engine.&lt;/p&gt;

&lt;p&gt;For the backend I went with &lt;strong&gt;Remix&lt;/strong&gt;. Everyone's pushing Next.js, but it's had its share of security headaches and self-hosting it outside Vercel feels worse, not better. Remix gets out of my way and hosts anywhere.&lt;/p&gt;

&lt;p&gt;The catalog is a mix on purpose, the simple stuff (Snake, Breakout, Flappy, tower defense, blackjack) next to genuinely harder builds: &lt;strong&gt;Dungeon Cast&lt;/strong&gt;, which is basically Wolfenstein 3D running as a raycaster, and a Mario-Kart-style racer. The hard ones exist mostly because I wanted to prove the 2.5D layer could carry them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The skills you can't download
&lt;/h2&gt;

&lt;p&gt;Here's the thing nobody tells you about "vibe coding" a game: the AI is only as good as the domain knowledge you feed it. For a 2D engine pretending to do 3D, there's no package to install and no tutorial to point at. I had to &lt;em&gt;build&lt;/em&gt; those skills (render a 3D space inside a 2D engine, fake the physics convincingly) through hours of trial and error, then codify them so my agent could reuse them.&lt;/p&gt;

&lt;p&gt;That's the real work of AI-assisted game dev. Not "make me a platformer." It's assembling the specific, hard-won knowledge the model doesn't have, so that when you ask for a platformer, it actually knows what you mean. A prototype platformer came together surprisingly fast, &lt;em&gt;after&lt;/em&gt; the skills existed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feeding the machine: a pixel-art pipeline on my home PC
&lt;/h2&gt;

&lt;p&gt;A game portal needs a lot of art, and I wasn't about to hand-draw all of it or pay per image. So I built a pixel-art generation pipeline that runs on my own home PC: open, locally-run image models, not a hosted API. No GPT-image, no Gemini; just a functional pipeline stitched from pieces you can actually self-host.&lt;/p&gt;

&lt;p&gt;It's not a model trained from scratch on pixel art; it's a pragmatic pipeline that produces usable sprites, and it even handles animation, including the fiddly skeleton work. On top of it I built an online pixel-art editor so I can keep everything under my control instead of round-tripping through someone's cloud.&lt;/p&gt;

&lt;p&gt;Owning the whole art pipeline is the same instinct that shows up in everything I build: keep it local, keep it yours, keep it cheap to run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a portal at all
&lt;/h2&gt;

&lt;p&gt;The honest answer is that I have a strange bubble of people and I wanted a playground more than a product. But there's a real lesson in it: AI didn't let me build a game faster so much as it let me build the &lt;em&gt;infrastructure around&lt;/em&gt; building games: the 2.5D layer, the reusable engine skills, the art pipeline, the editor. Those compound. Every new game is cheaper than the last because the machinery is already there.&lt;/p&gt;

&lt;p&gt;If you want a five-minute break from thinking about AI, go play something.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://www.pixelden.io" rel="noopener noreferrer"&gt;pixelden.io&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What's the last thing you built where the tooling around the thing turned out to be more valuable than the thing itself?&lt;/em&gt;&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>ai</category>
      <category>javascript</category>
    </item>
    <item>
      <title>"Can the model write the code?" Wrong question.</title>
      <dc:creator>Tomas Grasl</dc:creator>
      <pubDate>Mon, 10 Aug 2026 14:18:21 +0000</pubDate>
      <link>https://dev.to/freema/can-the-model-write-the-code-wrong-question-3ndi</link>
      <guid>https://dev.to/freema/can-the-model-write-the-code-wrong-question-3ndi</guid>
      <description>&lt;p&gt;I let an agent pull its own tickets from Linear and drive them to Done. One command: &lt;code&gt;/implement&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let me disarm that right away. This is not an autonomous agent doing whatever it wants. It is a fairly narrow pipe with several points where it stops and waits for me. Yes, I know this will be done better later. But right now this is the most conservative version I can run, and more importantly, the version I can explain to someone else.&lt;/p&gt;

&lt;p&gt;The project is Luštírna, a gamification POC for an ecosystem of thirteen sites: daily games, a credit wallet, a three-way paywall. Around forty tasks, milestones M1 to M6, one developer, a second person feeding the backlog. What follows is how the loop is wired, because almost none of the interesting decisions in it are about models. They are about where you put the gates.&lt;/p&gt;

&lt;h2&gt;
  
  
  How you start it
&lt;/h2&gt;

&lt;p&gt;Two modes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/implement&lt;/code&gt; is a single pass. It takes the queue and goes task by task for as long as there is something unblocked left in Linear, then summarizes what is waiting and why. This is just an init prompt. I did not want to retype the same three paragraphs every morning.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/loop 45m /implement&lt;/code&gt; is the long run. Same thing, except it does not shut down when the queue empties. Every 45 minutes it wakes up, orients itself (git status, Linear, the check gate, beta health) and picks work back up as soon as anything unblocks: a merged PR, a new task, a changed priority. Thirty to sixty minutes is fine as an interval. Shorter does not help, because the thing doing the unblocking is a human.&lt;/p&gt;

&lt;p&gt;Both are typed into a fresh context. Everything that has to survive lives in the repo (&lt;code&gt;docs/progress.md&lt;/code&gt;) and in Linear, never in the conversation. That sounds like a style preference. It is not, and there is a story at the end of this post about what happens when you ignore it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The main session writes no code
&lt;/h2&gt;

&lt;p&gt;This is the part that changed the most since the first version.&lt;/p&gt;

&lt;p&gt;The orchestrator session does not write a single line of production code. It writes a brief, spawns an agent, waits for the result. The working context lives inside those agents, the main thread stays free for steering: Linear, the gates, the decisions.&lt;/p&gt;

&lt;p&gt;One iteration is one task taken to Done, and the steps are always the same: orient, pick a task, design, implement, verify, review, deploy, close.&lt;/p&gt;

&lt;p&gt;Step zero is the underrated one. Context does not survive between iterations, the repo does. So every iteration starts identically: git state, recent commits, read &lt;code&gt;docs/progress.md&lt;/code&gt;, reload conventions, run the check gate. If something is red before any work has started, that is the first job, because the previous iteration left a mess. Skip this ritual and after a few hours the loop is building on foundations it does not know are crooked.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who does what
&lt;/h2&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;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fable&lt;/td&gt;
&lt;td&gt;Orchestrates. Writes the design and brief for every task, then runs the review workflow over the diff once verification is green. Also handles diagnosis when a fix fails twice.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Opus&lt;/td&gt;
&lt;td&gt;Writes all production code and fixes findings. Always as a spawned agent with its own brief, never the main context.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sonnet&lt;/td&gt;
&lt;td&gt;Clicks through the acceptance criteria in a browser, writes a report with screenshots.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Codex / Cursor&lt;/td&gt;
&lt;td&gt;Independent review at the end of a loop, deliberately outside the Claude family. Cursor is wired in through my plugin: &lt;a href="https://github.com/freema/cursor-plugin-cc" rel="noopener noreferrer"&gt;cursor-plugin-cc&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two rules hold this together. Writing code is never delegated to a smaller model. And the agent that tests never fixes what it tested, otherwise it is grading its own homework.&lt;/p&gt;

&lt;p&gt;The Fable allocation is worth a note. The original design used the strongest model at three expert moments and one big review at the end of the phase. That ended on August 8. Review in one large batch catches less than continuous review of small changes, and by the time you audit six months of code at once, half the findings are too expensive to act on. Fable now writes the brief for every task and reviews every diff. Routine code stays with Opus agents, because in routine code the gap between models is small, while in design it is enormous. An append only ledger does not get rewritten after a month in production. You live with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The verifier must not see the code
&lt;/h2&gt;

&lt;p&gt;This is the single most important rule in the loop.&lt;/p&gt;

&lt;p&gt;The test agent gets the acceptance criteria and a URL. It does not get the diff, the plan, or any implementation reasoning. The reason is simple: a verifier that knows how the thing is written stops testing the requirement and starts confirming the code.&lt;/p&gt;

&lt;p&gt;The quiet failure mode of agentic development is not bad code. It is tests written to pass. The agent runs the code, sees the output, and records it as the expectation. That test will never catch the bug it was written for.&lt;/p&gt;

&lt;p&gt;So the verifier owes three things beyond the happy path.&lt;/p&gt;

&lt;p&gt;Nasty cases, not just the sunny one: repeat a scored action and confirm the second credit was not granted, spoof a client side value and expect the server to reject it, search the page, the bundles and the network responses for today's puzzle solution and seed.&lt;/p&gt;

&lt;p&gt;Evidence instead of conclusions: the report is criterion by criterion, pass or fail, each with a screenshot, a URL, a commit SHA and a console error count. A conclusion without an artifact does not count.&lt;/p&gt;

&lt;p&gt;And no fixes. Whoever tests does not repair.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gates the loop cannot rewrite
&lt;/h2&gt;

&lt;p&gt;An agent that can edit its own checks has no checks. It sounds obvious. It was not in the first version, and the loop was allowed to touch anything.&lt;/p&gt;

&lt;p&gt;The perimeter now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CI config, deploy files, Dockerfile, env files and anything on the server change only with human confirmation. Confirmation given in the conversation counts immediately and gets recorded in a task comment.&lt;/li&gt;
&lt;li&gt;Merges go through a pull request, never a direct push.&lt;/li&gt;
&lt;li&gt;Tests are never deleted, skipped or softened to get green. A red test is a finding, not an obstacle.&lt;/li&gt;
&lt;li&gt;Four domains (login, credit ledger, migrations, paywall) get implemented by the loop but merged by a human.&lt;/li&gt;
&lt;li&gt;Migrations in a release may only add. Dropping and renaming columns waits for a later release, otherwise rollback stops working.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cheapest rule of the set is also the most effective: whatever slipped through gets a check. Every bug that made it as far as verification is converted into a test or a lint rule in the same iteration. A rule written in a conventions file holds only until the context fills up. A check holds always.&lt;/p&gt;

&lt;h2&gt;
  
  
  The thing you only find by accident
&lt;/h2&gt;

&lt;p&gt;There are gaps in all of this, and some of them you find sideways.&lt;/p&gt;

&lt;p&gt;I thought my router had died. Latency in the hundreds of milliseconds, identical over cable and over Wi-Fi. Ping to my own router: 1 ms, zero loss. Ping one hop past it: 363 ms average, spikes over a second.&lt;/p&gt;

&lt;p&gt;It had not died. It was the orchestrator session of this loop, which had been running for 2 days and 17 hours in a single context.&lt;/p&gt;

&lt;p&gt;What confused me first was that it should have been compacting. Then I found the issue on GitHub. Claude Code resends the entire conversation on every turn, every message and every tool output. Prompt cache saves compute on the server, not bytes on the wire. Upload volume scales with the size of the live context, not with the length of what you just typed. A fifty character question can ship half a megabyte.&lt;/p&gt;

&lt;p&gt;There is no built in network usage indicator, so a session strangling your uplink looks exactly like a session doing nothing. Low minimum latency with a huge spread is the signature of bufferbloat: a saturated outbound queue on the router, paid for by every device on the network, including the ones on cable. Which is exactly why it presents as dead hardware.&lt;/p&gt;

&lt;p&gt;I wrote a plugin for it: a statusline with an estimated upload per turn, a hook that warns as a session grows, and a scan that shows which running session is currently eating the link. &lt;a href="https://github.com/freema/ai-skills/tree/main/skills/context-guard" rel="noopener noreferrer"&gt;context-guard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the fresh context rule turns out not to be context hygiene. It is also a network rule. 😅&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would tell someone wiring this up
&lt;/h2&gt;

&lt;p&gt;The bottleneck moves. It does not disappear. You stop writing code and you start reading diffs and saying yes or no, and the throughput of the whole thing is set by how good your verification is, not by how good your model is. Everything else is downstream of that.&lt;/p&gt;

&lt;p&gt;The payoff is unattended flow: you wake up to a deployed task with evidence attached to each acceptance criterion. Not the feeling of going faster. That feeling, in my experience, lies.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>claude</category>
    </item>
    <item>
      <title>I gave two AI agents a way to talk to each other. Then one of them fixed a bug while I slept.</title>
      <dc:creator>Tomas Grasl</dc:creator>
      <pubDate>Thu, 06 Aug 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/freema/i-gave-two-ai-agents-a-way-to-talk-to-each-other-then-one-of-them-fixed-a-bug-while-i-slept-a57</link>
      <guid>https://dev.to/freema/i-gave-two-ai-agents-a-way-to-talk-to-each-other-then-one-of-them-fixed-a-bug-while-i-slept-a57</guid>
      <description>&lt;p&gt;OpenClaw is an autonomous agent you'd normally talk to over Discord or Telegram. That never sat right with me. Chatting with an autonomous worker through a chat app wastes most of what makes it useful. So I asked the obvious question: what if I connect it directly to Claude, agent to agent?&lt;/p&gt;

&lt;p&gt;That's &lt;strong&gt;openclaw-mcp&lt;/strong&gt;. Claude delegates a task, Claw goes off and does the work autonomously on a server, and reports back. One conversation, two agents collaborating. It's my second most successful repo (over 120 GitHub stars), and by stars and issue traffic, more of you seem to run it than run the official bridge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it stops being a toy
&lt;/h2&gt;

&lt;p&gt;Agent-to-agent sounds cute until you see it close a real loop. A couple I actually run:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bug fixing on autopilot.&lt;/strong&gt; n8n catches a Sentry alert. An AI node decides it's worth fixing and sends the task to Claw over MCP. Claw clones the repo, spins up Claude Code, fixes the bug, opens a pull request on GitHub, and drops a Slack message with the link. You wake up to a ready-to-review PR. The first time that happened I genuinely didn't believe it until I read the diff.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jira without the context bloat.&lt;/strong&gt; Instead of loading ten different MCPs into Claude Code and watching them eat your context window, you load &lt;em&gt;one&lt;/em&gt;: Claw. Tell Claw to grab the Jira task; it hands back a clean prompt; you do the work; you notify Jira through Claw that it's done. One bridge instead of ten tool servers is a real context saving.&lt;/p&gt;

&lt;h2&gt;
  
  
  The unglamorous part: making it safe to run
&lt;/h2&gt;

&lt;p&gt;The fun demo is easy. Making an agent you'd actually leave running took the boring work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Docker images on GHCR&lt;/strong&gt; with &lt;strong&gt;OAuth 2.1&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security hardening&lt;/strong&gt;: SSRF protection, input validation, CORS. An agent that clones repos and runs code is a juicy target; treat it like one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configurable timeouts&lt;/strong&gt; for long-running operations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session persistence&lt;/strong&gt;, so Claw keeps your conversation context across calls.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or just &lt;code&gt;npx openclaw-mcp&lt;/code&gt; if you want to poke at it in seconds. It's at v1.2.1 with full CI/CD.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest warning
&lt;/h2&gt;

&lt;p&gt;I'm not going to pretend this is a tame tool. &lt;strong&gt;Claw can go rogue if you don't set it up properly.&lt;/strong&gt; It's happened to me more than once: an agent with the ability to clone, edit and push, pointed at the wrong flow, will do exactly what you told it to and not at all what you meant. When it works it feels like magic; when it doesn't, it's a mess you have to clean up.&lt;/p&gt;

&lt;p&gt;Which is why the next thing I'm building is the opposite of open-ended: a code-forge where the flows are precisely defined and I work with predefined agents instead of hoping an open agent improvises correctly. MCP's improvisation is great for exploration and real trouble for unattended code changes. Know which one you're doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agent-to-tool vs. agent-to-agent
&lt;/h2&gt;

&lt;p&gt;Building this pushed me toward the other half of the picture, so I also built &lt;strong&gt;openclaw-a2a&lt;/strong&gt;, an implementation of Google's &lt;strong&gt;A2A (Agent2Agent) protocol v1.0&lt;/strong&gt;. And the thing worth saying out loud:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP and A2A aren't competitors. They're complements.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MCP&lt;/strong&gt; = an agent talks to tools. &lt;em&gt;Vertical.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A2A&lt;/strong&gt; = an agent talks to another agent. &lt;em&gt;Horizontal.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Today you have one agent doing one thing. The direction of travel is a network of agents, each good at something different, coordinating on their own, and that needs a protocol built for it, not a chat integration bolted on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it (carefully)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Bridge: &lt;strong&gt;&lt;a href="https://github.com/freema/openclaw-mcp" rel="noopener noreferrer"&gt;github.com/freema/openclaw-mcp&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A2A: &lt;strong&gt;&lt;a href="https://github.com/freema/openclaw-a2a" rel="noopener noreferrer"&gt;github.com/freema/openclaw-a2a&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Set the guardrails before you hand it the keys.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Do you see real potential in agent-to-agent, or is it still hype? I go back and forth on it myself.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>automation</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I gave Claude read access to my Google marketing stack. Now I just ask it questions.</title>
      <dc:creator>Tomas Grasl</dc:creator>
      <pubDate>Tue, 04 Aug 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/freema/i-gave-claude-read-access-to-my-google-marketing-stack-now-i-just-ask-it-questions-50b</link>
      <guid>https://dev.to/freema/i-gave-claude-read-access-to-my-google-marketing-stack-now-i-just-ask-it-questions-50b</guid>
      <description>&lt;p&gt;Opening Google Analytics to answer one question is a special kind of tax. You know the number is in there. You also know it's four clicks, two date pickers and a dimension dropdown away, and by the time you've found it you've forgotten what you wanted it for.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Metrifyr&lt;/strong&gt;: a &lt;em&gt;remote&lt;/em&gt; MCP server that puts my Google marketing stack behind my AI agent. Nothing to install: connect it once (Claude, Cursor, VS Code, any MCP client), then ask the question in plain language and it goes and gets the number. It's in the Cursor marketplace and the official MCP Registry, and the catalog has grown past a hundred tools, though, as you'll see, no single session loads them all.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's actually connected
&lt;/h2&gt;

&lt;p&gt;Metrifyr isn't a wrapper around one API. It federates the whole Google marketing surface behind a single MCP connection:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Analytics 4&lt;/strong&gt;: run reports, realtime, metadata, compare periods. Plus the admin side: create properties, data streams, conversion events, custom dimensions and metrics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search Console&lt;/strong&gt;: search analytics, URL inspection, sitemaps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AdSense&lt;/strong&gt;: accounts, earnings, payment history, revenue by keyword.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tag Manager&lt;/strong&gt;: read and audit containers, tags, triggers, variables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Ads&lt;/strong&gt;: campaign planning.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Connect it once, and the agent can reach across all of them in a single train of thought. "Which landing pages lost the most organic traffic last quarter, and were any of them earning AdSense revenue?" is one question to me. It's Search Console &lt;em&gt;and&lt;/em&gt; Analytics &lt;em&gt;and&lt;/em&gt; AdSense to the machine, joined without me opening a single tab.&lt;/p&gt;

&lt;h2&gt;
  
  
  Raw numbers are the boring part
&lt;/h2&gt;

&lt;p&gt;Pulling a GA4 report over MCP is table stakes. The part I actually care about is the layer on top, the analysis tools that answer the questions you'd otherwise pay an SEO consultant to run:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Content decay scan&lt;/strong&gt;: which pages are quietly bleeding traffic month over month.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Striking-distance optimizer&lt;/strong&gt;: the queries ranking positions 11 to 20, one nudge away from page one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keyword cannibalization&lt;/strong&gt;: where two of your own pages are fighting over the same query.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content opportunity finder&lt;/strong&gt; and &lt;strong&gt;competitor sitemap keywords&lt;/strong&gt;: gaps you're not covering that your competitors are.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PageSpeed / Core Web Vitals&lt;/strong&gt;, &lt;strong&gt;schema validation&lt;/strong&gt;, &lt;strong&gt;SEO audit&lt;/strong&gt;, &lt;strong&gt;IndexNow&lt;/strong&gt; submission, &lt;strong&gt;rank tracking&lt;/strong&gt;, &lt;strong&gt;Reddit topic mining&lt;/strong&gt;, &lt;strong&gt;Trends&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren't "fetch a metric." They're "look at my data and tell me where to spend my next hour." That's the difference between a dashboard and an assistant.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one tool that changed how I read my own traffic
&lt;/h2&gt;

&lt;p&gt;My favorite lives at that intersection: &lt;code&gt;adsense_keyword_revenue&lt;/code&gt;. It ranks your organic pages by &lt;strong&gt;real AdSense earnings&lt;/strong&gt;, not by clicks, joining Search Console click data with per-page AdSense earnings and computing page RPM.&lt;/p&gt;

&lt;p&gt;Suddenly a page with 200 clicks at a $12 RPM beats one with 2,000 clicks at $0.40. No Google dashboard shows you this view; the data lives in two different products that don't talk to each other. Over MCP, joining them is one tool call, and it completely reorders which pages are worth your time.&lt;/p&gt;

&lt;p&gt;That's the whole thesis in one tool: the value isn't the raw number, it's the &lt;em&gt;join across products&lt;/em&gt; that no single UI will do for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  But isn't a hundred tools a lot?
&lt;/h2&gt;

&lt;p&gt;If you've read my other posts, you know I bang on about keeping an MCP tool surface &lt;em&gt;small&lt;/em&gt;. Every tool is a tax on the agent's context. So a hundred-tool server should be exactly the mistake I warn against.&lt;/p&gt;

&lt;p&gt;It gets away with it because tools load &lt;strong&gt;per scope&lt;/strong&gt;. Connect only Search Console and your agent sees the Search Console tools, not the ninety it has no business calling. The catalog is large; what any one session actually loads is not, and it's bounded by which Google accounts you connected, not by a cap I picked. Same principle (small surface) enforced by your grants instead of by deletion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why MCP, and not another dashboard
&lt;/h2&gt;

&lt;p&gt;Every analytics product on earth already has a UI. The reason to expose this over MCP instead of building yet another chart:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The agent already has your context.&lt;/strong&gt; It knows what you shipped last week, what campaign you're worried about, what you asked five minutes ago. A dashboard makes you translate all of that into filters by hand. An MCP tool lets the agent do the translation and just show you the answer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data becomes composable.&lt;/strong&gt; Once GA4, Search Console and AdSense are all tools in the same context, the model chains them. No export-to-CSV, no VLOOKUP, no "let me pull this into a spreadsheet." The join happens in the conversation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read-only by default is a feature.&lt;/strong&gt; Most of what you want from marketing data is questions, not changes. The reporting surface is read-only; the handful of write actions (creating a GA4 property, a conversion event) are separate and explicit. Your agent can't accidentally reconfigure your analytics while answering a question about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pattern I keep coming back to
&lt;/h2&gt;

&lt;p&gt;This is the third or fourth MCP server I've built, and the same lesson keeps surfacing: &lt;strong&gt;the value isn't the API access, it's removing the translation step.&lt;/strong&gt; The data was always reachable. What changes is that you stop context-switching into four different tools to assemble an answer, and start getting the answer where you're already working.&lt;/p&gt;

&lt;p&gt;If you spend your week staring at GA4, Search Console and AdSense in separate tabs and stitching them together in your head, that stitching is exactly the job an agent with the right tools does for free.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://metrifyr.cloud" rel="noopener noreferrer"&gt;metrifyr.cloud&lt;/a&gt;: connect once, then just ask for your data.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What's the report you rebuild by hand every week? That's the one worth handing to an agent first.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>mcp</category>
    </item>
    <item>
      <title>"Developers Will Lose Their Jobs": How You Were All Wrong</title>
      <dc:creator>Tomas Grasl</dc:creator>
      <pubDate>Sun, 02 Aug 2026 17:56:50 +0000</pubDate>
      <link>https://dev.to/freema/developers-will-lose-their-jobs-how-you-were-all-wrong-1h5h</link>
      <guid>https://dev.to/freema/developers-will-lose-their-jobs-how-you-were-all-wrong-1h5h</guid>
      <description>&lt;p&gt;I don't write the code of our systems anymore. I write agents that write the code.&lt;/p&gt;

&lt;p&gt;And that is exactly why the job panic looks so silly from where I sit.&lt;/p&gt;

&lt;p&gt;I run a backend team at a Czech media house. Paywall, subscriptions, OAuth, CRM, mailing. Real systems with real money going through them. Most of my day now goes into rules, permissions, test gates and review steps for agents, not into functions. The work didn't disappear. It moved one layer up, and that layer is harder.&lt;/p&gt;

&lt;h2&gt;
  
  
  Every new name is a patch on the previous one
&lt;/h2&gt;

&lt;p&gt;Watch the vocabulary of the last four years. Prompt engineering. Context engineering. Harness engineering. Loop engineering. Now graph engineering.&lt;/p&gt;

&lt;p&gt;The community treats these like levels of enlightenment. They're not. They're workarounds. Each one exists because the previous one hit a wall.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2022, Prompt.&lt;/strong&gt; You polish one sentence. "You are an experienced traffic lawyer, what do I do if they clocked me at 150 in a village, asking for a friend." It was a prestigious, well paid job title. Then agents started doing 50 steps in a row and one beautiful sentence stopped mattering.&lt;br&gt;
Weakness: it doesn't scale past a single turn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2025, Context.&lt;/strong&gt; &lt;code&gt;agents.md&lt;/code&gt;, &lt;code&gt;.clinerules&lt;/code&gt;, repo conventions dumped into the window before the model touches anything. Stop guessing, here are the rules of this project.&lt;br&gt;
Weakness: the model knows what to do, but has nothing stopping it from doing something else.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2026, Harness.&lt;/strong&gt; Sandbox, tests, permissions, logs. The model is just an engine, the harness is the rig around it. There's a number going around that the same model jumps from 52% to 66% on coding tasks purely from a better harness, without anyone touching the weights. I can't verify that number, but the direction matches what I see: most of my quality gains in the last year came from the rig, not the model.&lt;br&gt;
Weakness: you're still the one handing out every task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Then, Loop.&lt;/strong&gt; "I don't write prompts anymore, I have loops that assign work to the model." You start it and go get coffee. It watches PRs, fixes CI, picks up feedback.&lt;br&gt;
Weakness: nondeterminism. Run it twice, get two different worlds. Fine for a side project, not fine for a paywall.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now, Graph.&lt;/strong&gt; Instead of a loop that improvises, you draw the thing. Code, then ALWAYS review, then merge. No guessing about order. Google reportedly rebuilt their agent dev kit from an agent runner into a graph engine for this reason.&lt;br&gt;
Weakness: unknown so far. There will be one. Probably that the graph itself becomes a codebase nobody wants to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The skill is spotting the ceiling, not learning the name
&lt;/h2&gt;

&lt;p&gt;Here's what I think people get wrong. They chase the vocabulary. New term drops, half the timeline rewrites their setup that weekend, usually because someone with a big following said so.&lt;/p&gt;

&lt;p&gt;The actual skill is different. It's looking at a layer and knowing quickly where its ceiling is, and which lever to pull so the output gets good. Not "which layer is currently correct", but "this one will break on step 30, so I need a gate there".&lt;/p&gt;

&lt;p&gt;You don't learn that from a thread. You learn it because you've watched it break a few dozen times. Which is a very old skill wearing a new hat.&lt;/p&gt;

&lt;h2&gt;
  
  
  What my day actually looks like
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I set the rules, the permissions, the test gates, the review steps.&lt;/li&gt;
&lt;li&gt;The agent works.&lt;/li&gt;
&lt;li&gt;I read diffs and say yes or no.&lt;/li&gt;
&lt;li&gt;When it gets stuck, I finish it by hand.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Less code written. More decisions made. And the decisions are the part that was always hard.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pattern nobody says out loud
&lt;/h2&gt;

&lt;p&gt;Look at the direction of that chain again. Prompt is a request. Graph is architecture.&lt;/p&gt;

&lt;p&gt;Every single layer added since 2022 exists to take freedom away from the model and give control back to a human. Context takes away guessing. Harness takes away access. Loop takes away idle time, and then graph takes away the loop's improvisation.&lt;/p&gt;

&lt;p&gt;The better the models get, the more control we take back. Not less.&lt;/p&gt;

&lt;p&gt;That's the opposite of the story being sold. "AI writes everything, developers become obsolete" doesn't survive five minutes of contact with a production system. Somebody has to decide where the review step goes, where the rollback goes, which permissions the agent never gets, and whether a PR that looks fine is actually going to break checkout on Friday evening.&lt;/p&gt;

&lt;p&gt;The people most sure that developers are finished are usually the people who have never run an agent against a real repo.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what's next
&lt;/h2&gt;

&lt;p&gt;I don't know.&lt;/p&gt;

&lt;p&gt;Maybe the abstraction gets good enough that we end up back at prompting. You say what you want, and underneath it a graph of loops does something nobody fully follows anymore. The circle closes.&lt;/p&gt;

&lt;p&gt;Even then, someone designs that graph. Someone maintains it. Someone gets paged when it merges garbage at 3am.&lt;/p&gt;

&lt;p&gt;Guess who.&lt;/p&gt;




&lt;p&gt;Not interested in which layer you're on. Where did you hit its ceiling? That's the more useful conversation.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>programming</category>
      <category>career</category>
    </item>
    <item>
      <title>Can we play a game on pixelden? Made my pixel art game portal playable inside Claude via MCP</title>
      <dc:creator>Tomas Grasl</dc:creator>
      <pubDate>Thu, 30 Jul 2026 20:01:58 +0000</pubDate>
      <link>https://dev.to/freema/can-we-play-a-game-on-pixelden-made-my-pixel-art-game-portal-playable-inside-claude-via-mcp-h4m</link>
      <guid>https://dev.to/freema/can-we-play-a-game-on-pixelden-made-my-pixel-art-game-portal-playable-inside-claude-via-mcp-h4m</guid>
      <description>&lt;p&gt;I hacked the new MCP UI extension 😎&lt;/p&gt;

&lt;p&gt;By which I mean I read the spec and used it exactly as documented, for a dumb little game. 😅&lt;/p&gt;

&lt;p&gt;MCP Apps is the official MCP UI extension. Short version: your server declares an HTML resource under ui://, links it to a tool via _meta.ui.resourceUri, and the host renders that HTML in a sandboxed iframe right in the conversation. The iframe talks back over JSON-RPC, so it can call tools. Not a rendered screenshot, a live UI.&lt;/p&gt;

&lt;p&gt;Everyone is shipping dashboards and forms with it. I put a game loop in there.&lt;/p&gt;

&lt;p&gt;The tool starts a run, the iframe is a real one button arcade game. When you crash, the widget sends the seed and the ticks you jumped at back to the server, the server replays them through the engine and computes the score. The model never touches the number.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.pixelden.io/play-in-claude" rel="noopener noreferrer"&gt;https://www.pixelden.io/play-in-claude&lt;/a&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>llm</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Claude Code plans, Cursor Composer executes, Claude reviews. I wired the three together.</title>
      <dc:creator>Tomas Grasl</dc:creator>
      <pubDate>Thu, 30 Jul 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/freema/claude-code-plans-cursor-composer-executes-claude-reviews-i-wired-the-three-together-ffc</link>
      <guid>https://dev.to/freema/claude-code-plans-cursor-composer-executes-claude-reviews-i-wired-the-three-together-ffc</guid>
      <description>&lt;p&gt;I was burning expensive Claude tokens on tasks a cheaper model could handle just fine. Renames, placeholder swaps, grinding through a well-scoped task list. That's not where Claude's magic is, and it's not where I want to spend the budget. So I stopped picking one tool and wired two together.&lt;/p&gt;

&lt;p&gt;After a few weeks of juggling terminals, the setup settled into three moves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Claude Code makes the plan.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cursor Composer 2 executes it.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude reviews the diff.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tokens saved, quality kept. I packaged it as a Claude Code plugin so I don't reinvent the hand-off every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just stay in Cursor?
&lt;/h2&gt;

&lt;p&gt;Because Claude Code has a real edge in planning, and it's not only the model. It's the whole rig: long-context sessions, subagents, the TUI, the way tools compose. The plans it produces are consistently good, and I didn't want to give that up to save money on execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just stay in Claude?
&lt;/h2&gt;

&lt;p&gt;Because Composer 2 is genuinely good at day-to-day coding and one-shot work. File edits, applying diffs, churning through a well-scoped task list in force mode. Cursor and Composer are heavily tuned for exactly this CLI use case. Fast, and safe enough for mechanical changes.&lt;/p&gt;

&lt;p&gt;Picking one meant either overpaying for execution or under-planning. Wiring them together meant each tool does the part it's best at.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually use it for
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bigger refactors&lt;/strong&gt;: think out loud with Claude, then let Composer grind through the mechanical edits in the background. Multilingual site integration, where Composer swaps every hard-coded string for a placeholder, is a perfect fit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Rename X to Y across the codebase and update the tests"&lt;/strong&gt;: classic Composer territory. No reason to spend Claude cycles on it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;E2E testing via a browser MCP&lt;/strong&gt;: one slash command spins it up. Composer 2 is more than enough here; I don't need a frontier model to click through a page and assert on it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What didn't work
&lt;/h2&gt;

&lt;p&gt;Letting Cursor do the &lt;em&gt;planning&lt;/em&gt;. It's fine. But Claude's planning loop is better, and that's the one place I don't compromise. The lesson: don't split work by tool arbitrarily; split it by what each tool is actually best at. Planning to Claude, mechanical execution to Composer, review back to Claude.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's in the plugin
&lt;/h2&gt;

&lt;p&gt;Rather than re-do the hand-off by hand each time, I shipped it as a Claude Code plugin: eight &lt;code&gt;/cursor:*&lt;/code&gt; commands (delegate, status, result, cancel, resume, browser-verify, sessions, setup) plus a &lt;code&gt;cursor-runner&lt;/code&gt; subagent for automatic delegation. Zero runtime dependencies, MIT.&lt;/p&gt;

&lt;p&gt;Heavily inspired by &lt;code&gt;openai/codex-plugin-cc&lt;/code&gt;, which pulls the same trick with GPT/Codex, credit where it's due.&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;The interesting shift here isn't "use a cheaper model." It's treating your coding agents like a small team with different strengths instead of looking for one model to rule them all. A planner, an executor, a reviewer. They just happen to be three different CLIs, and the plugin is the glue that makes the hand-off free.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/freema/cursor-plugin-cc" rel="noopener noreferrer"&gt;github.com/freema/cursor-plugin-cc&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Are you running a multi-tool coding setup, or still trying to make one model do everything? Curious how others split the work.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>productivity</category>
      <category>cursor</category>
    </item>
    <item>
      <title>I've built a handful of MCP servers. Here's what separates a good one from a demo.</title>
      <dc:creator>Tomas Grasl</dc:creator>
      <pubDate>Tue, 28 Jul 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/freema/ive-built-a-handful-of-mcp-servers-heres-what-separates-a-good-one-from-a-demo-4i4f</link>
      <guid>https://dev.to/freema/ive-built-a-handful-of-mcp-servers-heres-what-separates-a-good-one-from-a-demo-4i4f</guid>
      <description>&lt;p&gt;This year I've built more MCP servers than I meant to, across three pretty different shapes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/freema/vellum" rel="noopener noreferrer"&gt;vellum&lt;/a&gt;&lt;/strong&gt;: a self-hosted server over a folder of markdown, so my agent has a memory that's just files I own. (Open source, MIT.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metrifyr&lt;/strong&gt;: a marketing-data server that puts GA4, Search Console, AdSense and Tag Manager behind one connection.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;read-only gateway&lt;/strong&gt; over a company's internal user-data stack, federating half a dozen internal services behind one audited MCP surface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Personal, product, enterprise. Totally different data, totally different stakes. And yet the things that made each one &lt;em&gt;good&lt;/em&gt;, versus a flashy demo that falls over the moment a real agent uses it in anger, were the same every time. Here are the seven that keep recurring.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Every tool you expose is a tax on the agent's context
&lt;/h2&gt;

&lt;p&gt;This is the one nobody warns you about. Every tool definition (name, description, JSON schema) gets loaded into the model's context on &lt;em&gt;every single request&lt;/em&gt;, whether or not it's ever called. Twenty tools of boilerplate and the agent is reading pages of plumbing before it touches your data.&lt;/p&gt;

&lt;p&gt;So the design pressure runs the opposite way from a normal API: fewer, broader tools beat many narrow ones. vellum has 15 core tools and I fought to keep it there. If a tool doesn't earn its slot in the context window on most requests, it shouldn't be a tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Tools are for acting. Resources are for reading.
&lt;/h2&gt;

&lt;p&gt;The corollary to #1. Most servers expose everything (including "read this thing") as a tool. But MCP has a better primitive for reading: &lt;strong&gt;resources&lt;/strong&gt;. In vellum, every note is a resource at a stable URI (&lt;code&gt;vellum://note/projects/x.md&lt;/code&gt;). The agent attaches a document by reference instead of spending a tool round-trip to fetch it, and it can &lt;em&gt;subscribe&lt;/em&gt; to that URI and get told the moment the note changes.&lt;/p&gt;

&lt;p&gt;Reading through a resource costs no tool definition. Reading through a tool costs one on every request. Use the right primitive.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Fail closed on auth, fail open on limits
&lt;/h2&gt;

&lt;p&gt;A token with no grants should see &lt;strong&gt;zero tools&lt;/strong&gt;: not an error when it tries to call one, but genuinely nothing in &lt;code&gt;tools/list&lt;/code&gt;. Authorization fails &lt;em&gt;closed&lt;/em&gt;. Rate limiters, on the other hand, should fail &lt;em&gt;open&lt;/em&gt;: if the limiter itself breaks, you degrade to serving the request, not to locking everyone out. Getting these two backwards is how you either leak capability or take yourself down.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Annotate what's safe and what isn't
&lt;/h2&gt;

&lt;p&gt;MCP lets you tag tools with hints: &lt;code&gt;readOnlyHint&lt;/code&gt;, &lt;code&gt;destructiveHint&lt;/code&gt;, &lt;code&gt;idempotentHint&lt;/code&gt;. Use them. They're how a well-behaved client knows it can call your search tool freely but should think twice before your delete tool. On the marketing server this is the line between "the agent can answer any question about your analytics" and "the agent can reconfigure your analytics", and the annotations are what keep those two worlds visibly separate.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Writes must be conflict-safe
&lt;/h2&gt;

&lt;p&gt;The moment more than one thing can write (an agent &lt;em&gt;and&lt;/em&gt; a human, or two agents) last-write-wins silently eats data. vellum returns a content hash on every read, and a write fails on hash mismatch instead of clobbering. It's optimistic concurrency, the same trick databases have used forever, and it turns "the agent overwrote my edit" from a support ticket into a retry.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. For anything touching real data: read-only, and audit everything
&lt;/h2&gt;

&lt;p&gt;The enterprise gateway taught me this one hard. When an MCP server sits in front of a company's actual user data, the default posture is read-only, every tool call is logged with who called it and what came back, and any PII in a response comes back as a hash, not the raw value. An agent is a new kind of caller; treat it like one you'll have to explain to a security review later, because you will.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Tell the agent how to use you
&lt;/h2&gt;

&lt;p&gt;MCP has a spot in the handshake for &lt;strong&gt;server instructions&lt;/strong&gt;: a short document the agent reads before it does anything. This is where you say "notes are vault-relative paths," "prefer patch over rewrite," "empty query with tags is a pure tag filter." It's the difference between an agent that fumbles your API and one that uses it the way you intended on the first try. Most servers leave it blank. Don't.&lt;/p&gt;

&lt;h2&gt;
  
  
  One gotcha that cost me an afternoon
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;structuredContent&lt;/code&gt; roughly &lt;em&gt;doubles&lt;/em&gt; your response size: the payload is serialized into the response twice. If you've got size-based metrics or limits, they'll suddenly read high for no obvious reason. Recalibrate them, or you'll spend an afternoon chasing a leak that isn't there.&lt;/p&gt;




&lt;p&gt;None of this is about clever features. Across a note vault, a marketing stack and an enterprise gateway, the servers that behaved well were the ones that respected the agent's context, used the right primitive for each job, and were honest about what was safe to call. The demo is easy. The seven things above are what make it survive contact with a real agent.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you're building on MCP: which of these bit you first? For me it was #1. I over-exposed tools on my first server and watched the agent drown in its own toolbox.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Mozilla adopted my Firefox DevTools MCP, but I didn't build it to browse the web</title>
      <dc:creator>Tomas Grasl</dc:creator>
      <pubDate>Thu, 23 Jul 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/freema/mozilla-adopted-my-firefox-devtools-mcp-but-i-didnt-build-it-to-browse-the-web-5142</link>
      <guid>https://dev.to/freema/mozilla-adopted-my-firefox-devtools-mcp-but-i-didnt-build-it-to-browse-the-web-5142</guid>
      <description>&lt;p&gt;A little while ago I wrote an MCP server that lets an AI agent inspect and control Firefox through the Remote Debugging Protocol. It got adopted into the Mozilla org. That's a nice flex, and I'll take it, but it buries the more useful story, which is &lt;em&gt;why&lt;/em&gt; I built it. It wasn't to give my agent a browser. It was to make my agent write its own tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real problem: e2e tests, not browsing
&lt;/h2&gt;

&lt;p&gt;Multi-agent orchestration I've mostly got a handle on. My actual pain, the thing that eats my evenings, is end-to-end testing. Nobody wants to write it, it rots the moment the UI shifts, and it's exactly the kind of mechanical-but-fiddly work you'd love to hand off.&lt;/p&gt;

&lt;p&gt;So the flow I actually care about looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Claude has a "test skill" that tells it to &lt;strong&gt;click through the app&lt;/strong&gt; using the Firefox MCP: open the page, fill the form, follow the flow, read the DOM back.&lt;/li&gt;
&lt;li&gt;Once it's walked the flow and knows what the app does, it &lt;strong&gt;writes a Cypress or Playwright test&lt;/strong&gt; for it.&lt;/li&gt;
&lt;li&gt;From then on it just &lt;strong&gt;runs the test&lt;/strong&gt;. The MCP was scaffolding to author the test, not a permanent dependency.&lt;/li&gt;
&lt;li&gt;If it gets stuck, it pings me and I finish that one by hand.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result is a reasonably tight dev loop: the AI builds a thing, tests the thing, and knows when it broke the thing. The browser control is a means to that end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Firefox, when Chrome DevTools MCP exists
&lt;/h2&gt;

&lt;p&gt;Fair question. Chrome's DevTools MCP does most of the same moves. Three reasons I reached for Firefox anyway, and none of them is "Firefox is better at everything."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's stricter about standards.&lt;/strong&gt; Firefox holds the line on W3C (CSS Grid inspection, layout edge cases) where Chrome quietly papers over your mistakes. That sounds like a downside until you realize it's exactly what you want from a &lt;em&gt;test&lt;/em&gt; browser. If a layout is going to break, I'd rather it break in the strict engine during testing than in front of a user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Leaner to run on a server.&lt;/strong&gt; I don't run this on my laptop. It runs on a server, next to a Claude CLI or Codex session and whatever else is going. When you're stacking agents on one box, a lighter headless browser is the difference between fitting and swapping. And for my setup, headless Firefox is the lighter one. (Measure it on your own box; it depends on what you load.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's open source.&lt;/strong&gt; For something I want to run on my own infrastructure and tinker with, that speaks for itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this says about MCP servers in general
&lt;/h2&gt;

&lt;p&gt;The thing I keep taking away from this one: &lt;strong&gt;the best MCP servers are scaffolding for a workflow, not a permanent appendage.&lt;/strong&gt; The Firefox MCP is at its most valuable in the minutes it takes the agent to learn a flow and codify it into a real test. After that, a plain &lt;code&gt;playwright test&lt;/code&gt; command does the job: no agent, no MCP, no tokens.&lt;/p&gt;

&lt;p&gt;Designing for that ("help the agent build something that outlives the session" instead of "keep the agent calling me forever") is a different mindset than most tool servers take. And it happens to produce the tool I actually reach for every day.&lt;/p&gt;

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

&lt;p&gt;If your pain is the same as mine, writing and maintaining e2e tests, this flow is worth stealing even if you never touch Firefox: let the agent explore the app through a browser MCP, then have it emit a real Playwright/Cypress test you can run headless forever after.&lt;/p&gt;

&lt;p&gt;The repo lives in the Mozilla org now: &lt;strong&gt;&lt;a href="https://github.com/mozilla/firefox-devtools-mcp" rel="noopener noreferrer"&gt;mozilla/firefox-devtools-mcp&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What's your current e2e testing loop: hand-written, recorded, or generated? I'm always looking to tighten mine.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>firefox</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
