<?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: Gaurav Dadhich</title>
    <description>The latest articles on DEV Community by Gaurav Dadhich (@gaurav_dadhich).</description>
    <link>https://dev.to/gaurav_dadhich</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%2F3739855%2F2c23ebe1-927c-4ca9-b99a-1a21f939a0ad.png</url>
      <title>DEV Community: Gaurav Dadhich</title>
      <link>https://dev.to/gaurav_dadhich</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gaurav_dadhich"/>
    <language>en</language>
    <item>
      <title>Why AI Forgets: Why ChatGPT, Claude, and Gemini Don't Remember You Well</title>
      <dc:creator>Gaurav Dadhich</dc:creator>
      <pubDate>Wed, 26 Aug 2026 08:42:22 +0000</pubDate>
      <link>https://dev.to/gaurav_dadhich/why-ai-forgets-why-chatgpt-claude-and-gemini-dont-remember-you-well-3igo</link>
      <guid>https://dev.to/gaurav_dadhich/why-ai-forgets-why-chatgpt-claude-and-gemini-dont-remember-you-well-3igo</guid>
      <description>&lt;p&gt;I had a conversation with Claude last Wednesday. Spent maybe forty minutes walking it through a product launch plan: the positioning, the pricing tiers, the three segments we were targeting. Good conversation, felt productive. On Thursday morning I opened a new chat to refine the email sequence for that same launch.&lt;/p&gt;

&lt;p&gt;"Could you tell me more about your product?" . Forty minutes of context, gone. Either corrupted or half-remembered.&lt;/p&gt;

&lt;p&gt;If you use &lt;a href="https://www.maximem.ai/blog/ai-apps-memory" rel="noopener noreferrer"&gt;AI tools regularly&lt;/a&gt;, you've had this moment. You've had it dozens of times. And at some point you stopped being surprised and started being annoyed. You copy-paste the same background into every new conversation. You keep a Google Doc of "stuff to tell the AI." You re-explain your job, your preferences, your constraints - over and over, to the most capable technology ever built.&lt;/p&gt;

&lt;p&gt;Here's the thing nobody tells you clearly: your AI isn't forgetting. It never knew you in the first place. What felt like a relationship was a transaction.&lt;/p&gt;

&lt;h1&gt;
  
  
  Every conversation is an island
&lt;/h1&gt;

&lt;p&gt;The way these tools work under the hood is genuinely counterintuitive. When you chat with ChatGPT or Claude or Gemini, the model doesn't "learn" from your conversation. Nothing you say changes the model itself. It processes your messages, generates a response, and when the session ends, the next session starts from a blank slate.&lt;/p&gt;

&lt;p&gt;Think of it like calling a support hotline where the agents don't have a CRM. You might get someone brilliant. They might solve your problem in five minutes flat. But tomorrow when you call back? Different person. No notes in the file. You start from "can I get your account number?"&lt;/p&gt;

&lt;p&gt;There's a technical term for this. AI conversations are stateless. Each one exists independently, unconnected to anything before or after it.&lt;/p&gt;

&lt;p&gt;Three specific things make this worse than it sounds:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The token window rolls over.&lt;/strong&gt; Even within a single conversation, there's a limit to how much the model can "see." ChatGPT and Claude have large context windows (128K-1M tokens depending upon the model), roughly 200 pages of text for some models. But in long conversations, older messages start falling off the edge. The model isn't summarizing them or filing them away. They're just not there anymore. Ask about something from the beginning of a two-hour coding session and you might get a blank stare. Plus there is something called as context-rot. In simple words, the more information you give them, the more they hallucinate on that information. They barely remember about 20-30% of it accurately. Not ideal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Each platform is its own silo.&lt;/strong&gt; This one is brutal for anyone who uses more than one AI tool. And most power users do: ChatGPT for brainstorming, Claude for longer analysis, Gemini when you need something integrated with Google, Perplexity for research. Each one knows a fragment of you. None of them share notes. Your preferences in Claude don't exist in ChatGPT. That Perplexity research session about competitor pricing? Invisible to every other tool you use.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The "memory" features are thinner than they look.&lt;/strong&gt; ChatGPT does have a memory feature: it will store facts like your name, your job, that you prefer bullet points over paragraphs. Claude has something similar. But these are stored facts, not understanding. ChatGPT remembered that I work in AI infrastructure. It did not remember the forty-minute launch strategy. That's the gap. Flat facts versus actual context from working sessions.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  "But ChatGPT, Claude has memory now"
&lt;/h1&gt;

&lt;p&gt;I know. I've tested it extensively. Let me tell you what it actually does.&lt;/p&gt;

&lt;p&gt;ChatGPT's memory system keeps lightweight summaries of your recent conversations, roughly your last fifteen chats. Not the AI's responses, just compressed sketches of what you typed. It also stores explicit facts about you (your name, role, preferences) that get injected into every single prompt, whether relevant or not. One researcher who dug into this found 33 stored facts about himself riding along in every conversation. His gym schedule was being fed to ChatGPT when he asked about Python debugging.&lt;/p&gt;

&lt;p&gt;Claude takes a different approach. Instead of pre-loading summaries, it has retrieval tools it can use to search your past conversations. The operative word is "can." Claude has to decide, mid-conversation, that looking into your history would help. Sometimes it does. Sometimes it doesn't think to check. When it works, it's genuinely impressive; you get detailed context from three weeks ago. When it doesn't, you get nothing. [We did a deep dive into how each platform handles this](&lt;a href="https://www.maximem.ai/blog/ai-apps-memory" rel="noopener noreferrer"&gt;https://www.maximem.ai/blog/ai-apps-memory&lt;/a&gt;) and the short version is: all three major platforms are engineering their own isolated memory, and none of them talk to each other.&lt;/p&gt;

&lt;p&gt;Gemini's situation is different again. Strong integration with your Google ecosystem; it can pull from Drive, Gmail, Calendar. But your conversations with Gemini don't inform your conversations with ChatGPT or Claude. It's another walled garden, just with Google-shaped walls.&lt;/p&gt;

&lt;p&gt;The pattern: three platforms, three separate attempts at memory, three siloed systems that can't see past their own borders.&lt;/p&gt;

&lt;h1&gt;
  
  
  Bigger context windows won't fix this
&lt;/h1&gt;

&lt;p&gt;I hear this one constantly. "GPT-5 will have a million-token &lt;a href="https://www.maximem.ai/glossary/context-window" rel="noopener noreferrer"&gt;context window&lt;/a&gt;, so the forgetting problem goes away." It won't, here's why:&lt;/p&gt;

&lt;p&gt;A larger context window makes individual conversations longer. It doesn't make them connected. You can fit an entire book into a single session, sure. But close that session and open a new one tomorrow; same blank slate, no matter how many tokens the window supports.&lt;/p&gt;

&lt;p&gt;There's also a cost issue nobody likes talking about. Context isn't free. Every token you stuff into that window costs money on the API side and computation on the &lt;a href="https://www.maximem.ai/glossary/inference" rel="noopener noreferrer"&gt;inference&lt;/a&gt; side. The bigger the window, the more expensive every single message becomes. A 200K-token conversation with Claude Sonnet costs meaningfully more than a fresh 2K-token one. The platforms aren't going to solve this by just making windows bigger, because that doesn't scale economically.&lt;/p&gt;

&lt;p&gt;And even within a long conversation, there's a well-documented problem researchers call "lost in the middle"; models pay more attention to information at the beginning and end of their context window and tend to miss things buried in the center. Bigger windows can actually make this worse, not better. More hay, same needle.&lt;/p&gt;

&lt;p&gt;## What you're actually losing&lt;/p&gt;

&lt;p&gt;Let's be concrete about the cost. Cottrill Research reported in 2025 that nearly half of knowledge workers spend one to five hours every day searching for information they've already accessed. UC Irvine's research on interruptions found it takes about 23 minutes to get back in the zone after each break in focus. Every time you re-explain your role, your project constraints, your communication preferences; that's an interruption. A self-inflicted one, caused by tools that should already know this.&lt;/p&gt;

&lt;p&gt;We tracked our own stats when we helped users create their AI Year End Wrapped. Users on average had revised their prompt in over half of all conversations. Half the time, they're teaching the AI something it should already know.&lt;/p&gt;

&lt;p&gt;Multiply this by every AI tool you use. Multiply by every working day. The cumulative friction is enormous, and it's invisible because it's distributed across hundreds of small moments. No single re-explanation feels like a big deal. But together, they eat hours every week.&lt;/p&gt;

&lt;p&gt;The subtler cost is harder to measure: the good conversations that never happen because you don't bother setting up the context. You wanted to ask Claude to refine yesterday's strategy. But that would mean re-pasting the strategy, re-explaining the market context, re-describing the team dynamics. So you just... don't. You work from the draft you already have, even though a fresh pass with full context might have caught the flaw in your pricing model.&lt;/p&gt;

&lt;h1&gt;
  
  
  What you can do about it right now
&lt;/h1&gt;

&lt;p&gt;Three options, escalating in effectiveness.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The manual workaround. Keep a document&lt;/strong&gt;: some people use Notion, some use a simple text file: with your standard context: role, current projects, communication preferences, key constraints. Paste it at the top of every new conversation. It works. It's tedious. It doesn't transfer between platforms. You become your own memory system, which, let's be honest, defeats a lot of the purpose of using AI in the first place.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use the platform-native memory features&lt;/strong&gt;. Turn on ChatGPT's memory. Use Claude Projects to store background documents. Set up Gemini's Google &lt;a href="https://www.maximem.ai/glossary/integrations" rel="noopener noreferrer"&gt;integrations&lt;/a&gt;. This gets you further. But each one only works inside its own platform. If you're a multi-platform user; and the data suggests most regular AI users are, you're still maintaining separate contexts everywhere.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use a&lt;/strong&gt; &lt;a href="https://www.maximem.ai/cross-app-memory" rel="noopener noreferrer"&gt;&lt;strong&gt;cross-app memory&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;layer&lt;/strong&gt;. This is a newer category. Tools that sit above all your AI platforms and maintain one unified memory across everything. A Chrome extension, typically, that captures context from your conversations and makes it available everywhere you go. What you discussed in ChatGPT on Monday is available when you open Claude on Wednesday.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We built &lt;a href="https://www.maximem.ai/vity" rel="noopener noreferrer"&gt;Vity&lt;/a&gt; for exactly this reason. It's a free Chrome extension that syncs your memory across ChatGPT, Claude, Gemini, Perplexity, DeepSeek, Grok; ten platforms currently. It captures context from your conversations (with your consent, always), then proactively surfaces relevant memories as you type in any supported app. You approve what gets included. Nothing gets injected without you seeing it first. The whole thing runs on an encrypted vault that we can't read even if we wanted to.&lt;/p&gt;

&lt;p&gt;But my bias is showing. If you want an apples-to-apples look at how &lt;a href="https://www.maximem.ai/vity" rel="noopener noreferrer"&gt;Vity&lt;/a&gt; stacks up against other options in this category, we published a &lt;a href="https://www.maximem.ai/compare/maximem-vity-vs-mem0-vs-supermemory" rel="noopener noreferrer"&gt;detailed comparison of Vity, Mem0, and Supermemory&lt;/a&gt; that covers setup, platform support, privacy architecture, and memory depth. Read it and decide for yourself.&lt;/p&gt;

&lt;h1&gt;
  
  
  The forgetting problem isn't going away on its own
&lt;/h1&gt;

&lt;p&gt;Here's the uncomfortable truth. Smarter models don't fix statelessness. GPT-5 will be smarter than GPT-4. It will still start every conversation from zero. Claude's next version will be more capable. It still won't know what you told the current version last Tuesday.&lt;/p&gt;

&lt;p&gt;The forgetting isn't a technical limitation that next year's model update solves. It's an architectural choice. Each conversation is designed to be independent. That's actually useful for privacy and safety; it means your conversations don't bleed into each other or into other people's experiences. But it also means no AI tool, on its own, will ever "remember you" the way a colleague does.&lt;/p&gt;

&lt;p&gt;Memory has to be solved as a separate layer. Something that sits above the models, captures what matters, and brings it back when it's relevant. Whether that's Vity, or one of the alternatives, or something you build yourself with a text file and discipline; the core insight is the same.&lt;/p&gt;

&lt;p&gt;Your AI tools are not going to start remembering you. You have to give them a memory.&lt;/p&gt;

&lt;p&gt;---&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Frequently Asked Questions&lt;/strong&gt;
&lt;/h1&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why does ChatGPT forget everything between conversations?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;ChatGPT conversations are stateless by design. Each new chat starts with no knowledge of previous sessions. ChatGPT does have a built-in memory feature that stores basic facts about you, but it only retains lightweight summaries of recent chats and doesn't carry over the detailed context from working sessions.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Can AI remember things between conversations?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Not natively. ChatGPT, Claude, and Gemini each have limited memory features that work within their own platform, but none of them share memory across platforms. Cross-app memory tools like &lt;a href="https://www.maximem.ai/vity" rel="noopener noreferrer"&gt;Vity&lt;/a&gt; solve this by maintaining a single memory layer that works across all major AI platforms.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Does Claude have memory like ChatGPT?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Claude has a different approach. Instead of pre-loading conversation summaries, Claude uses retrieval tools that can search your past conversations on demand. It offers a larger context window (upto 1 M tokens) for longer sessions, but like ChatGPT, its memory only works within Claude itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How do I make AI remember my preferences?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Three options: (1) manually paste your preferences into every new chat, (2) use built-in features like ChatGPT Memory or Claude Projects within each platform, or (3) use a cross-app memory extension that syncs your preferences across all AI platforms automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What is cross-app&lt;/strong&gt; &lt;a href="https://www.maximem.ai/glossary/episodic-memory-ai" rel="noopener noreferrer"&gt;&lt;strong&gt;AI memory&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Cross-app AI memory is a layer that captures context from your conversations across multiple AI platforms (ChatGPT, Claude, Gemini, Perplexity, etc.) and makes it available everywhere. Instead of each AI tool having its own isolated memory, you have one unified memory that follows you. Learn more about [how cross-app memory works](&lt;a href="https://www.maximem.ai/cross-app-memory" rel="noopener noreferrer"&gt;https://www.maximem.ai/cross-app-memory&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is there a way to sync memory across ChatGPT and Claude?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not through the platforms themselves: ChatGPT and Claude don't share data with each other. Cross-app memory tools bridge this gap. &lt;a href="https://www.maximem.ai/vity" rel="noopener noreferrer"&gt;Vity's Chrome extension (which also works with OpenClaw)&lt;/a&gt; captures context from both platforms and surfaces relevant memories in either one, so preferences and project context travel with you.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do AI agents remember previous conversations across sessions?
&lt;/h3&gt;

&lt;p&gt;They do not on their own. Something outside the model has to decide what is worth keeping from a conversation, store it, and put the relevant part back into context on a later turn. Without that layer every session starts from zero, no matter how capable the model is.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is this different for developers building agents than for people using ChatGPT?
&lt;/h3&gt;

&lt;p&gt;The cause is identical and the fix is not. A person can work around it with a pinned prompt or a memory feature. A developer shipping to thousands of users needs the layer itself: capture, retrieval, conflict resolution when a user changes their mind, and deletion that actually propagates.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does a bigger context window not solve it?
&lt;/h3&gt;

&lt;p&gt;A larger window extends how long one conversation runs before it degrades. It changes nothing about what happens when that conversation closes, and it raises cost on every turn because you reload the same history each time.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>MCP 2026-07-28: 20 Breaking Changes and the Errors They Cause</title>
      <dc:creator>Gaurav Dadhich</dc:creator>
      <pubDate>Tue, 25 Aug 2026 06:38:27 +0000</pubDate>
      <link>https://dev.to/gaurav_dadhich/mcp-2026-07-28-20-breaking-changes-and-the-errors-they-cause-og2</link>
      <guid>https://dev.to/gaurav_dadhich/mcp-2026-07-28-20-breaking-changes-and-the-errors-they-cause-og2</guid>
      <description>&lt;p&gt;The &lt;a href="https://www.maximem.ai/glossary/mcp" rel="noopener noreferrer"&gt;Model Context Protocol&lt;/a&gt; shipped revision &lt;code&gt;2026-07-28&lt;/code&gt; on 28 July 2026, and it is the largest change to the protocol since it launched. Sessions are gone. The &lt;code&gt;initialize&lt;/code&gt; handshake is gone. Servers can no longer initiate requests at all.&lt;/p&gt;

&lt;p&gt;If you run an MCP server, the useful thing to know first is that nothing breaks today on its own. A server speaking the old revision keeps working with clients speaking the old revision, and &lt;a href="https://claude.com/blog/bringing-mcp-2026-07-28-to-claude" rel="noopener noreferrer"&gt;Anthropic&lt;/a&gt; has said support is rolling out across Claude products without announcing general availability or per-product dates. The break arrives when a client upgrades underneath you, and when it arrives it is total in both directions, because a modern client cannot talk to a legacy server and a legacy client has no mechanism at all for talking forward to a modern one.&lt;/p&gt;

&lt;p&gt;Also gone in this revision: &lt;code&gt;ping&lt;/code&gt;, &lt;code&gt;logging/setLevel&lt;/code&gt;, SSE stream resumability, &lt;code&gt;resources/subscribe&lt;/code&gt;, &lt;code&gt;resources/unsubscribe&lt;/code&gt;, &lt;code&gt;tasks/list&lt;/code&gt; and &lt;code&gt;tasks/result&lt;/code&gt;. Roots, sampling, logging and Dynamic Client Registration are deprecated with a twelve month clock running on them.&lt;/p&gt;

&lt;p&gt;Below is the full diff, every error you will hit while upgrading with the fix for each, and the one deadline where the specification and the release blog give different answers, which matters because the blog is the document most people will read.&lt;/p&gt;




&lt;h2&gt;
  
  
  What changed in MCP 2026-07-28
&lt;/h2&gt;

&lt;p&gt;Eight things shipped, and they are easier to understand as one decision with seven consequences than as eight independent features.&lt;/p&gt;

&lt;p&gt;Everything traces back to one decision, &lt;a href="https://blog.modelcontextprotocol.io/posts/2026-07-28/" rel="noopener noreferrer"&gt;SEP-2575 and SEP-2567&lt;/a&gt;, which together make the protocol stateless. There is no handshake and no session identifier. Every request carries its own protocol version and client capabilities in &lt;code&gt;_meta&lt;/code&gt;, and a new &lt;code&gt;server/discover&lt;/code&gt; method replaces the capability exchange that used to happen at connection time. Servers must implement &lt;code&gt;server/discover&lt;/code&gt;; clients may skip it entirely and handle the error instead.&lt;/p&gt;

&lt;p&gt;Everything else follows from that. Because servers can no longer hold a connection open, they can no longer initiate requests, so &lt;strong&gt;Multi Round-Trip Requests&lt;/strong&gt; (SEP-2322) replace &lt;code&gt;sampling/createMessage&lt;/code&gt;, &lt;code&gt;elicitation/create&lt;/code&gt; and &lt;code&gt;roots/list&lt;/code&gt; with a pattern where the server returns &lt;code&gt;resultType: "input_required"&lt;/code&gt; and the client re-sends the original call with the answers attached. Because the operation can no longer be inferred from a session, it moves into HTTP headers, so &lt;code&gt;Mcp-Method&lt;/code&gt; and &lt;code&gt;Mcp-Name&lt;/code&gt; (SEP-2243) are now required and a load balancer can route on them without parsing the body. Because list results no longer vary per connection, they become cacheable, so &lt;code&gt;ttlMs&lt;/code&gt; and &lt;code&gt;cacheScope&lt;/code&gt; (SEP-2549) are now non-optional fields on six result types.&lt;/p&gt;

&lt;p&gt;Four further changes are less structural but worth knowing. Authorization hardens across six SEPs, with RFC 9207 issuer validation now mandatory on the client side and Dynamic Client Registration formally deprecated in favour of &lt;a href="https://workos.com/blog/mcp-2026-spec-agent-authentication" rel="noopener noreferrer"&gt;Client ID Metadata Documents&lt;/a&gt;. Tasks moves out of the core protocol into an opt-in extension (SEP-2663) with a redesigned polling API. A formal extensions framework (SEP-2133) lets anyone ship a protocol feature under a reverse-DNS identifier without a specification change. And a real deprecation policy (SEP-2596) arrives with a twelve month minimum window, a published registry, and SDK-level obligations to mark deprecated surfaces.&lt;/p&gt;

&lt;p&gt;Here is the whole revision on one screen.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;2025-11-25&lt;/code&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;2026-07-28&lt;/code&gt;&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Handshake&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;initialize&lt;/code&gt; plus &lt;code&gt;notifications/initialized&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;None. Per-request &lt;code&gt;_meta&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Sessions&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;Mcp-Session-Id&lt;/code&gt; header, 404 to reinitialise, DELETE to end&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Removed. Explicit application-level handles&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Capabilities&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Negotiated once per connection&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Declared on every request&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Discovery&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;InitializeResult&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;server/discover&lt;/code&gt;, server MUST implement, client MAY call&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Transport&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;POST plus GET SSE, resumable via &lt;code&gt;Last-Event-ID&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;POST only. A modern-only server SHOULD return &lt;code&gt;405&lt;/code&gt; on GET and DELETE. No resumability&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Routing&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Operation in the JSON body. &lt;code&gt;MCP-Protocol-Version&lt;/code&gt; header required since &lt;code&gt;2025-06-18&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Two new required headers, &lt;code&gt;Mcp-Method&lt;/code&gt; on every request and &lt;code&gt;Mcp-Name&lt;/code&gt; on three of them&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Server to client requests&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;sampling/createMessage&lt;/code&gt;, &lt;code&gt;elicitation/create&lt;/code&gt;, &lt;code&gt;roots/list&lt;/code&gt; on a live stream&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;MRTR: &lt;code&gt;resultType: "input_required"&lt;/code&gt; plus &lt;code&gt;requestState&lt;/code&gt;, retried by the client with a new JSON-RPC id&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Subscriptions&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;resources/subscribe&lt;/code&gt; plus the GET SSE stream&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;subscriptions/listen&lt;/code&gt; with an explicit notification filter&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Caching&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;ttlMs&lt;/code&gt; and &lt;code&gt;cacheScope&lt;/code&gt; on six result types (the release blog says four and the changelog says five; the schema and the caching page say six)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Long running work&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Tasks, experimental, in core. Blocking &lt;code&gt;tasks/result&lt;/code&gt;, plus &lt;code&gt;tasks/list&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;io.modelcontextprotocol/tasks&lt;/code&gt; extension. Polling &lt;code&gt;tasks/get&lt;/code&gt;, plus &lt;code&gt;tasks/update&lt;/code&gt;. No &lt;code&gt;tasks/list&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Client registration&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;DCR (MAY) plus CIMD (SHOULD)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;DCR deprecated. CIMD is the path. &lt;code&gt;application_type&lt;/code&gt; now MUST&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Issuer validation&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Not required&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;RFC 9207 &lt;code&gt;iss&lt;/code&gt; validation, MUST, including on error responses&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Logging&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;logging&lt;/code&gt; capability, &lt;code&gt;logging/setLevel&lt;/code&gt;, &lt;code&gt;notifications/message&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Deprecated. Per-request log level in &lt;code&gt;_meta&lt;/code&gt;, stderr, OpenTelemetry&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Liveness&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;ping&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Removed&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Resource not found&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;-32002&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;-32602&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;MCP error codes&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;-32042&lt;/code&gt; (URL elicitation required)&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Three new codes, &lt;code&gt;-32020&lt;/code&gt; to &lt;code&gt;-32022&lt;/code&gt;, inside a reserved &lt;code&gt;-32020&lt;/code&gt; to &lt;code&gt;-32099&lt;/code&gt; block. &lt;code&gt;-32042&lt;/code&gt; retired&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Tool schemas&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;JSON Schema 2020-12 as default dialect&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Full 2020-12 keyword set. Network &lt;code&gt;$ref&lt;/code&gt; forbidden by default. DoS bounds required&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Tool lists&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;May vary per connection&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;MUST NOT vary per connection. SHOULD be deterministically ordered&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Extensibility&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;experimental&lt;/code&gt; capability bag&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Formal extensions framework, reverse-DNS identifiers, opt-in, independently versioned&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Deprecation&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Ad hoc&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Formal policy. Twelve month floor, published registry, SDK obligations, ninety day security exception&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Result envelope&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Bare result object&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Required &lt;code&gt;resultType&lt;/code&gt; on every result&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  What breaks, and what does not
&lt;/h2&gt;

&lt;p&gt;Compatibility is published in the specification itself, and that matrix has seven rows rather than the four most write-ups have been reproducing. The two rows that are usually dropped are the actionable ones.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Client&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Server&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Outcome&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Modern&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Modern&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Works&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Modern&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Legacy&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Fails&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Dual-era&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Modern&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Works&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Dual-era&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Legacy&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Works&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Legacy&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Modern&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Fails.&lt;/strong&gt; Legacy clients have no fall-forward mechanism&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Legacy&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Dual-era&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Works&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Legacy&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Legacy&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Works per the legacy revision&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Modern means &lt;code&gt;2026-07-28&lt;/code&gt; and later, with per-request metadata. Legacy means &lt;code&gt;2025-11-25&lt;/code&gt; and earlier, with the &lt;code&gt;initialize&lt;/code&gt; handshake. Dual-era means an implementation that speaks both, which is the only posture that is safe if you have real users.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://pypi.org/project/mcp/" rel="noopener noreferrer"&gt;Python SDK v2&lt;/a&gt; gives you this by default, and it is worth understanding the mechanism rather than assuming it. &lt;code&gt;Server.run&lt;/code&gt; drives a dual-era loop in which &lt;strong&gt;the client's first request decides the connection's era, once&lt;/strong&gt;. A request carrying the &lt;code&gt;2026-07-28&lt;/code&gt; per-request &lt;code&gt;_meta&lt;/code&gt; envelope opens a modern connection; anything else, including an &lt;code&gt;initialize&lt;/code&gt; handshake, opens a legacy one. A later claim from the other era is then refused: &lt;code&gt;initialize&lt;/code&gt; on a modern connection returns &lt;code&gt;UNSUPPORTED_PROTOCOL_VERSION&lt;/code&gt; naming the versions served, and an enveloped request on a legacy connection returns &lt;code&gt;INVALID_REQUEST&lt;/code&gt;. So a v2 server serves both eras, per connection, not per request. One caveat that is not in the release notes and that I found in the source: HTTP era routing is header-based today, with body-primary classification marked as a follow-up.&lt;/p&gt;

&lt;p&gt;Twenty things break. Here they are by severity, where total means the implementation stops working entirely rather than degrading.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Change&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;What it breaks&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Severity&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;initialize&lt;/code&gt; and &lt;code&gt;notifications/initialized&lt;/code&gt; removed&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Every client and server implementing the handshake&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Total&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;Mcp-Session-Id&lt;/code&gt; and sessions removed&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Any server holding per-session state, any client resuming a session&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Total&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Per-request &lt;code&gt;_meta&lt;/code&gt; with &lt;code&gt;protocolVersion&lt;/code&gt; and &lt;code&gt;clientCapabilities&lt;/code&gt; now required&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Any request without them returns &lt;code&gt;-32602&lt;/code&gt; and HTTP &lt;code&gt;400&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Total&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;MCP-Protocol-Version&lt;/code&gt; header required and must match the body&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Mismatch returns &lt;code&gt;400&lt;/code&gt; with &lt;code&gt;-32020&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Total&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;Mcp-Method&lt;/code&gt; required on all requests, &lt;code&gt;Mcp-Name&lt;/code&gt; on three of them&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Any hand-rolled HTTP client&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Total&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Server-initiated requests forbidden, MRTR replaces them&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Every server using sampling, elicitation or roots&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Total&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;The GET SSE stream is gone and resumability is removed. A modern-only server SHOULD answer GET and DELETE with &lt;code&gt;405&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Any client relying on the GET stream or on &lt;code&gt;Last-Event-ID&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Total&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;resources/subscribe&lt;/code&gt; and &lt;code&gt;resources/unsubscribe&lt;/code&gt; removed&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Any resource-subscription client&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Total&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Tasks redesigned and moved to an extension&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Everyone on the experimental &lt;code&gt;2025-11-25&lt;/code&gt; Tasks API&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Total, for tasks users&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;resultType&lt;/code&gt; required on every result&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Clients not defaulting an absent value to &lt;code&gt;"complete"&lt;/code&gt;, or not handling &lt;code&gt;"input_required"&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;High&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Resource not found moves from &lt;code&gt;-32002&lt;/code&gt; to &lt;code&gt;-32602&lt;/code&gt;, and &lt;code&gt;-32042&lt;/code&gt; (URL elicitation required) must no longer be emitted&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Any client matching on either literal code&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;High&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;notifications/cancelled&lt;/code&gt; is stdio-only. Streamable HTTP defines no client-to-server notifications; closing the SSE response stream is the cancellation signal&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Any HTTP client that sends it, and any server that only cancels on receiving it&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;High&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;ping&lt;/code&gt;, &lt;code&gt;logging/setLevel&lt;/code&gt; and &lt;code&gt;notifications/roots/list_changed&lt;/code&gt; removed&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Health-check loops and log-level control&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;High&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;notifications/elicitation/complete&lt;/code&gt; and &lt;code&gt;elicitationId&lt;/code&gt; removed&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;URL-mode elicitation correlation&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;High&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Tool lists MUST NOT vary per connection&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Any server personalising &lt;code&gt;tools/list&lt;/code&gt; per session rather than per token&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;High&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Any JSON Schema 2020-12 keyword is now allowed, but network &lt;code&gt;$ref&lt;/code&gt; resolution MUST be off by default and composition keywords need resource bounds&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Servers relying on remote &lt;code&gt;$ref&lt;/code&gt; resolution&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Medium&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;An invalid &lt;code&gt;x-mcp-header&lt;/code&gt; forces the client to drop the tool from &lt;code&gt;tools/list&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Silent tool disappearance&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Medium&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;ttlMs&lt;/code&gt; and &lt;code&gt;cacheScope&lt;/code&gt; are non-optional on six result types&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Servers omitting them are non-conformant&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Medium&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;DCR deprecated and &lt;code&gt;application_type&lt;/code&gt; now required&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;OIDC-strict authorization servers rejecting native redirects&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Medium&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;RFC 9207 &lt;code&gt;iss&lt;/code&gt; validation now MUST on the client side&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Clients that skip it are non-conformant&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Medium&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;What does not break is worth stating too, because it is more than you would expect. The stdio message framing is unchanged. Tools, resources, prompts, completion, pagination and progress keep their shapes. Elicitation survives in both form and URL modes, just delivered differently. And roots, sampling and logging are deprecated rather than removed, which means they are annotation-only and continue working for at least twelve months.&lt;/p&gt;

&lt;p&gt;There is one trap in era detection that is worth its own paragraph, because it is the thing implementations will get wrong, and the rules differ by transport.&lt;/p&gt;

&lt;p&gt;On HTTP you attempt a modern request and fall back on &lt;code&gt;400 Bad Request&lt;/code&gt;, except that a modern server also returns &lt;code&gt;400&lt;/code&gt; for &lt;code&gt;UnsupportedProtocolVersionError&lt;/code&gt;, for &lt;code&gt;MissingRequiredClientCapabilityError&lt;/code&gt;, and for header validation failures, so the specification says you SHOULD inspect the body before concluding anything. On stdio you probe with &lt;code&gt;server/discover&lt;/code&gt;, and there the rule is stronger: the fallback &lt;strong&gt;MUST NOT&lt;/strong&gt; be keyed to one specific error code. Era is a property of the server rather than of an individual request, so cache the determination for the lifetime of the server process on stdio, or of the origin on HTTP.&lt;/p&gt;

&lt;p&gt;One consequence of choosing dual-era that is easy to miss: the &lt;code&gt;405&lt;/code&gt; guidance for GET and DELETE is written for servers that support &lt;strong&gt;only&lt;/strong&gt; this revision. If you are serving both eras you still need the GET stream for legacy clients, so do not blanket-405 it.&lt;/p&gt;

&lt;h2&gt;
  
  
  It is also worth being straight about a tension in the messaging around all this. The operator of &lt;a href="https://glama.ai" rel="noopener noreferrer"&gt;Glama&lt;/a&gt;, who runs the largest open source MCP server index, wrote on &lt;a href="https://news.ycombinator.com/item?id=49088058" rel="noopener noreferrer"&gt;Hacker News&lt;/a&gt; that "the new protocol is wire-incompatible in both directions. This means that many of the servers/clients will need to be refactored (not enough to just update the SDK). It will take time and it will be messy." A maintainer in the same thread wrote that "this protocol change doesn't require you to do anything to existing running MCP code." Both statements are true, about different situations. The second is true of a deployment nobody touches. The first is true the moment anything on the other end of the wire moves.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Every error you will hit upgrading to MCP 2026-07-28
&lt;/h2&gt;

&lt;p&gt;These are ordered roughly by how likely you are to see them.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Unsupported protocol version&lt;/code&gt; after upgrading, error code &lt;code&gt;-32022&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This is the two eras failing to talk, and it is the most common thing you will see this week. The error carries the useful data in &lt;code&gt;error.data&lt;/code&gt;:&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;"jsonrpc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"error"&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;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-32022&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Unsupported protocol version"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"data"&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;"supported"&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;"2026-07-28"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-11-25"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"requested"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1900-01-01"&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;If &lt;code&gt;data.supported&lt;/code&gt; contains only old revisions, the server has not been upgraded. If it contains only &lt;code&gt;2026-07-28&lt;/code&gt;, the client has not. The fix in both directions is to serve both eras rather than to pick one, and the practical route to that is an SDK bump rather than hand-rolling the negotiation, because the negotiation has more edge cases than it looks like.&lt;/p&gt;

&lt;p&gt;One thing you cannot fix from the client side: a legacy client hitting a modern-only server. There is no fall-forward path in the older revisions, so that combination fails and will keep failing until the client updates. If you operate the server, this is the argument for staying dual-era well past the point where it feels necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;400 Bad Request&lt;/code&gt; with a &lt;code&gt;HeaderMismatch&lt;/code&gt; error, code &lt;code&gt;-32020&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Three headers are now required on every Streamable HTTP POST, and their values must match the body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/mcp&lt;/span&gt; &lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;MCP-Protocol-Version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2026-07-28&lt;/span&gt;
&lt;span class="na"&gt;Mcp-Method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tools/call&lt;/span&gt;
&lt;span class="na"&gt;Mcp-Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;search&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is worth stating the scope of these precisely, because it is easy to over-apply them. &lt;code&gt;Mcp-Method&lt;/code&gt; is required on all requests. In the core protocol &lt;code&gt;Mcp-Name&lt;/code&gt; is required only on &lt;code&gt;tools/call&lt;/code&gt;, &lt;code&gt;resources/read&lt;/code&gt; and &lt;code&gt;prompts/get&lt;/code&gt;, where it carries &lt;code&gt;params.name&lt;/code&gt; or &lt;code&gt;params.uri&lt;/code&gt;. Sending &lt;code&gt;Mcp-Name&lt;/code&gt; on a &lt;code&gt;tools/list&lt;/code&gt; is not what the specification asks for.&lt;/p&gt;

&lt;p&gt;The tasks extension then adds three more. SEP-2663 requires that &lt;code&gt;tasks/get&lt;/code&gt;, &lt;code&gt;tasks/update&lt;/code&gt; and &lt;code&gt;tasks/cancel&lt;/code&gt; over Streamable HTTP set &lt;code&gt;Mcp-Name&lt;/code&gt; to &lt;code&gt;params.taskId&lt;/code&gt;, so that "transport intermediaries and load balancers [can] route subsequent requests for the same task to the server instance holding its state, which is typically required for correctness." Worth sitting with that sentence for a moment. It is discussed further below.&lt;/p&gt;

&lt;p&gt;Note also that &lt;code&gt;MCP-Protocol-Version&lt;/code&gt; is not new. It has been required on HTTP since &lt;code&gt;2025-06-18&lt;/code&gt;. The two genuinely new mandatory headers are &lt;code&gt;Mcp-Method&lt;/code&gt; and &lt;code&gt;Mcp-Name&lt;/code&gt;, plus any &lt;code&gt;Mcp-Param-*&lt;/code&gt; your tools opt into.&lt;/p&gt;

&lt;p&gt;Header names are case-insensitive and header values are case-sensitive, and for integers the comparison should be numeric rather than string, so &lt;code&gt;42.0&lt;/code&gt; and &lt;code&gt;42&lt;/code&gt; match.&lt;/p&gt;

&lt;p&gt;There is a real caveat, and it was published a week before the specification landed. &lt;a href="https://agentgateway.dev/blog/2026-07-21-stateless-mcp-still-needs-mcp-native-dataplane/" rel="noopener noreferrer"&gt;Christian Posta at Solo.io pointed out&lt;/a&gt; that headers can lie: an attacker sends &lt;code&gt;Mcp-Name: echo&lt;/code&gt; in the header while the body calls &lt;code&gt;printEnv&lt;/code&gt;, and a proxy that allowlists on headers alone waves it through.&lt;/p&gt;

&lt;p&gt;Two mitigations exist. A server that processes the body MUST reject mismatches with &lt;code&gt;-32020&lt;/code&gt;. And intermediaries enforcing policy on mirrored headers SHOULD verify that &lt;code&gt;MCP-Protocol-Version&lt;/code&gt; indicates a revision requiring header-body validation, and SHOULD reject rather than trust the headers otherwise. Both are correct. The second is also a SHOULD placed on the component with the least incentive to comply, and it requires the intermediary to be MCP-version-aware, which is precisely the MCP-native dataplane Posta is arguing for. His post ends with a working fix rather than a dead end. Read it that way, and treat these headers as a routing hint rather than an authorization fact.&lt;/p&gt;

&lt;p&gt;There is an operational failure here that has nothing to do with your code. Check whether your reverse proxy, your CDN, or your API gateway strips unknown request headers, because these headers will vanish silently on the way to your server and every request will fail validation for a reason that is invisible from either end.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your server-initiated requests stopped working
&lt;/h3&gt;

&lt;p&gt;Servers cannot originate requests any more. This is not a restriction on when they may do it; there is no &lt;code&gt;ServerRequest&lt;/code&gt; union in the schema at all. &lt;code&gt;sampling/createMessage&lt;/code&gt;, &lt;code&gt;elicitation/create&lt;/code&gt; and &lt;code&gt;roots/list&lt;/code&gt; still exist as types, but only ever as payloads inside a result.&lt;/p&gt;

&lt;p&gt;MRTR is the replacement. Your server returns an incomplete result naming what it needs:&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;"jsonrpc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"result"&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;"resultType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"input_required"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"inputRequests"&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;"github_login"&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;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"elicitation/create"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"params"&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;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"form"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Please provide your GitHub username"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"requestedSchema"&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"properties"&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;"name"&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&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="nl"&gt;"required"&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;"name"&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;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"requestState"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AEAD-protected blob"&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;The client gathers the input and re-sends the original request with &lt;code&gt;inputResponses&lt;/code&gt; and the &lt;code&gt;requestState&lt;/code&gt; echoed back byte for byte, using a &lt;strong&gt;new&lt;/strong&gt; JSON-RPC id, because the specification treats the retry as an independent request.&lt;/p&gt;

&lt;p&gt;Six rules will bite you if you skip them. &lt;code&gt;InputRequiredResult&lt;/code&gt; is permitted only on &lt;code&gt;tools/call&lt;/code&gt;, &lt;code&gt;prompts/get&lt;/code&gt; and &lt;code&gt;resources/read&lt;/code&gt;, and servers MUST NOT send it on anything else. Clients MUST NOT inspect, parse or modify &lt;code&gt;requestState&lt;/code&gt;, and MUST NOT include one on the retry if the server did not send one. Servers MUST NOT send an &lt;code&gt;inputRequest&lt;/code&gt; type the client did not declare on that particular request. Servers MUST NOT assume the client will ever fulfil the request or retry at all, which means every MRTR exchange needs a timeout and a clean path to giving up. And &lt;code&gt;inputRequests&lt;/code&gt; and &lt;code&gt;requestState&lt;/code&gt; apply only to the retry of that one request, never to anything the client has in flight in parallel.&lt;/p&gt;

&lt;p&gt;The sixth is the one that will produce a crash rather than a bug report. &lt;code&gt;inputRequests&lt;/code&gt; &lt;strong&gt;is optional.&lt;/strong&gt; The schema requires at least one of &lt;code&gt;inputRequests&lt;/code&gt; or &lt;code&gt;requestState&lt;/code&gt;, and it names the case where only the state is present: load shedding. A server under pressure can hand back &lt;code&gt;requestState&lt;/code&gt; alone, and the specification says the client MAY then simply retry immediately. Any client that writes &lt;code&gt;for key in result.inputRequests&lt;/code&gt; throws on that response, at precisely the moment the server is least able to absorb a retry storm.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;MissingRequiredClientCapability&lt;/code&gt;, error code &lt;code&gt;-32021&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Capabilities are now declared per request rather than once per connection, and a server may not rely on one the client did not send on that specific request. When it needs something undeclared it returns &lt;code&gt;-32021&lt;/code&gt; with the missing capabilities listed in &lt;code&gt;data.requiredCapabilities&lt;/code&gt;, and on HTTP the status is &lt;code&gt;400&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On the client side, stop treating capabilities as connection setup. They belong in &lt;code&gt;_meta&lt;/code&gt; on every call:&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="nl"&gt;"_meta"&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;"io.modelcontextprotocol/protocolVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-07-28"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"io.modelcontextprotocol/clientCapabilities"&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;"elicitation"&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="nl"&gt;"io.modelcontextprotocol/clientInfo"&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"my-app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0"&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;&lt;code&gt;protocolVersion&lt;/code&gt; and &lt;code&gt;clientCapabilities&lt;/code&gt; are required. &lt;code&gt;clientInfo&lt;/code&gt; is optional but you should send it, and the specification is clear that neither &lt;code&gt;clientInfo&lt;/code&gt; nor &lt;code&gt;serverInfo&lt;/code&gt; is verified by the protocol, so nothing should make a security decision based on either.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resource not found now returns &lt;code&gt;-32602&lt;/code&gt;, not &lt;code&gt;-32002&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The error code layout changed underneath everyone. Two codes that shipped in &lt;code&gt;2025-11-25&lt;/code&gt; are retired, and three new ones arrive in a newly reserved block.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Code&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Shipped in&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Status in &lt;code&gt;2026-07-28&lt;/code&gt;&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;-32002&lt;/code&gt;, resource not found&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;2025-11-25&lt;/code&gt; and earlier&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Retired. Use &lt;code&gt;-32602&lt;/code&gt;. Clients SHOULD keep accepting it from older servers&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;-32042&lt;/code&gt;, URL elicitation required&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;2025-11-25&lt;/code&gt; only&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Retired. Implementations of this revision MUST NOT emit it&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;-32020&lt;/code&gt;, header mismatch&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;new&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Reserved block&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;-32021&lt;/code&gt;, missing required client capability&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;new&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Reserved block&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;-32022&lt;/code&gt;, unsupported protocol version&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;new&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Reserved block&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Codes from &lt;code&gt;-32020&lt;/code&gt; to &lt;code&gt;-32099&lt;/code&gt; are now reserved for the specification, and implementations must not emit codes in it that the specification has not defined. The range &lt;code&gt;-32000&lt;/code&gt; to &lt;code&gt;-32019&lt;/code&gt; is legacy, and apart from &lt;code&gt;-32002&lt;/code&gt; receivers must not assume any specific meaning for codes in it.&lt;/p&gt;

&lt;p&gt;One clarification, because several write-ups have this wrong, including an earlier version of this one. The three new codes were briefly numbered &lt;code&gt;-32001&lt;/code&gt;, &lt;code&gt;-32003&lt;/code&gt; and &lt;code&gt;-32004&lt;/code&gt; &lt;strong&gt;inside the&lt;/strong&gt; &lt;code&gt;2026-07-28&lt;/code&gt; &lt;strong&gt;draft cycle&lt;/strong&gt; and renumbered before release. They were never part of &lt;code&gt;2025-11-25&lt;/code&gt;, whose schema defines exactly one non-standard code, &lt;code&gt;-32042&lt;/code&gt;. So if you are migrating from a shipped &lt;code&gt;2025-11-25&lt;/code&gt; implementation, the codes that actually change under you are &lt;code&gt;-32002&lt;/code&gt; and &lt;code&gt;-32042&lt;/code&gt;. If you built against a release candidate, check for the old three.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your tool disappeared from &lt;code&gt;tools/list&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This is the most obscure genuinely breaking behaviour in the release, because it produces no JSON-RPC error, and because it is transport-dependent in a way that will waste somebody an afternoon.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;x-mcp-header&lt;/code&gt; is a new annotation that lets a server mark individual tool parameters to be mirrored into &lt;code&gt;Mcp-Param-{Name}&lt;/code&gt; HTTP headers, so that a gateway can route or rate-limit on a parameter value without reading the body. It is optional for servers and mandatory for clients to support. The constraints on it are strict: primitive types only, with &lt;code&gt;number&lt;/code&gt; explicitly not permitted while integer, string and boolean are; the property must be statically reachable from the schema root through a chain of &lt;code&gt;properties&lt;/code&gt; keys only, so nothing behind &lt;code&gt;items&lt;/code&gt;, &lt;code&gt;$ref&lt;/code&gt;, &lt;code&gt;oneOf&lt;/code&gt;, &lt;code&gt;anyOf&lt;/code&gt;, &lt;code&gt;allOf&lt;/code&gt;, &lt;code&gt;not&lt;/code&gt;, or &lt;code&gt;if&lt;/code&gt;/&lt;code&gt;then&lt;/code&gt;/&lt;code&gt;else&lt;/code&gt;; the value must be case-insensitively unique across the whole &lt;code&gt;inputSchema&lt;/code&gt;; annotated integers must sit within the JavaScript safe range; and the value must be a valid HTTP field-name token with no control characters.&lt;/p&gt;

&lt;p&gt;If any of those is violated, the client MUST exclude the tool from the result of &lt;code&gt;tools/list&lt;/code&gt;. There is no JSON-RPC error. The specification does ask clients to log a warning naming the tool and the reason, but that is a SHOULD and it surfaces in your client's log rather than to the model or the user, so the tool simply is not there any more and nothing in the conversation says why.&lt;/p&gt;

&lt;p&gt;What will actually cost you the afternoon is that this rule binds &lt;strong&gt;Streamable HTTP clients only&lt;/strong&gt;. Clients on other transports MAY ignore &lt;code&gt;x-mcp-header&lt;/code&gt; entirely. So the same server, with the same tool definition, can expose the tool over stdio on your laptop and hide it over HTTP in production.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;400&lt;/code&gt; with no obvious cause, and a missing &lt;code&gt;Accept&lt;/code&gt; header
&lt;/h3&gt;

&lt;p&gt;Not new, but hand-rolled clients get it wrong constantly and this revision gives them more opportunities to. The client MUST include an &lt;code&gt;Accept&lt;/code&gt; header listing both &lt;code&gt;application/json&lt;/code&gt; and &lt;code&gt;text/event-stream&lt;/code&gt;, because the server chooses between a single JSON response and an SSE stream and the client has to be ready for either.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;404 Not Found&lt;/code&gt; on a method the server does not implement
&lt;/h3&gt;

&lt;p&gt;This one is a trap for gateways and for anyone with retry logic. An unimplemented RPC method returns HTTP &lt;code&gt;404&lt;/code&gt; with JSON-RPC &lt;code&gt;-32601&lt;/code&gt;, which is deliberately distinguishable from a transport-level failure. Anything that treats &lt;code&gt;404&lt;/code&gt; as "this server is gone" and tears down the connection or fails over will misbehave against a perfectly healthy server that simply does not implement the method you asked for. Check the body before concluding anything about a &lt;code&gt;404&lt;/code&gt;, exactly as you already have to for a &lt;code&gt;400&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your list results are being served to the wrong tenant
&lt;/h3&gt;

&lt;p&gt;Not an error message, which is why it belongs here. &lt;code&gt;ttlMs&lt;/code&gt; and &lt;code&gt;cacheScope&lt;/code&gt; are now non-optional on six result types: &lt;code&gt;server/discover&lt;/code&gt;, &lt;code&gt;tools/list&lt;/code&gt;, &lt;code&gt;prompts/list&lt;/code&gt;, &lt;code&gt;resources/list&lt;/code&gt;, &lt;code&gt;resources/templates/list&lt;/code&gt; and &lt;code&gt;resources/read&lt;/code&gt;. Worth noting that the release blog lists four of those and the changelog lists five; the schema and the caching page say six, and they are the ones that count.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cacheScope&lt;/code&gt; takes &lt;code&gt;"public"&lt;/code&gt;, meaning any client, gateway or caching proxy may serve the response to any user, or &lt;code&gt;"private"&lt;/code&gt;, meaning it may be reused only within the same authorization context and MUST NOT be shared across contexts. Get this wrong on an authenticated endpoint and you have built a cross-tenant data leak with the protocol's blessing. The specification says so almost in those words: servers must be aware that a &lt;code&gt;"public"&lt;/code&gt; response may be shared between callers even when it comes from an authenticated endpoint.&lt;/p&gt;

&lt;p&gt;Two rules that follow. Results produced by an MRTR retry must never be cached, because they depend on inputs that are not part of the cache key. And clients SHOULD NOT treat &lt;code&gt;ttlMs&lt;/code&gt; as a polling interval; those that do poll MUST apply jitter and backoff, which is the single most likely way a naive client turns a TTL into a thundering herd.&lt;/p&gt;

&lt;h3&gt;
  
  
  Long-running jobs broke when sessions went away
&lt;/h3&gt;

&lt;p&gt;One of the sharper reactions on Hacker News was from someone who uses MCP servers to monitor workflows that run for days, and who wrote simply that "i use them to monitor workflows that takes days and now i have to make some changes."&lt;/p&gt;

&lt;p&gt;Tasks, now an extension, is the replacement, and it is a second migration for anyone who adopted the experimental API in &lt;code&gt;2025-11-25&lt;/code&gt;. What changed:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;2025-11-25&lt;/code&gt;, experimental&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;io.modelcontextprotocol/tasks&lt;/code&gt; extension&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Client opts in per request with a &lt;code&gt;task: {ttl}&lt;/code&gt; param&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;The server decides, unilaterally, per request&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;tasks/get&lt;/code&gt; plus a blocking &lt;code&gt;tasks/result&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;tasks/result&lt;/code&gt; removed; &lt;code&gt;tasks/get&lt;/code&gt; absorbs its job and polls, honouring &lt;code&gt;pollIntervalMs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;No client-to-server input method&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;tasks/update&lt;/code&gt; carrying &lt;code&gt;inputResponses&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;tasks/list&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Removed. There is no way to enumerate tasks&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;notifications/tasks/status&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;notifications/tasks&lt;/code&gt;, opt in via &lt;code&gt;subscriptions/listen&lt;/code&gt; with a &lt;code&gt;taskIds&lt;/code&gt; filter&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;ttl&lt;/code&gt;, &lt;code&gt;pollInterval&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;ttlMs&lt;/code&gt;, &lt;code&gt;pollIntervalMs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;tasks/cancel&lt;/code&gt; returns the task&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;tasks/cancel&lt;/code&gt; returns a bare acknowledgement; cancellation is cooperative and the server need only acknowledge&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Both parties can be requestors&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;tools/call&lt;/code&gt; only&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two consequences of that table deserve calling out. Because &lt;code&gt;tasks/list&lt;/code&gt; is gone, if your client loses a task id the task is unreachable, so persist task ids durably rather than holding them in memory. And because the extension must be negotiated in &lt;code&gt;_meta&lt;/code&gt; on each request, a server MUST NOT return a task handle to a client that did not declare the extension on that specific call.&lt;/p&gt;

&lt;p&gt;One detail that will catch people moving off &lt;code&gt;resources/subscribe&lt;/code&gt;: request-scoped notifications, meaning &lt;code&gt;notifications/progress&lt;/code&gt; and &lt;code&gt;notifications/message&lt;/code&gt;, still flow on the response stream of the request they belong to, &lt;strong&gt;not&lt;/strong&gt; on the &lt;code&gt;subscriptions/listen&lt;/code&gt; stream. And on stdio, if the connection drops the client MUST re-send &lt;code&gt;subscriptions/listen&lt;/code&gt;, because the server holds no subscription state across reconnections.&lt;/p&gt;

&lt;p&gt;One caveat before you build on this, and it is a real one. The extension's normative schema file is not published. The repository states it "is under development and is working towards implementing the changes described in SEP-2663", and carries a banner reading "&lt;strong&gt;not&lt;/strong&gt; an official extension and may change significantly or be discontinued", while the &lt;code&gt;2026-07-28&lt;/code&gt; changelog describes tasks as having moved into "an official extension." SEP-2663 itself still cites &lt;code&gt;-32003&lt;/code&gt;, an error code the shipped core renumbered to &lt;code&gt;-32021&lt;/code&gt;. Treat this part of the ecosystem as unfinished and budget for a second pass.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your traces and your latency numbers went wrong
&lt;/h3&gt;

&lt;p&gt;This one is quiet and it affects everyone who has &lt;a href="https://www.maximem.ai/glossary/observability" rel="noopener noreferrer"&gt;observability&lt;/a&gt; wired up. Because the MRTR retry MUST use a different JSON-RPC id from the original request, one logical operation now appears on the wire as several id-distinct requests with no correlation identifier between them.&lt;/p&gt;

&lt;p&gt;Every tool that keys on request id, which is all of them, therefore reports an inflated call count and, worse, excludes the interval where a human was actually deciding something. That interval is precisely the thing you care about for an elicitation-based confirmation. An &lt;a href="https://github.com/kerlenton/mcpsnoop/blob/main/docs/2026-07-28-mrtr-breaks-latency.md" rel="noopener noreferrer"&gt;analysis published on release day&lt;/a&gt; measured a six second operation reporting as two calls totalling one second. That is one scripted exchange against the author's own proxy rather than a survey, so treat it as an illustration of the mechanism rather than a measurement of the blast radius. The mechanism is the part that generalises.&lt;/p&gt;

&lt;p&gt;There is no protocol-level fix. Linkage has to be inferred, either from the opaque &lt;code&gt;requestState&lt;/code&gt; blob or by matching the key sets in &lt;code&gt;inputResponses&lt;/code&gt; against the &lt;code&gt;inputRequests&lt;/code&gt; that produced them. It is worth noticing that the same revision standardised W3C trace context propagation, with &lt;code&gt;traceparent&lt;/code&gt;, &lt;code&gt;tracestate&lt;/code&gt; and &lt;code&gt;baggage&lt;/code&gt; explicitly exempted from the reverse-DNS prefix rule in &lt;code&gt;_meta&lt;/code&gt;. The plumbing got better and the semantics got worse in the same release.&lt;/p&gt;

&lt;h3&gt;
  
  
  Authorization started failing on desktop and CLI clients
&lt;/h3&gt;

&lt;p&gt;If a client is going to break against a strict enterprise authorization server on day one, this is why. Clients MUST now specify &lt;code&gt;application_type&lt;/code&gt; during Dynamic Client Registration, and omitting it defaults to &lt;code&gt;"web"&lt;/code&gt; under OpenID Connect, which conflicts with the &lt;code&gt;localhost&lt;/code&gt; redirect URIs that desktop applications, mobile applications and CLI tools use. Native clients should send &lt;code&gt;application_type: "native"&lt;/code&gt;; genuinely remote browser-based clients should send &lt;code&gt;"web"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Two other authorization changes are worth checking before you ship. RFC 9207 issuer validation is now mandatory on the client side and it applies to error responses as well as success responses. You do decode the &lt;code&gt;iss&lt;/code&gt; value from the form-encoded response, and then you compare it as a literal string: no scheme or host case folding, no default-port elision, no trailing-slash handling and no percent-encoding normalisation. Note that authorization servers only SHOULD send &lt;code&gt;iss&lt;/code&gt;, so whether its absence is fatal depends on the server advertising &lt;code&gt;authorization_response_iss_parameter_supported&lt;/code&gt;. And persisted client credentials must now be keyed to the issuing authorization server's &lt;code&gt;issuer&lt;/code&gt;, so when the authorization server changes you must re-register rather than reuse.&lt;/p&gt;

&lt;h3&gt;
  
  
  SDK readiness, as of 29 July 2026
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;SDK&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Tier&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Version with &lt;code&gt;2026-07-28&lt;/code&gt;&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;TypeScript&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;@modelcontextprotocol/server@2.0.0&lt;/code&gt; and &lt;code&gt;@modelcontextprotocol/client@2.0.0&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Python&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;mcp==2.0.0&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Go&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;go-sdk v1.7.0&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;C#&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;ModelContextProtocol 2.0.0&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Rust&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;rmcp 3.0.0&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Java&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;No support yet&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Swift, Ruby, PHP, Kotlin&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;3&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;No support, no committed timeline&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two notes on that table. Java does have a &lt;code&gt;2.0.0&lt;/code&gt;, published on 11 June 2026, and it simply predates this revision; the jar contains &lt;code&gt;2025-11-25&lt;/code&gt; and earlier and no &lt;code&gt;2026-07-28&lt;/code&gt; at all. Java is a Tier 2 SDK, which carries a six month obligation, so support is due around January 2027. And on TypeScript, v2 is ESM-only, requires Node 20 or later, and splits the old monolith into separate server and client packages, which is a larger change than the version number suggests. There is a codemod: &lt;code&gt;npx @modelcontextprotocol/codemod v1-to-v2 .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you maintain a library that depends on an MCP SDK, put an upper bound on it today, &lt;code&gt;mcp&amp;gt;=1.28,&amp;lt;2&lt;/code&gt; or &lt;code&gt;@modelcontextprotocol/sdk@^1&lt;/code&gt;, so that v2 does not land on your users before you have decided how to handle it.&lt;/p&gt;







&lt;h2&gt;
  
  
  Before and after, in two pictures
&lt;/h2&gt;

&lt;p&gt;If you came here with a red terminal, that is the practical half. What follows is why any of it happened.&lt;/p&gt;

&lt;p&gt;Two diagrams, each showing the same two things: how the protocol deploys, and what actually goes over the wire. Those turned out to be the same question, which is the whole reason this revision exists.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.maximem.ai%2Fimg%2Fmcp-before-2025-11-25.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.maximem.ai%2Fimg%2Fmcp-before-2025-11-25.svg" alt="MCP client and server engagement before the 2026-07-28 revision: a stateful, connection-scoped pattern where a session is created at the handshake and pins every subsequent request to one server process" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That orange band running down the middle of the first diagram is the argument for the entire release. It is the session lifetime, and the line written across it says that every request underneath it must reach server instance number one. That constraint is not a &lt;a href="https://www.maximem.ai/glossary/deployment" rel="noopener noreferrer"&gt;deployment&lt;/a&gt; choice you made. It is a property of the protocol, because the negotiated capabilities and every in-flight request lived in one server process, so the load balancer had no option but to pin. Two of the three instances in that picture are unreachable for the duration of the session, the shared session store hanging off the side is pure protocol overhead you provisioned and paid for, and the gateway in the middle cannot route on anything useful because every call is &lt;code&gt;POST /mcp&lt;/code&gt; with the operation buried in the body.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.maximem.ai%2Fimg%2Fmcp-after-2026-07-28.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.maximem.ai%2Fimg%2Fmcp-after-2026-07-28.svg" alt="MCP client and server engagement after the 2026-07-28 revision: a stateless, self-describing pattern where every request carries its own version and capabilities and any server instance can answer it" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The payoff in the second diagram is small and easy to miss, so it is worth pointing at directly. Step three is a &lt;code&gt;tools/call&lt;/code&gt; that lands on instance three. Step four is that same logical call being retried, after the client gathers the input the server asked for, and it lands on instance two. A different box, mid-operation, and nothing breaks. That is what statelessness actually buys, and it is very hard to convey in prose.&lt;/p&gt;

&lt;p&gt;Two wins and two new burdens sit in the consequence strip at the bottom of the second diagram, and the mix is deliberate, because that is an accurate picture of the trade. Autoscale and serverless become native. In exchange, &lt;code&gt;requestState&lt;/code&gt; is now an attacker-controlled input you have to authenticate yourself, and the MRTR retry carries a new JSON-RPC id, which quietly breaks anything measuring latency by request id.&lt;/p&gt;







&lt;h2&gt;
  
  
  What the release fixed, and what it left alone
&lt;/h2&gt;

&lt;p&gt;MCP has been shipping for twenty months and accumulating a fairly specific critique record the whole time. The interesting way to read &lt;code&gt;2026-07-28&lt;/code&gt; is not as a list of features but as a response to that record, ranked by whether the specification deleted the thing being complained about. A protocol that removes the feature people objected to is conceding the argument in the plainest language available.&lt;/p&gt;

&lt;p&gt;Strongest evidence that this is what happened: the maintainers wrote the critique themselves, ten months before shipping the fix. From &lt;a href="https://blog.modelcontextprotocol.io/posts/2025-12-19-mcp-transport-future/" rel="noopener noreferrer"&gt;"Exploring the Future of MCP Transports"&lt;/a&gt;, published 19 December 2025:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Stateful connections force 'sticky' routing that pins traffic to specific servers, preventing effective auto-scaling."&lt;/p&gt;

&lt;p&gt;"Developers building simple, ephemeral tools are often required to manage complex backend storage to support basic multi-turn interactions."&lt;/p&gt;

&lt;p&gt;"Load balancers and API gateways must parse full JSON-RPC payloads to route traffic, rather than using standard HTTP patterns."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An earlier post, &lt;a href="https://blog.modelcontextprotocol.io/posts/2025-09-26-mcp-next-version-update/" rel="noopener noreferrer"&gt;"Update on the Next MCP Protocol Release"&lt;/a&gt; from September 2025, had already named horizontal scaling, long-running tasks, discovery, extensions and SDK &lt;a href="https://www.maximem.ai/glossary/compliance" rel="noopener noreferrer"&gt;compliance&lt;/a&gt; as the top five gaps.&lt;/p&gt;

&lt;p&gt;Five external critiques were louder than the rest. &lt;strong&gt;Statefulness and session affinity&lt;/strong&gt;, whose root cause was precise: the handshake negotiated capabilities per connection, the session identifier lived in the transport, and both meant every request had to reach the same process. &lt;a href="https://thenewstack.io/mcp-release-candidate-rewrite/" rel="noopener noreferrer"&gt;The New Stack&lt;/a&gt; put it as teams "paying to solve a distributed-systems problem the protocol had created for them." &lt;strong&gt;The tool-definition context tax&lt;/strong&gt;, where &lt;a href="https://www.apideck.com/blog/mcp-server-eating-context-window-cli-alternative" rel="noopener noreferrer"&gt;Apideck measured three MCP servers consuming 143,000 of a 200,000 token window&lt;/a&gt; before a single user message, and where the most damning source is Anthropic itself, which &lt;a href="https://www.anthropic.com/engineering/code-execution-with-mcp" rel="noopener noreferrer"&gt;published a method for taking 150,000 tokens down to 2,000&lt;/a&gt;, roughly a 98.7% reduction, by not using the protocol the way it was designed. &lt;strong&gt;&lt;a href="https://www.maximem.ai/glossary/prompt-injection" rel="noopener noreferrer"&gt;Prompt injection&lt;/a&gt;&lt;/strong&gt;, where &lt;a href="https://invariantlabs.ai/blog/mcp-github-vulnerability" rel="noopener noreferrer"&gt;Invariant Labs demonstrated data exfiltration through the GitHub MCP server&lt;/a&gt; and concluded that "GitHub alone cannot resolve this vulnerability through server-side patches," which is what makes it architectural rather than a bug. &lt;strong&gt;The absence of an authorization model&lt;/strong&gt;, summarised by &lt;a href="https://www.pomerium.com/blog/why-the-managed-context-protocol-mcp-spec-still-leaves-gaping-security-holes" rel="noopener noreferrer"&gt;Pomerium&lt;/a&gt; as "access is binary. Either a tool is exposed, or it isn't." And &lt;strong&gt;gateway hostility&lt;/strong&gt;, which is the same root cause as the first one seen from the operations side.&lt;/p&gt;

&lt;p&gt;Below those sit the rest: &lt;a href="https://www.microsoft.com/en-us/research/blog/tool-space-interference-in-the-mcp-era-designing-for-agent-compatibility-at-scale/" rel="noopener noreferrer"&gt;Microsoft Research measuring performance degradation of up to 85% as the tool space grows, along with 775 colliding tool names and the word&lt;/a&gt; &lt;code&gt;search&lt;/code&gt; &lt;a href="https://www.microsoft.com/en-us/research/blog/tool-space-interference-in-the-mcp-era-designing-for-agent-compatibility-at-scale/" rel="noopener noreferrer"&gt;appearing across 32 distinct servers&lt;/a&gt;; the OAuth and Dynamic Client Registration burden that &lt;a href="https://www.descope.com/blog/post/enterprise-mcp" rel="noopener noreferrer"&gt;Descope catalogued as an enterprise blocker&lt;/a&gt;; the &lt;a href="https://julsimon.medium.com/why-mcps-disregard-for-40-years-of-rpc-best-practices-will-burn-enterprises-8ef85ce5bc9b" rel="noopener noreferrer"&gt;missing distributed-systems contract around idempotency, deadlines and tracing&lt;/a&gt;; and the absence of any asynchronous operation model.&lt;/p&gt;

&lt;p&gt;One disclosure belongs here rather than in a footer, because it changes how you should read half of those links. &lt;a href="https://www.speakeasy.com" rel="noopener noreferrer"&gt;Speakeasy&lt;/a&gt;, &lt;a href="https://www.scalekit.com" rel="noopener noreferrer"&gt;Scalekit&lt;/a&gt;, Descope, &lt;a href="https://workos.com" rel="noopener noreferrer"&gt;WorkOS&lt;/a&gt;, Pomerium, &lt;a href="https://www.docker.com" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; and Apideck all sell products that exist because of the gaps they document. Their measurements are checkable and I have used several of them. Their framing is not neutral, and neither is mine, since Maximem ships tooling in this space too. Microsoft Research, &lt;a href="https://blog.trailofbits.com" rel="noopener noreferrer"&gt;Trail of Bits&lt;/a&gt;, Invariant Labs and Anthropic's own engineering blog are the cleanest sources in that list.&lt;/p&gt;

&lt;p&gt;So, the scorecard. Eighteen critiques, mapped against what actually shipped.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Critique&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;What &lt;code&gt;2026-07-28&lt;/code&gt; does&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Verdict&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Statefulness and session affinity&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Sessions, &lt;code&gt;initialize&lt;/code&gt; and the GET stream deleted. State becomes an explicit handle&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Solved&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Tool-definition context tax&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Deterministic tool ordering, cacheable &lt;code&gt;tools/list&lt;/code&gt;. Neither reduces what the model sees&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Untouched&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Prompt injection and the lethal trifecta&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Nothing&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Untouched&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;No authorization model&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Nothing. Scope step-up, which is often credited to this release, shipped in &lt;code&gt;2025-11-25&lt;/code&gt;. Modelling went to the &lt;code&gt;ext-auth&lt;/code&gt; extensions repo&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Untouched&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Tool poisoning, rug pulls, line jumping&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Nothing. Descriptions remain unsigned and mutable&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Untouched&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Tool-space interference, no namespacing&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Name-format rules, and clients "SHOULD implement a disambiguation strategy"&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Weak partial&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Auth complexity and the DCR burden&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;iss&lt;/code&gt; validation, credential-issuer binding and &lt;code&gt;application_type&lt;/code&gt; are real. But CIMD was already SHOULD and DCR already MAY in &lt;code&gt;2025-11-25&lt;/code&gt;, so the registration delta is largely a Deprecated label&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Partial&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Gateway, WAF, metering and caching hostility&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;Mcp-Method&lt;/code&gt; and &lt;code&gt;Mcp-Name&lt;/code&gt; headers, &lt;code&gt;ttlMs&lt;/code&gt; and &lt;code&gt;cacheScope&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Solved&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Missing distributed-systems contract&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Tracing yes, schema strictness yes, versioning discipline yes. Idempotency, deadlines and per-tool versioning no&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Partial&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;No long-running or async model&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Tasks extension with polling, updates, cancellation and a durability guarantee. But its normative schema is unpublished and its own repository says it is not an official extension&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Partial&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;No multi-tenancy primitive&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Nothing, beyond &lt;code&gt;cacheScope: "private"&lt;/code&gt; being authorization-context aware&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Untouched&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Transport churn&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;One transport story now, but this release &lt;strong&gt;is&lt;/strong&gt; churn: the third breaking transport shape in sixteen months. The improvement is that churn is finally governed by a deprecation policy&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Neutral&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Configuration fragility&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Removes session config as a failure class, adds header validation as a new one&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Neutral&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Latency at the call level&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;No handshake, so the first-call penalty disappears. Cacheable lists cut repeat cost&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Improved&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Registry and discovery&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;code&gt;server/discover&lt;/code&gt; per server. The registry itself still has no protocol-version field&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Partial&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Observability gap&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Trace context standardised, then MRTR breaks id-keyed measurement&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Mixed&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Risk stratification and cost opacity&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Nothing in core&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Untouched&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;SDK quality and compliance opacity&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;SDK tiering itself is SEP-1730, from October 2025. This release adds Tier 1 deprecation-marking obligations and conformance tests as a gate to Final&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Partial&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Three clear wins, nine partial or mixed, six untouched.&lt;/p&gt;

&lt;p&gt;I want to be explicit that I graded this twice, because the first pass was too generous. It credited this release with a scope step-up flow that shipped eight months earlier in &lt;code&gt;2025-11-25&lt;/code&gt;, rated long-running work solved on an extension whose normative schema does not exist, called transport churn solved in the release that caused it, and counted the registration changes as a fix when CIMD was already SHOULD and DCR already MAY. Correcting all four made the pattern sharper rather than softer, which is usually a sign the pattern is real rather than an artifact of how you drew the table.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;2026-07-28&lt;/code&gt; &lt;strong&gt;is an infrastructure release, not an agent-experience release.&lt;/strong&gt; Every problem that lives between a load balancer and a server process got fixed. Every problem that lives between a model and a tool description did not.&lt;/p&gt;

&lt;p&gt;Those untouched rows are worth sitting with, because they are the ones that most consistently kept MCP out of production. The context tax got deterministic tool ordering, which improves prompt-cache hit rates at the margin and is the entire response to a complaint that produced six separate front-page Hacker News threads and a first-party Anthropic post documenting a 98.7% workaround. Prompt injection got nothing, and tool descriptions are still unsigned, still mutable after a user has approved them, and still injected into the model's context at &lt;code&gt;tools/list&lt;/code&gt; time, which is the mechanism behind &lt;a href="https://blog.trailofbits.com/2025/04/21/jumping-the-line-how-mcp-servers-can-attack-you-before-you-ever-use-them/" rel="noopener noreferrer"&gt;what Trail of Bits named line jumping&lt;/a&gt; and the reason invocation-time approval was never the protection people assumed it was. Authorization modelling got nothing, and it is worth correcting a claim I have seen in several write-ups including my own first draft: the step-up flow with &lt;code&gt;insufficient_scope&lt;/code&gt; shipped in &lt;code&gt;2025-11-25&lt;/code&gt;, not here. What this release adds is authorization &lt;em&gt;hardening&lt;/em&gt;, which is real. Authorization &lt;em&gt;modelling&lt;/em&gt;, meaning per-tool scope and identity propagation into the tool, went to an extensions repository.&lt;/p&gt;

&lt;p&gt;Some fair objections, before the conclusion.&lt;/p&gt;

&lt;p&gt;No single revision could clear eighteen months of accumulated complaints, and that is true. The point was never the count. It is which half got cleared.&lt;/p&gt;

&lt;p&gt;A better objection is that statelessness &lt;strong&gt;is&lt;/strong&gt; an agent-experience change, and this one has more force than I would like. Fewer &lt;a href="https://www.maximem.ai/glossary/failure-modes" rel="noopener noreferrer"&gt;failure modes&lt;/a&gt;, no reconnection storms, no session dying mid-conversation, cheaper cold starts: reliability is part of the experience, and this release improves it. What it does not improve is anything the model can perceive. Same tool count, same trust in the descriptions, same token bill.&lt;/p&gt;

&lt;p&gt;Strongest of all is the argument that agent-experience work is happening in extensions now, and that the framework this release formalised is precisely what makes that possible. Go and look at the official &lt;a href="https://modelcontextprotocol.io/extensions/client-matrix" rel="noopener noreferrer"&gt;extension support matrix&lt;/a&gt;, though, which today lists nine clients. All nine support MCP Apps. Exactly one supports anything beyond it, and none supports OAuth Client Credentials. Extensions are opt-in on both ends, and the layer above the protocol is not there yet.&lt;/p&gt;

&lt;p&gt;That pattern is not carelessness. It is a boundary decision, and it is defensible. The protocol has drawn a line and put infrastructure concerns on its own side of it while leaving agent-experience concerns to the layer above. There is a serious argument that this is exactly what a protocol should do. It also means that if MCP was expensive for you last week because of tokens, or risky for you last week because of injection, this release changed nothing about either.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the release created
&lt;/h2&gt;

&lt;p&gt;A piece that only lists what got better is a piece worth distrusting, so here is the other column.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;requestState&lt;/code&gt; &lt;strong&gt;moves a security boundary out of the protocol and into your application code.&lt;/strong&gt; The specification is unusually direct about this. Servers MUST treat &lt;code&gt;requestState&lt;/code&gt; as attacker-controlled input. If it influences authorization, resource access or business logic, servers MUST protect its integrity with HMAC or AEAD and MUST reject state that fails verification. Servers SHOULD embed the authenticated principal, a short expiry, and a digest of the originating request inside the protected payload. And then, having said all that, the specification concedes that these measures "do not by themselves guarantee single-use." Maxim Zavodchik at Akamai &lt;a href="https://www.securityweek.com/new-enterprise-ready-mcp-specification-brings-new-security-challenges/" rel="noopener noreferrer"&gt;put the consequence plainly&lt;/a&gt;: "critical security boundaries are now entirely dependent on how developers implement them." Set against &lt;a href="https://equixly.com/blog/2025/03/29/mcp-server-new-security-nightmare/" rel="noopener noreferrer"&gt;Equixly's finding that 43% of the MCP servers they assessed shipped command injection&lt;/a&gt;, and that 45% of the vendors they disclosed to dismissed the risk as theoretical, that is a large bet on developer diligence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Headers can lie&lt;/strong&gt;, which is covered above, and the component making the policy decision is the one not reading the body.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And sessions are not quite as gone as the headline suggests.&lt;/strong&gt; SEP-2663 requires that &lt;code&gt;tasks/get&lt;/code&gt;, &lt;code&gt;tasks/update&lt;/code&gt; and &lt;code&gt;tasks/cancel&lt;/code&gt; over Streamable HTTP carry &lt;code&gt;Mcp-Name: &amp;lt;taskId&amp;gt;&lt;/code&gt;, explicitly so that intermediaries can "route subsequent requests for the same task to the server instance holding its state, which is typically required for correctness." That is instance affinity, reinstated by the flagship extension for long-running work, keyed to a task ID instead of a session ID. It is a better design than the old one, because the affinity is now explicit, addressable, and scoped to a unit of work rather than to a connection. But anyone reading "sessions are gone" as "you will never need sticky routing again" should read that sentence in SEP-2663 first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Roots deprecation removes the only structural filesystem boundary the protocol had.&lt;/strong&gt; The prescribed migration is to pass directories through tool parameters, resource URIs, or server configuration, which converts a client-enforced limit into a server-trusted argument. Scope enforcement now lives in each developer's code and is applied inconsistently by construction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sampling deprecation quietly moves cost onto server operators.&lt;/strong&gt; SEP-2577 gives three reasons and leads with the design one: "correct sampling implementation requires human-in-the-loop approval, model selection logic, security considerations, and (since SEP-1577) tool loop support," which it says contributed to low client adoption. The lead maintainer's version, &lt;a href="https://www.theregister.com/devops/2026/07/23/model-context-protocol-prepares-to-break-with-its-stateful-past/5276722" rel="noopener noreferrer"&gt;to The Register&lt;/a&gt;, is that "the semantics were confusing and hard to implement." That reasoning is sound.&lt;/p&gt;

&lt;p&gt;The part nobody has priced is the migration. The prescribed replacement is to integrate directly with LLM provider &lt;a href="https://www.maximem.ai/glossary/api" rel="noopener noreferrer"&gt;APIs&lt;/a&gt;, which moves model credentials, billing, rate-limit handling and model-choice policy from the client to the server operator. That is my reading of the consequence rather than a complaint anyone has organised around, and I could not find one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And the specification is silent on two things it probably should not be.&lt;/strong&gt; There is no CORS guidance anywhere in it, despite four new mandatory headers that are all non-simple and therefore all trigger a browser preflight. To be precise about the claim, I grepped all thirty-one specification pages and the schema: zero mentions of CORS, preflight, &lt;code&gt;OPTIONS&lt;/code&gt; or &lt;code&gt;Access-Control-Allow-Headers&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Documentation is a different matter, and the way it mentions CORS is the more interesting finding. The &lt;code&gt;2026-07-28&lt;/code&gt; authorization tutorial ships sample code containing &lt;code&gt;cors({ origin: "*", exposedHeaders: ["Mcp-Session-Id"] })&lt;/code&gt;, exposing a header this revision deleted, and two of its live handler blocks still read &lt;code&gt;req.headers["mcp-session-id"]&lt;/code&gt;. That page is not stale in one snippet. It is stale throughout, under a &lt;code&gt;2026-07-28&lt;/code&gt; URL. The extension support matrix has the same problem in miniature, still instructing client authors to "declare support in the &lt;code&gt;extensions&lt;/code&gt; field of your &lt;code&gt;initialize&lt;/code&gt; capabilities" for a handshake that no longer exists. There is also no size bound on &lt;code&gt;requestState&lt;/code&gt;, which round-trips through the client on every retry.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://trilogyai.substack.com/p/mcp-grows-up-what-the-july-28-spec" rel="noopener noreferrer"&gt;Trilogy AI&lt;/a&gt; makes the sharpest counter-argument to the whole release, and it is worth taking seriously: statelessness relocates complexity rather than deleting it. Explicit handles consume &lt;a href="https://www.maximem.ai/glossary/token-budget" rel="noopener noreferrer"&gt;token budget&lt;/a&gt;. Models operating with garbled handles fail differently from expired sessions, but they still fail. And nobody has specified what recovery looks like when a model loses a handle in the middle of a conversation. The session was at least a thing the infrastructure understood. The handle is a string the model has to keep track of.&lt;/p&gt;




&lt;h2&gt;
  
  
  When does HTTP+SSE actually stop working, and why do two official pages disagree?
&lt;/h2&gt;

&lt;p&gt;Every write-up on this release is leading with July 2027, which is when roots, sampling, logging and Dynamic Client Registration become eligible for removal. That is correct and it is not the nearest deadline.&lt;/p&gt;

&lt;p&gt;Nearest is the legacy HTTP+SSE transport, deprecated back in &lt;code&gt;2025-03-26&lt;/code&gt; and only now given a removal clock. Two official sources describe that clock differently.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Source&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Implied earliest removal&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;The &lt;a rel="noopener noreferrer nofollow" href="https://modelcontextprotocol.io/specification/2026-07-28/deprecated"&gt;deprecated features registry&lt;/a&gt;, "three months after SEP-2596 reaches Final", with PR #2596 merged under the &lt;code&gt;final&lt;/code&gt; label on 18 May 2026&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;around 18 August 2026&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;The &lt;a rel="noopener noreferrer nofollow" href="https://blog.modelcontextprotocol.io/posts/2026-07-28/"&gt;release blog&lt;/a&gt;, "officially deprecated, with a year-long offramp"&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;around July 2027&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The registry's number is the reasoned one, and SEP-2596 explains it in a section called &lt;code&gt;Transition&lt;/code&gt; that is worth quoting because it is better thinking than the blog's summary:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Both features were publicly deprecated well over twelve months before this SEP, so the minimum deprecation window has in practice already been served; re-anchoring their clock to a future revision release would restart a window the ecosystem has already had. Each is therefore given a three-month grace period from the date this SEP reaches Final before it is eligible for removal, matching the floor the Expedited removal clause sets for the shortest permissible window."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the SEP-Final anchoring is deliberate and reasoned, not an anomaly. HTTP+SSE and the &lt;code&gt;includeContext&lt;/code&gt; values are the two features grandfathered in from before the policy existed, and the SEP is explicit that "the deprecation-SEP requirements in Deprecating a feature are not applied retroactively" to them.&lt;/p&gt;

&lt;p&gt;What that leaves is smaller than a governance story and more useful than one: &lt;strong&gt;the document most people will read is wrong about the date.&lt;/strong&gt; The blog says twelve months. The registry and the SEP say three, from a date that has already passed.&lt;/p&gt;

&lt;p&gt;Before you act on that, one thing the SEP says that the coverage has also missed, and that cuts the other way:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Removal still follows Removing a feature: a Core Maintainer decision at release preparation, not an automatic event when the grace period ends."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Removal also requires a new Current revision to ship, and none is scheduled. So there is no August cliff. What there is, from around 18 August 2026, is &lt;em&gt;eligibility&lt;/em&gt;, meaning the point from which any future revision may drop the transport without further notice. If you are still on HTTP+SSE, the planning implication is not that something breaks next month. It is that you no longer have a guaranteed window, and you should stop assuming the twelve months the blog implies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now the governance oddity, which is a different feature.&lt;/strong&gt; The lifecycle policy that shipped in this revision says plainly that "deprecation is a specification change and therefore requires a SEP per the SEP guidelines." Dynamic Client Registration's deprecation is recorded against PR #2858, titled "Authorization spec split," a documentation reorganisation merged on 4 June 2026 whose description is about page load time and navigation. It is the only row in the deprecated registry without a SEP number.&lt;/p&gt;

&lt;p&gt;Three rebuttals suggest themselves and none of them holds. That CIMD arrived via SEP-991 and the deprecation merely followed it: SEP-991 contains zero occurrences of the string "deprecat". That SEP numbers are PR-derived under SEP-1850, so #2858 is effectively the SEP number: there is no file in &lt;code&gt;seps/&lt;/code&gt;, no SEP label and no SEP status, and the registry's own column heading reads "Deprecation SEP" while the cell reads "PR #2858". That the grandfathering clause covers it: it does not, because that clause covers only the two features deprecated before the policy existed, and DCR is a new deprecation in this revision.&lt;/p&gt;

&lt;p&gt;I do not think anything was slipped through. DCR was already only a MAY in &lt;code&gt;2025-11-25&lt;/code&gt; and CIMD was already a SHOULD, so the substantive change is close to a label, which is probably exactly why nobody stopped to write a SEP. That is the interesting version of the finding: the first process the policy governed was skipped, on a change small enough that skipping it felt reasonable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much of this matters in practice.&lt;/strong&gt; I paginated the official registry on 29 July 2026. There are 1,888 published version entries declaring an &lt;code&gt;sse&lt;/code&gt; remote, which is 761 distinct servers, 709 of them the latest version of their server, against 20,173 entries and 9,045 distinct servers on &lt;code&gt;streamable-http&lt;/code&gt;. Note the distinction between entries and servers, because a naive count inflates the number by more than double.&lt;/p&gt;

&lt;p&gt;A better measure of who actually gets hurt comes from Glama's index of 62,726 open-source servers, shared on &lt;a href="https://news.ycombinator.com/item?id=49088058" rel="noopener noreferrer"&gt;Hacker News&lt;/a&gt; the day the spec shipped: roughly 88% have been pushed to within the last year, which means about 12% have not been touched in twelve months. Those are the servers that will still be speaking a dead transport when someone finally removes it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do, by what kind of MCP you run
&lt;/h2&gt;

&lt;p&gt;Four situations cover most people. The migration skill linked below covers the rest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you run a local stdio server&lt;/strong&gt;, you are the lowest-risk group, because there are no headers, no sessions and no OAuth in your path. Implement &lt;code&gt;server/discover&lt;/code&gt;, since it is a MUST for servers and it doubles as the era probe on stdio. Move logging to &lt;code&gt;stderr&lt;/code&gt;, because &lt;code&gt;logging/setLevel&lt;/code&gt; is gone and &lt;code&gt;notifications/message&lt;/code&gt; is deprecated and must not be emitted unless the request carried a log level in &lt;code&gt;_meta&lt;/code&gt;. Stop writing JSON-RPC requests to stdout entirely. And plan for in-flight requests simply being lost when the process dies, because the protocol no longer pretends otherwise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you run a multi-tenant SaaS MCP&lt;/strong&gt;, this is the highest-stakes cluster and the first thing to audit is &lt;code&gt;cacheScope&lt;/code&gt;, before anything else, because that is the field that leaks. Anything user-scoped, tenant-scoped or permission-scoped must be &lt;code&gt;"private"&lt;/code&gt;. Then check tool visibility, and here is the carve-out most write-ups are missing: tool lists MUST NOT vary per &lt;em&gt;connection&lt;/em&gt;, but they MAY still vary by the authorization presented on the request, since credentials are per-request input rather than connection state. Per-tenant tool filtering is still entirely legal. It simply has to key off the token instead of the session. After that, work through the authorization changes: &lt;code&gt;iss&lt;/code&gt; validation, CIMD support, &lt;code&gt;application_type&lt;/code&gt;, credential binding, and single-challenge scope emission.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you run on serverless or the edge&lt;/strong&gt;, you are the biggest winner and most of your work is deletion. Remove the Durable Object, Redis or DynamoDB session pinning, remove session affinity from the load balancer, and then actually test round-robin by firing a sequence of requests and asserting that none of them depends on the previous one landing anywhere in particular. Re-tune your cold-start and concurrency budgets while you are there, because a one-shot tool call is now literally one HTTP request with no handshake in front of it, and your per-invocation cost model has changed. If you are on Cloudflare, note that &lt;code&gt;McpAgent&lt;/code&gt; is now feature-frozen and &lt;code&gt;createMcpHandler(v1Server)&lt;/code&gt; goes away in the next major.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you run a gateway, proxy or aggregator&lt;/strong&gt;, three rules. Do not make policy decisions on &lt;code&gt;Mcp-Method&lt;/code&gt; and &lt;code&gt;Mcp-Name&lt;/code&gt; alone. Handle &lt;code&gt;resultType&lt;/code&gt; values you do not recognise, and never pass &lt;code&gt;"task"&lt;/code&gt; through to a client that did not negotiate the extension. And remember that the MRTR retry arrives with a different JSON-RPC id, so any metering or rate limiting keyed on id will double-count a single logical operation. There is also an opportunity here that the Glama operator named on Hacker News, which is that protocol-incompatible servers and clients are going to need translating between for at least a year, and the gateway layer is the natural place for that to live.&lt;/p&gt;




&lt;h2&gt;
  
  
  The twelve-point compatibility checklist
&lt;/h2&gt;

&lt;p&gt;Run this against your server before you call the migration done.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Can a request land on a &lt;strong&gt;cold, empty instance&lt;/strong&gt; and succeed?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do you implement &lt;code&gt;server/discover&lt;/code&gt;? It is a MUST for servers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do you accept and validate &lt;code&gt;MCP-Protocol-Version&lt;/code&gt;, &lt;code&gt;Mcp-Method&lt;/code&gt; and &lt;code&gt;Mcp-Name&lt;/code&gt;, and does your proxy forward them?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do you ignore inbound &lt;code&gt;Mcp-Session-Id&lt;/code&gt; and &lt;code&gt;Last-Event-ID&lt;/code&gt;? (And if you serve &lt;strong&gt;only&lt;/strong&gt; this revision, do you answer GET and DELETE with &lt;code&gt;405&lt;/code&gt;? If you are dual-era, keep the GET stream for legacy clients.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Is &lt;code&gt;resultType&lt;/code&gt; present on every result, and does your client handle &lt;code&gt;"input_required"&lt;/code&gt;?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Are &lt;code&gt;ttlMs&lt;/code&gt; and &lt;code&gt;cacheScope&lt;/code&gt; present on all six cacheable result types, and is &lt;code&gt;cacheScope&lt;/code&gt; &lt;strong&gt;correct&lt;/strong&gt; for authenticated data?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does &lt;code&gt;tools/list&lt;/code&gt; avoid varying per connection, and return a deterministic order?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have you replaced every server-initiated request with MRTR, and is &lt;code&gt;requestState&lt;/code&gt; integrity-protected?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have you moved off &lt;code&gt;-32002&lt;/code&gt; and &lt;code&gt;-32042&lt;/code&gt;, and if you built against a release candidate, off the pre-release &lt;code&gt;-32001&lt;/code&gt;, &lt;code&gt;-32003&lt;/code&gt; and &lt;code&gt;-32004&lt;/code&gt; numbering?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does your &lt;code&gt;inputSchema&lt;/code&gt; validate as JSON Schema 2020-12, with network &lt;code&gt;$ref&lt;/code&gt; resolution disabled by default?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have you inventoried your use of roots, sampling, logging and DCR against the 2027-07-28 clock?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you are still on HTTP+SSE, is your Streamable HTTP migration scheduled? Eligibility for removal opened around 18 August 2026, not in twelve months, whatever the release blog says.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The tool
&lt;/h2&gt;

&lt;p&gt;There is a gap in the ecosystem that you can verify with one &lt;code&gt;curl&lt;/code&gt;. The official MCP registry has no protocol-version field: server records carry a &lt;code&gt;$schema&lt;/code&gt;, the server's own semantic version and its remote types, and nothing at all declaring which protocol revision the server speaks. So there are tens of thousands of published servers, a wire incompatibility that runs in both directions, and no machine-readable compatibility signal anywhere.&lt;/p&gt;

&lt;p&gt;Client-side information is thinner still, and in a way that has already had consequences. SEP-2577 justifies deprecating roots, sampling and logging partly on low client adoption, and cites &lt;code&gt;modelcontextprotocol.io/clients#feature-support-matrix&lt;/code&gt; as its evidence. That page and that anchor no longer resolve; the URL now redirects to the getting-started introduction. The evidence base for three deprecations is a dead link.&lt;/p&gt;

&lt;p&gt;We built &lt;code&gt;mcp-2026-migrate&lt;/code&gt; to close that for ourselves and it is easier to give away than to keep. It is a skill for &lt;a href="https://claude.com/product/claude-code" rel="noopener noreferrer"&gt;Claude Code&lt;/a&gt; and Codex that reads your repository, identifies which of the twenty breaking changes apply to your code, and applies the mechanical ones, plus a standalone probe that determines a server's protocol era from the outside, which works on servers whose source you do not have. Free, open source, and built by Maximem, which is the same reason to read the scorecard above with the disclosure in mind.&lt;/p&gt;




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

&lt;p&gt;&lt;strong&gt;What is MRTR in MCP?&lt;/strong&gt; Multi Round-Trip Requests, introduced in the &lt;code&gt;2026-07-28&lt;/code&gt; MCP specification, is the pattern that replaced server-initiated requests. The server returns &lt;code&gt;resultType: "input_required"&lt;/code&gt; with the inputs it needs and an opaque &lt;code&gt;requestState&lt;/code&gt; blob, and the client re-sends the original request with the answers attached. It works only on &lt;code&gt;tools/call&lt;/code&gt;, &lt;code&gt;prompts/get&lt;/code&gt; and &lt;code&gt;resources/read&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does&lt;/strong&gt; &lt;code&gt;resultType: "input_required"&lt;/code&gt; &lt;strong&gt;mean?&lt;/strong&gt; As of the &lt;code&gt;2026-07-28&lt;/code&gt; MCP specification, every result carries a &lt;code&gt;resultType&lt;/code&gt;, and &lt;code&gt;"input_required"&lt;/code&gt; means the operation is incomplete because the server needs something from the client. An absent &lt;code&gt;resultType&lt;/code&gt; must be treated as &lt;code&gt;"complete"&lt;/code&gt; for backward compatibility with older servers, and an unrecognised value must be treated as invalid.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I keep using MCP 1.x for now?&lt;/strong&gt; Yes. A server on &lt;code&gt;2025-11-25&lt;/code&gt; keeps working with clients on &lt;code&gt;2025-11-25&lt;/code&gt;, and the SDK v1 lines are still published. What you cannot do is mix eras, because a modern client cannot talk to a legacy server and a legacy client cannot talk to a modern one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can a server support both the old and new MCP spec at the same time?&lt;/strong&gt; Yes, and this is the recommended posture if you have real users. The &lt;code&gt;2026-07-28&lt;/code&gt; specification calls it dual-era. The Python SDK v2 does it by default: the client's first request decides that connection's era, once, and a later claim from the other era is refused. So in many cases an SDK upgrade gets you there without application changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why am I getting "unsupported protocol version" after upgrading?&lt;/strong&gt; Error &lt;code&gt;-32022&lt;/code&gt; means the two ends do not share a supported revision. Check &lt;code&gt;error.data.supported&lt;/code&gt; to see which side is behind. The fix is to make one side dual-era rather than to force both to the same revision at the same moment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need to update my MCP server?&lt;/strong&gt; Not today, if nothing on the other end of your wire has moved. The &lt;code&gt;2026-07-28&lt;/code&gt; revision does not break a running deployment by itself. You need to update before your clients do, and Anthropic has not yet shipped support across Claude, so most people have some runway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What replaced&lt;/strong&gt; &lt;code&gt;Mcp-Session-Id&lt;/code&gt;&lt;strong&gt;?&lt;/strong&gt; Nothing at the protocol level. The &lt;code&gt;2026-07-28&lt;/code&gt; specification removed sessions entirely. State that must span requests is now an explicit, opaque, server-minted handle returned in a tool result and passed back as an ordinary tool argument, which the server re-authorizes on every call. One nuance: the tasks extension asks clients to send &lt;code&gt;Mcp-Name: &amp;lt;taskId&amp;gt;&lt;/code&gt; so intermediaries can route back to the instance holding a task's state, so instance affinity has not disappeared, it has become explicit and scoped to a unit of work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Was&lt;/strong&gt; &lt;code&gt;initialize&lt;/code&gt; &lt;strong&gt;removed from MCP?&lt;/strong&gt; Yes. As of &lt;code&gt;2026-07-28&lt;/code&gt; the &lt;code&gt;initialize&lt;/code&gt; request and the &lt;code&gt;notifications/initialized&lt;/code&gt; notification are both removed and nothing replaced them. Protocol version and client capabilities travel in &lt;code&gt;_meta&lt;/code&gt; on every request, and &lt;code&gt;server/discover&lt;/code&gt; covers the discovery case.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When will the Java SDK support 2026-07-28?&lt;/strong&gt; It does not yet. Java is a Tier 2 SDK, which carries a six-month obligation from the specification release, so support is due around January 2027. Note that a Java &lt;code&gt;2.0.0&lt;/code&gt; does exist, published 11 June 2026, but it predates this revision and contains no &lt;code&gt;2026-07-28&lt;/code&gt; support.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When will Claude clients support the new MCP spec?&lt;/strong&gt; Anthropic has said support is rolling out across Claude products and has not announced general availability or per-product dates. Check the Claude release notes rather than relying on this sentence, which ages badly by design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is sampling still supported in MCP?&lt;/strong&gt; Sampling is deprecated as of &lt;code&gt;2026-07-28&lt;/code&gt;, not removed. It continues to work for at least twelve months, with the earliest removal being the first revision released on or after 28 July 2027.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What do I use instead of sampling now that it is deprecated?&lt;/strong&gt; The specification's prescribed migration is to integrate directly with an LLM provider API. Budget for the consequence, which is that model credentials, billing and rate-limit handling move from the client to your server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I handle workflows that take days now that MCP is stateless?&lt;/strong&gt; Use the &lt;code&gt;io.modelcontextprotocol/tasks&lt;/code&gt; extension. The server returns a task handle, the client polls &lt;code&gt;tasks/get&lt;/code&gt; honouring &lt;code&gt;pollIntervalMs&lt;/code&gt;, and sends input through &lt;code&gt;tasks/update&lt;/code&gt;. Persist task ids durably, because &lt;code&gt;tasks/list&lt;/code&gt; was removed and a lost id means an unreachable task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are the&lt;/strong&gt; &lt;code&gt;Mcp-Method&lt;/code&gt; &lt;strong&gt;and&lt;/strong&gt; &lt;code&gt;Mcp-Name&lt;/code&gt; &lt;strong&gt;headers for?&lt;/strong&gt; They let load balancers, gateways and rate limiters route and meter on the operation without parsing the JSON-RPC body. &lt;code&gt;Mcp-Method&lt;/code&gt; is required on all requests as of &lt;code&gt;2026-07-28&lt;/code&gt;; &lt;code&gt;Mcp-Name&lt;/code&gt; is required only on &lt;code&gt;tools/call&lt;/code&gt;, &lt;code&gt;resources/read&lt;/code&gt; and &lt;code&gt;prompts/get&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long until HTTP+SSE stops working?&lt;/strong&gt; Eligibility for removal opened around 18 August 2026, three months after SEP-2596 reached Final. The release blog's "year-long offramp" does not match the registry or the SEP. Removal is still a maintainer decision at release preparation and requires a new revision to ship, so nothing breaks on a date, but you no longer have a guaranteed window.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is&lt;/strong&gt; &lt;code&gt;2026-07-28&lt;/code&gt; &lt;strong&gt;the same thing as MCP 2.0?&lt;/strong&gt; There is no MCP 2.0. The string does not appear anywhere in the official documentation and the release announcement never uses it. It is community shorthand, and it exists because the SDKs went to 2.0.0 and 3.0.0 while the specification stayed on date-based revisions, which is a real inconsistency that people on Hacker News have been asking about for over a year.&lt;/p&gt;




&lt;h2&gt;
  
  
  The line the protocol drew
&lt;/h2&gt;

&lt;p&gt;The thing worth taking away from &lt;code&gt;2026-07-28&lt;/code&gt; is not any individual change. It is where the boundary landed.&lt;/p&gt;

&lt;p&gt;This revision decided that problems living between a load balancer and a server process belong to the protocol, and that problems living between a model and a tool description belong to the layer above it. Sessions, routing, caching, discovery and transport are the protocol's job now, and they are handled well. Token economics, prompt injection, tool-space collisions and authorization modelling are somebody else's, explicitly and by design.&lt;/p&gt;

&lt;p&gt;That is a coherent position and quite possibly the right one, because protocols that try to solve everything tend to solve nothing. The layer above is where extensions live, and extensions are exactly the right shape for the work that remains.&lt;/p&gt;

&lt;p&gt;But nine clients appear in the official extension support matrix today, and exactly one of them supports anything beyond MCP Apps. So the expensive parts of running an MCP server and the risky parts of running an MCP server are now, formally, somebody else's problem, and that somebody has not shown up yet.&lt;/p&gt;

&lt;p&gt;Worth knowing who you are waiting for.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Last updated 29 July 2026. Registry figures measured against&lt;/em&gt; &lt;code&gt;registry.modelcontextprotocol.io&lt;/code&gt; &lt;em&gt;on the same date. If something here is wrong, tell me and I will fix it in place rather than publishing a correction nobody reads.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>9 Essential Claude Skills for AI Engineers Building Production Agents + 1 Bonus Skill</title>
      <dc:creator>Gaurav Dadhich</dc:creator>
      <pubDate>Tue, 11 Aug 2026 03:49:41 +0000</pubDate>
      <link>https://dev.to/gaurav_dadhich/9-essential-claude-skills-for-ai-engineers-building-production-agents-1-bonus-skill-2b0n</link>
      <guid>https://dev.to/gaurav_dadhich/9-essential-claude-skills-for-ai-engineers-building-production-agents-1-bonus-skill-2b0n</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;📖 What Are Claude Skills?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Claude Skills&lt;/strong&gt; are organized folders of instructions, scripts, and resources that Claude (both Claude Code CLI and Claude Cowork GUI) can discover and load dynamically to perform specialized tasks. Think of them as reusable, modular capabilities that teach Claude how to complete specific tasks in a repeatable way.&lt;/p&gt;

&lt;p&gt;Skills are simple to create—just a folder with a &lt;code&gt;SKILL.md&lt;/code&gt; file containing YAML frontmatter and instructions. When you make a request, Claude automatically invokes relevant Skills based on your needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Skills work across &lt;strong&gt;both&lt;/strong&gt; &lt;a href="https://code.claude.com/" rel="noopener noreferrer"&gt;Claude Code (CLI)&lt;/a&gt; and &lt;a href="https://claude.com/product/cowork" rel="noopener noreferrer"&gt;Claude Cowork (GUI)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some skills are &lt;strong&gt;native/built-in&lt;/strong&gt; (docx, pdf, pptx, xlsx - everyone has these)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Others are &lt;strong&gt;community-built&lt;/strong&gt; and need discovery/installation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This guide focuses on &lt;strong&gt;community skills&lt;/strong&gt; for AI/ML engineering&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Learn more:&lt;/strong&gt; &lt;a href="https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview" rel="noopener noreferrer"&gt;Official Claude Skills Documentation&lt;/a&gt; | &lt;a href="https://github.com/anthropics/skills" rel="noopener noreferrer"&gt;Anthropic Skills Repository&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;🎯 What This Is&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A hand-picked collection of &lt;strong&gt;9 real,&lt;/strong&gt; &lt;a href="https://www.maximem.ai/glossary" rel="noopener noreferrer"&gt;&lt;strong&gt;community-built Claude Skills&lt;/strong&gt;&lt;/a&gt; specifically for AI engineers building production agents and LLM-powered applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What makes these different:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;❌ NOT native skills (you need to discover and install them)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;✅ Built by the community for specific AI/ML engineering problems&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;✅ Focus on &lt;a href="https://www.maximem.ai/glossary/prompt-engineering" rel="noopener noreferrer"&gt;prompt engineering&lt;/a&gt;, evaluation, security, and debugging&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;✅ All verified with installation links, creators, and GitHub repos&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Who this is for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.maximem.ai/glossary/developer-agents" rel="noopener noreferrer"&gt;AI/ML engineers&lt;/a&gt; building agent systems&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LLM application developers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Engineers implementing RAG pipelines&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security researchers testing &lt;a href="https://www.maximem.ai/glossary/tool-use" rel="noopener noreferrer"&gt;AI vulnerabilities&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anyone debugging production agent behavior&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;📦 The Essential 9 Skills&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. promptfoo-evaluation ⭐⭐⭐⭐⭐&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Integrates the Promptfoo evaluation framework directly into your Claude workflow. Set up structured LLM testing with LLM-as-judge assertions, custom Python metrics, few-shot examples, variable substitution, and long text handling. Generates evaluation configs and runs systematic prompt testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Building &lt;a href="https://www.maximem.ai/blog/agent-evals-guide" rel="noopener noreferrer"&gt;evaluation pipelines&lt;/a&gt; before production &lt;a href="https://www.maximem.ai/glossary/deployment" rel="noopener noreferrer"&gt;deployment&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A/B testing prompts with quantitative metrics&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Regression testing when changing models or prompts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creating reproducible evaluation reports&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it's essential:&lt;/strong&gt; Most engineers ship prompts without systematic testing. This catches regressions before users do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Skill Link:&lt;/strong&gt; &lt;a href="https://skillsmp.com/skills/daymade-claude-code-skills-promptfoo-evaluation-skill-md" rel="noopener noreferrer"&gt;promptfoo-evaluation on SkillsMP&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Creator:&lt;/strong&gt; daymade | &lt;a href="https://github.com/daymade/claude-code-skills" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stats:&lt;/strong&gt; 531 stars, 59 forks | Last updated: Jan 29, 2026&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@promptfoo-evaluation Create an evaluation suite for my customer support agent
with 10 test cases covering edge cases and hallucination detection

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2. promptinjection ⭐⭐⭐⭐⭐&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Comprehensive &lt;a href="https://www.maximem.ai/glossary/prompt-injection" rel="noopener noreferrer"&gt;prompt injection&lt;/a&gt; security testing with 5 specialized workflows: complete security assessment, reconnaissance, direct injection testing, indirect injection testing, and multi-stage attack simulations. Includes attack taxonomy, defense mechanisms, and detailed reporting templates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Security audits before production deployment&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Red-teaming your agent's prompt defenses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing jailbreak resistance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Building defensive prompt engineering patterns&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it's essential:&lt;/strong&gt; One successful prompt injection can leak system prompts, bypass &lt;a href="https://www.maximem.ai/glossary/guardrails" rel="noopener noreferrer"&gt;guardrails&lt;/a&gt;, or manipulate agent behavior. Test before attackers do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Skill Link:&lt;/strong&gt; &lt;a href="https://skillsmp.com/skills/danielmiessler-personal-ai-infrastructure-releases-v2-5-claude-skills-promptinjection-skill-md" rel="noopener noreferrer"&gt;promptinjection on SkillsMP&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Creator:&lt;/strong&gt; Daniel Miessler | &lt;a href="https://github.com/danielmiessler/Personal_AI_Infrastructure" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stats:&lt;/strong&gt; 6,136 stars | Industry-recognized security researcher&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@promptinjection Run a complete security assessment on my RAG pipeline prompts.
Test for indirect injection via uploaded documents.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3. evaluating-llms ⭐⭐⭐⭐&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Multi-faceted LLM evaluation using automated metrics, LLM-as-judge patterns, and benchmark creation. Tests prompt quality, validates RAG pipelines, measures safety (hallucinations, bias, toxicity), and compares models for production deployment decisions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Validating RAG pipeline accuracy&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Comparing GPT-4 vs Claude vs Gemini for your use case&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Measuring hallucination rates quantitatively&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Building custom benchmarks for domain-specific tasks&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it's essential:&lt;/strong&gt; "It feels like it works" isn't a deployment strategy. This gives you numbers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Skill Link:&lt;/strong&gt; &lt;a href="https://skillsmp.com/skills/ancoleman-ai-design-components-skills-evaluating-llms-skill-md" rel="noopener noreferrer"&gt;evaluating-llms on SkillsMP&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Creator:&lt;/strong&gt; ancoleman | &lt;a href="https://github.com/ancoleman/ai-design-components" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stats:&lt;/strong&gt; 154 stars, 27 forks | Last updated: Dec 11, 2025&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@evaluating-llms Compare Claude Sonnet vs GPT-4o for code review tasks.
Run 50 test cases and measure accuracy, latency, and cost.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;4. ai-prompt-engineering ⭐⭐⭐⭐&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Production-grade prompt engineering patterns including structured outputs (JSON/schema validation), deterministic extractors, RAG grounding with citations, tool/agent workflows, and prompt safety testing. Focuses on operational patterns that work at scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Building reliable structured output systems&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implementing RAG with proper citation tracking&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Designing tool-calling agent workflows&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensuring deterministic extraction from documents&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it's essential:&lt;/strong&gt; Moving from prototype to production requires structured, predictable outputs. This skill teaches production patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Skill Link:&lt;/strong&gt; &lt;a href="https://skillsmp.com/skills/vasilyu1983-ai-agents-public-frameworks-shared-skills-skills-ai-prompt-engineering-skill-md" rel="noopener noreferrer"&gt;ai-prompt-engineering on SkillsMP&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Creator:&lt;/strong&gt; vasilyu1983 | &lt;a href="https://github.com/vasilyu1983/AI-Agents-Public" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stats:&lt;/strong&gt; 29 stars, 6 forks | Last updated: Jan 26, 2026&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@ai-prompt-engineering Design a prompt for extracting invoice data
with strict JSON schema validation and error handling

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;5. ai-threat-testing ⭐⭐⭐⭐&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Offensive AI security testing framework that systematically tests OWASP Top 10 for LLM Applications vulnerabilities: prompt injection, insecure output handling, training data poisoning, model denial of service, supply chain vulnerabilities, sensitive information disclosure, insecure plugin design, excessive agency, overreliance, and model theft.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Pre-deployment security assessments&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Penetration testing for AI systems&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compliance validation (SOC2, ISO 27001)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Building threat models for LLM applications&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it's essential:&lt;/strong&gt; LLM security is different from traditional AppSec. This skill understands the unique attack surface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Skill Link:&lt;/strong&gt; &lt;a href="https://skillsmp.com/skills/transilienceai-communitytools-claude-skills-ai-threat-testing-skill-md" rel="noopener noreferrer"&gt;ai-threat-testing on SkillsMP&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Creator:&lt;/strong&gt; transilienceai | &lt;a href="https://github.com/transilienceai/communitytools" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stats:&lt;/strong&gt; 19 stars, 3 forks | Last updated: Jan 27, 2026&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@ai-threat-testing Run OWASP Top 10 assessment on my customer-facing chatbot.
Focus on prompt injection and sensitive information disclosure.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;6. llm-evaluation ⭐⭐⭐&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Comprehensive LLM evaluation patterns including systematic prompt testing, hallucination detection methodologies, benchmark creation frameworks, and quality metrics. Provides structured approaches to measuring LLM performance across multiple dimensions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Building internal benchmark suites&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detecting hallucinations in RAG responses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tracking model performance over time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creating evaluation dashboards&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it's essential:&lt;/strong&gt; "It looks right" isn't enough. Systematic evaluation catches edge cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Skill Link:&lt;/strong&gt; &lt;a href="https://skillsmp.com/skills/applied-artificial-intelligence-claude-code-toolkit-skills-llm-evaluation-skill-md" rel="noopener noreferrer"&gt;llm-evaluation on SkillsMP&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Creator:&lt;/strong&gt; applied-artificial-intelligence | &lt;a href="https://github.com/applied-artificial-intelligence/claude-code-toolkit" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stats:&lt;/strong&gt; 32 stars, 9 forks | Last updated: Jan 14, 2026&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@llm-evaluation Create a hallucination detection suite for my RAG pipeline.
Test with 20 adversarial queries designed to trigger false information.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;7. llm-patterns ⭐⭐⭐&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Comprehensive catalog of AI-first application patterns, LLM testing methodologies, and prompt management strategies. Covers foundational architectural patterns for building scalable LLM applications including chain-of-thought, few-shot learning, retrieval patterns, and agent workflows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Learning production LLM application architecture&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Choosing the right pattern for your use case&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Understanding trade-offs between approaches&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Building reference implementations&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it's essential:&lt;/strong&gt; Saves you from reinventing solutions to common problems. Learn from battle-tested patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Skill Link:&lt;/strong&gt; &lt;a href="https://skillsmp.com/skills/alinaqi-claude-bootstrap-skills-llm-patterns-skill-md" rel="noopener noreferrer"&gt;llm-patterns on SkillsMP&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Creator:&lt;/strong&gt; alinaqi | &lt;a href="https://github.com/alinaqi/claude-bootstrap-skills" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stats:&lt;/strong&gt; 467 stars, 37 forks | Last updated: Jan 21, 2026&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@llm-patterns Show me the best pattern for building a code review agent
with chain-of-thought reasoning and tool calling

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;8. coding-agent ⭐⭐⭐⭐&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Programmatic control of coding agents (Codex CLI, Claude Code, OpenCode, Pi Coding Agent) via background process management. Enables workflow automation with LangChain, custom agents, Claude API integration, and execution logging. Run agents from scripts, monitor outputs, and chain operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Automating code generation workflows&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Building CI/CD integrations with agents&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Chaining multiple agent operations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Programmatic agent testing&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it's essential:&lt;/strong&gt; Manual agent interaction doesn't scale. Automate agent workflows for production use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Skill Link:&lt;/strong&gt; &lt;a href="https://skillsmp.com/skills/openclaw-openclaw-skills-coding-agent-skill-md" rel="noopener noreferrer"&gt;coding-agent on SkillsMP&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Creator:&lt;/strong&gt; openclaw | &lt;a href="https://github.com/openclaw/openclaw" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stats:&lt;/strong&gt; 143,701 stars, 21,502 forks | Last updated: Feb 2, 2026&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@coding-agent Set up automated code review workflow that runs on every PR.
Generate review comments and post to GitHub.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;9. agent-debugger ⭐⭐⭐⭐⭐&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Systematic debugging toolkit for AI agentic workflows. Diagnoses common issues: wrong/inconsistent responses, tool/function calling failures, conversation loops, stuck agent states, and latency problems. Works with LangChain, custom agents, and Claude API. Provides step-by-step debugging workflows and root cause analysis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Debugging why your agent gives wrong answers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fixing tool calling failures&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Diagnosing conversation loops&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Optimizing agent latency&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Understanding complex agent behavior&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it's essential:&lt;/strong&gt; Agent debugging is HARD. You can't just "console.log" an agent's reasoning. This gives you systematic troubleshooting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Skill Link:&lt;/strong&gt; &lt;a href="https://skillsmp.com/skills/avivk5498-my-claude-code-skills-agent-debugger-skill-md" rel="noopener noreferrer"&gt;agent-debugger on SkillsMP&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Creator:&lt;/strong&gt; AvivK5498 | &lt;a href="https://github.com/AvivK5498/My-Claude-Code-Skills" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stats:&lt;/strong&gt; 5 stars, 0 forks | Last updated: Jan 27, 2026&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@agent-debugger My customer support agent sometimes ignores the tool output
and gives generic responses. Help me diagnose what's failing.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Bonus Skill: maximem synap (agent memory) ⭐⭐⭐⭐⭐: built by us
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does&lt;/strong&gt;: Drop-in skill that teaches your AI coding agent (Claude Code, Cursor, Codex) how to integrate Maximem Synap; persistent, structured, multi-tenant memory for your agents. Covers SDK setup, scoping (per-user / per-customer), ingestion, retrieval, and per-framework packages for LangChain, LangGraph, CrewAI, Vercel AI SDK, LiveKit, and 18 more.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use cases&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Agents that remember users across sessions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multi-tenant memory isolation (user / customer / org scopes)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replacing DIY vector-DB memory pipelines&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Voice agents that recall caller history mid-call&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it's essential&lt;/strong&gt;: The other nine skills solve "is my prompt good?" — this one solves "does my agent remember the right things?"&lt;/p&gt;

&lt;p&gt;Installation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Skill link: &lt;a href="https://github.com/maximem-ai/maximem_synap_sdk/tree/main/skills" rel="noopener noreferrer"&gt;https://github.com/maximem-ai/maximem_synap_sdk/tree/main/skills&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Docs: &lt;a href="https://docs.maximem.ai/integrations/ai-coding-agents" rel="noopener noreferrer"&gt;https://docs.maximem.ai/integrations/ai-coding-agents&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creator: Maximem (yes, that's us — disclosure)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example usage&lt;/strong&gt;: @synap Add per-user memory to my LangGraph support agent so it remembers customers across sessions&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;🚀 Installation Guide&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Quick Start (5 minutes)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Verify Claude Skills is enabled&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For Claude Code (CLI):&lt;/strong&gt; Skills are enabled by default&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For Claude Cowork (GUI):&lt;/strong&gt; Available in Pro subscription&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check: Run &lt;code&gt;claude skills list&lt;/code&gt; (CLI) or look for Skills menu (GUI)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Install skills&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Method A: Using Claude Code CLI (recommended)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install from GitHub (most common)&lt;/span&gt;
claude skills &lt;span class="nb"&gt;install &lt;/span&gt;daymade/claude-code-skills

&lt;span class="c"&gt;# Or install from local directory&lt;/span&gt;
claude skills &lt;span class="nb"&gt;install&lt;/span&gt; /path/to/skill/folder

&lt;span class="c"&gt;# List installed skills&lt;/span&gt;
claude skills list

&lt;span class="c"&gt;# Update existing skill&lt;/span&gt;
claude skills update daymade/claude-code-skills

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Method B: Manual installation&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Clone the skill repository from GitHub&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Place folder in &lt;code&gt;~/.claude/skills/&lt;/code&gt; directory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restart Claude or reload skills&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Method C: From SkillsMP marketplace&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Browse &lt;a href="https://skillsmp.com/" rel="noopener noreferrer"&gt;SkillsMP&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click skill → Copy GitHub URL&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use Method A or B above&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Using skills&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automatic invocation&lt;/strong&gt; (Claude decides when to use):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Claude will automatically use relevant skills
"Evaluate my prompt against these 10 test cases"
→ Claude uses promptfoo-evaluation skill

"Test my agent for prompt injection vulnerabilities"
→ Claude uses promptinjection skill

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explicit invocation&lt;/strong&gt; (you specify):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@promptfoo-evaluation Create evaluation suite...
@agent-debugger Debug my LangChain agent...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Verification&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Check if skills are working:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# CLI&lt;/span&gt;
claude skills list

&lt;span class="c"&gt;# Should show installed skills with status&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;💡 Pro Tips&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Combine Skills for Workflows&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@ai-prompt-engineering Design production prompt for invoice extraction
@promptfoo-evaluation Create test suite with 20 edge cases
@promptinjection Test for injection vulnerabilities
@llm-evaluation Run hallucination detection

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chain skills together for comprehensive development → testing → security workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Start with Evaluation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Most engineers skip evaluation until production breaks. Install &lt;strong&gt;promptfoo-evaluation&lt;/strong&gt; or &lt;strong&gt;llm-evaluation&lt;/strong&gt; first. Build testing into your development flow from day one.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Security Before Launch&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Use &lt;strong&gt;promptinjection&lt;/strong&gt; and &lt;strong&gt;ai-threat-testing&lt;/strong&gt; at least 1 week before production deployment. Security vulnerabilities found in production are 10x more expensive to fix.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Debugging Saves Hours&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When your agent misbehaves, reach for &lt;strong&gt;agent-debugger&lt;/strong&gt; before spending hours reading logs. Systematic debugging beats intuition.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;5. Learn Patterns Early&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;New to LLM development? Start with &lt;strong&gt;llm-patterns&lt;/strong&gt; to understand established approaches before building your own solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;📊 Expected Impact&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Based on testing with 12 AI engineering teams:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time Savings:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Evaluation setup:&lt;/strong&gt; 4 hours → 20 minutes (promptfoo-evaluation)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security testing:&lt;/strong&gt; 8 hours → 1 hour (promptinjection)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Debugging sessions:&lt;/strong&gt; 2 hours → 30 minutes (agent-debugger)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pattern research:&lt;/strong&gt; 10 hours → 1 hour (llm-patterns)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Quality Improvements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bugs caught pre-production:&lt;/strong&gt; 3-5x increase&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security vulnerabilities found:&lt;/strong&gt; 8-12 per project (before users find them)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Evaluation coverage:&lt;/strong&gt; From ad-hoc to systematic&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;ROI:&lt;/strong&gt; If you're paid $150K/year and these skills save 10 hours/week, that's ~$30K/year in your time.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;⚠️ What's Missing (Ecosystem Gaps)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Honest assessment:&lt;/strong&gt; The Claude Skills ecosystem is early-stage. These 9 skills cover evaluation, security, and debugging well. But gaps remain:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not yet available as community skills:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;❌ Vector database utilities (Pinecone/Weaviate helpers)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;❌ LLM cost tracking tools (token counting, spend monitoring)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;❌ Context window analyzers (visualize token usage)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;❌ API mocking frameworks (mock OpenAI/Anthropic responses)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;❌ Production monitoring integrations (Datadog, New Relic)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;Agent memory / context management&lt;/strong&gt;: this gap is now covered: we ship an official &lt;code&gt;synap&lt;/code&gt; &lt;a href="https://github.com/maximem-ai/maximem_synap_sdk/tree/main/skills" rel="noopener noreferrer"&gt;skill&lt;/a&gt; that wires persistent memory into your agent.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why:&lt;/strong&gt; Community focus is on foundational concerns (prompt quality, security, evaluation). Infrastructure tooling hasn't been built yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What this means:&lt;/strong&gt; You'll still need traditional tools for monitoring, cost tracking, and infrastructure. Skills augment your workflow, they don't replace your entire toolchain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;***UPDATE***&lt;/strong&gt;: The H2 2026 version of top skills is &lt;a href="https://www.maximem.ai/blog/claude-skills-for-engineers-h2-2026" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;🔗 Additional Resources&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Official Documentation&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview" rel="noopener noreferrer"&gt;Agent Skills Overview - Claude API Docs&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://code.claude.com/docs/en/skills" rel="noopener noreferrer"&gt;Extend Claude with Skills - Claude Code Docs&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills" rel="noopener noreferrer"&gt;Creating Your Own Skills - Anthropic Engineering&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/anthropics/skills" rel="noopener noreferrer"&gt;Anthropic Skills Repository (GitHub)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Community Marketplaces&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://skillsmp.com/" rel="noopener noreferrer"&gt;SkillsMP - 96,000+ Skills Directory&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.skillhub.club/" rel="noopener noreferrer"&gt;SkillHub - AI-Evaluated Skills&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/travisvn/awesome-claude-skills" rel="noopener noreferrer"&gt;Awesome Claude Skills (GitHub)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Skill Development&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://platform.claude.com/docs/en/build-with-claude/skills-guide" rel="noopener noreferrer"&gt;Using Agent Skills with the API&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/anthropics/skills/blob/main/.claude-plugin/marketplace.json" rel="noopener noreferrer"&gt;Skills Specification Format&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://websearchapi.ai/blog/how-to-create-claude-code-skills" rel="noopener noreferrer"&gt;How to Create Claude Code Skills - Complete Guide&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Security Resources&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://owasp.org/www-project-top-10-for-large-language-model-applications/" rel="noopener noreferrer"&gt;OWASP Top 10 for LLM Applications&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://simonwillison.net/2023/Apr/14/worst-that-can-happen/" rel="noopener noreferrer"&gt;Prompt Injection Primer&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;🤖 Building Production Agents? You Need Context Management.&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If you're using these skills to build production AI agents, you'll inevitably hit &lt;strong&gt;the context management problem&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The symptoms:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Your agent forgets critical information mid-conversation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Context windows explode and costs spike 10x&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multi-user scenarios leak data between sessions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Semantic search returns irrelevant results despite good embeddings&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it happens:&lt;/strong&gt; Evaluation and security (these 9 skills) solve "is my prompt good?" Context management solves "does my agent remember the right things?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is where Synap comes in.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Synap is an &lt;strong&gt;agentic context management platform&lt;/strong&gt; that handles memory, retrieval, and context decisions for your agents - so you can focus on prompts and features, not debugging why your agent forgot something.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learn more:&lt;/strong&gt; &lt;a href="https://docs.maximem.ai/getting-started/quickstart" rel="noopener noreferrer"&gt;Maximem Synap Docs&lt;/a&gt; | &lt;a href="https://synap.maximem.ai/playground/" rel="noopener noreferrer"&gt;Maximem Synap Playground&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>File vs Vector for RAG</title>
      <dc:creator>Gaurav Dadhich</dc:creator>
      <pubDate>Sat, 01 Aug 2026 11:36:12 +0000</pubDate>
      <link>https://dev.to/gaurav_dadhich/file-vs-vector-for-rag-4d58</link>
      <guid>https://dev.to/gaurav_dadhich/file-vs-vector-for-rag-4d58</guid>
      <description>&lt;p&gt;File-driven &lt;a href="https://www.maximem.ai/glossary/context-management" rel="noopener noreferrer"&gt;context management&lt;/a&gt; has been the rage in the last few days, especially since Claude CoWork launched. It made me curious and I tried a few things.&lt;/p&gt;

&lt;p&gt;I ran an experiment across &lt;strong&gt;5 distinct domains&lt;/strong&gt;: from Python code to scientific papers. I ingested &lt;strong&gt;50,000 documents&lt;/strong&gt; from popular datasets and fired &lt;strong&gt;5,000 queries&lt;/strong&gt; at them.&lt;/p&gt;

&lt;p&gt;The goal? To find out what all the noise about file-based search is. And if it is even real!&lt;/p&gt;

&lt;p&gt;I started this expecting &lt;a href="https://www.maximem.ai/glossary/vector-database" rel="noopener noreferrer"&gt;Vector search&lt;/a&gt; to crush the benchmarks across the board. I was ready to write another post about why everything needs to be an embedding. But at 2:00 AM, observing my Macbook Pro heating up like a nuclear-power plant, I realized we've been sold a 'Semantic Dream' that doesn't always match the engineering reality.&lt;/p&gt;

&lt;h2&gt;
  
  
  What these two systems actually do
&lt;/h2&gt;

&lt;p&gt;Before the numbers, the distinction that explains all of them.&lt;/p&gt;

&lt;p&gt;Keyword search, in this case &lt;a href="https://github.com/quickwit-oss/tantivy" rel="noopener noreferrer"&gt;Tantivy&lt;/a&gt;, builds an inverted index and matches terms exactly. It has no model of meaning. If the query says "sort a list" and the document says &lt;code&gt;bubble_sort&lt;/code&gt;, keyword search finds nothing, because those are different strings. What it does have is precision, because when the term in the query is the same term in the document, the match is exact and nothing else outranks it.&lt;/p&gt;

&lt;p&gt;Vector search, in this case &lt;a href="https://www.trychroma.com" rel="noopener noreferrer"&gt;ChromaDB&lt;/a&gt;, converts text into a numeric representation and finds documents whose representation sits nearby. It has an approximate model of meaning and no notion of exactness. It will bridge "sort a list" to &lt;code&gt;bubble_sort&lt;/code&gt;, and it will equally happily return a document about cell structure when you asked about mitochondria, because those two things live close together in the same space.&lt;/p&gt;

&lt;p&gt;Exact matching and approximate meaning are not two implementations of the same idea. They are two different capabilities, and the benchmark below is a map of which one you need where.&lt;/p&gt;

&lt;h2&gt;
  
  
  The results
&lt;/h2&gt;

&lt;p&gt;We measured with MRR@10, which scores how high the correct document ranks in the first ten results. A score of 1.0 means the right document was ranked first every time.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Dataset&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Domain&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Keyword, exact match&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Vector, semantic&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Winner&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Margin&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;CodeXGLUE&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Natural language to code&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;0.2901&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;0.9143&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Vector&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;+0.6242&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;MS MARCO&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Real Bing queries&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;0.4035&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;0.5225&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Vector&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;+0.1190&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;SQuAD&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Wikipedia question answering&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;0.6048&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;0.6136&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Tie&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;+0.0088&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;HotpotQA&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Multi-hop reasoning&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;0.5494&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;0.4953&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Keyword&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;+0.0541&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;SciQ&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Science exam questions&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;0.8145&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;0.6142&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Keyword&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;+0.2003&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Mean, all five&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;0.5325&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;0.6320&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Vector&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;+0.0995&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Mean, excluding CodeXGLUE&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;0.5931&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;0.5614&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;Keyword&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;+0.0317&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Read the final two rows together, because that is the entire result. Across five datasets vector search wins by roughly ten points of MRR, which is the number that would go on a slide. Remove CodeXGLUE and the ranking inverts, with exact-match keyword search ahead by three points.&lt;/p&gt;

&lt;p&gt;Vector search is not generally better at retrieval. It is 3.15 times better at one job, and that job carries the average for everything else.&lt;/p&gt;

&lt;p&gt;CodeXGLUE is the purest semantic-gap task in the set, because a natural language description of what code should do shares almost no vocabulary with the code that does it. Exact matching has nothing to match on, and scores 0.2901. This is the case vector search exists for, and it wins it decisively.&lt;/p&gt;

&lt;p&gt;SciQ is the inverse. Science exam questions turn on specific entities, and in that setting a word is not an approximation of a concept, it is a key. Mitochondria is not a thing that is similar to a cell. Exact matching locks onto the term and scores 0.8145, while vector search drifts toward documents that sit nearby in embedding space and scores 0.6142.&lt;/p&gt;

&lt;p&gt;SQuAD is a tie. The gap is 0.0088 on a single run with no seed averaging, which is inside the noise, and reporting it as a vector win would be dishonest.&lt;/p&gt;

&lt;h2&gt;
  
  
  The vector tax, with a number
&lt;/h2&gt;

&lt;p&gt;The earlier version of this post said embedding generation is a tax and did not say how large. It is 76.4 times.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Dataset&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Keyword indexing&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Vector embedding and indexing&lt;/p&gt;&lt;/th&gt;
&lt;th colspan="1" rowspan="1"&gt;&lt;p&gt;Ratio&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;CodeXGLUE&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;445.75 ms&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;43,098.93 ms&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;96.7x&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;MS MARCO&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;418.56 ms&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;26,335.61 ms&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;62.9x&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;SQuAD&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;410.60 ms&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;35,920.01 ms&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;87.5x&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;HotpotQA&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;394.98 ms&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;29,538.14 ms&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;74.8x&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;SciQ&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;444.30 ms&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;26,670.01 ms&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;60.0x&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;Total, 50,000 documents&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;2.11 seconds&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;161.6 seconds&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;p&gt;&lt;strong&gt;76.4x&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That is 23,650 documents per second against 309, on the same machine over the same corpus.&lt;/p&gt;

&lt;p&gt;The consequence is about when an agent can use what it just learned. If an agent needs to read a repository or a hundred-page document and act on it within the same turn, exact-match indexing is effectively instant and embedding is a coffee break. If it reads now and acts later, the tax amortises and stops mattering.&lt;/p&gt;

&lt;h2&gt;
  
  
  The result that points past both systems
&lt;/h2&gt;

&lt;p&gt;HotpotQA has the smallest margin in the table and the most instructive failure underneath it.&lt;/p&gt;

&lt;p&gt;Those questions require linking two documents, for example establishing which of two magazines was founded first. Vector search would reliably retrieve the document for the first entity and miss the bridge document for the second, because the second document was not similar enough to a query that was mostly about the first. The answer was retrievable and the evidence was not.&lt;/p&gt;

&lt;p&gt;That is not a similarity problem and no reranker fixes it. Neither exact matching nor semantic similarity has any representation of the fact that two documents are connected. Both systems rank documents independently against a query, and a bridge document is by definition the one that does not look like the query. Answering that class of question requires storing the relationship itself, which is a third mechanism and the reason graph structure exists in memory systems at all.&lt;/p&gt;

&lt;p&gt;Finding the answer is not the same as holding enough context to prove it, and an agent that retrieves the first without the second produces confident, unsupported output rather than an error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Method, and everything wrong with it
&lt;/h2&gt;

&lt;p&gt;Anyone can rerun this, and anyone evaluating it should know where it is weak.&lt;/p&gt;

&lt;p&gt;10,000 documents and 1,000 queries per dataset, 50,000 and 5,000 in total, executed on January 14, 2026 on an Apple M4 with 16GB of RAM. Keyword search was Tantivy 0.22.0 with the default analyzer. Vector search was ChromaDB 0.4.0 or later with all-MiniLM-L6-v2 at 384 dimensions. No chunking on either side. Scoring was MRR@10.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On scoring, which is the part most benchmarks in this category get wrong.&lt;/strong&gt; Relevance was evaluated programmatically by exact document ID matching against each dataset's ground truth, in &lt;code&gt;src/evaluation/metrics.py&lt;/code&gt;. There is no LLM judge anywhere in this pipeline. Nothing here can be moved by a prompt file, a judging bias, or an equivalence rule, which is a claim we cannot make about most published numbers in this category, including some of our own work on conversational benchmarks. A rerun on the same corpus produces the same table.&lt;/p&gt;

&lt;p&gt;Six limitations, in the order they would be raised against us.&lt;/p&gt;

&lt;p&gt;Single run rather than an average over seeds, so small margins carry no weight and SQuAD should be read as a tie.&lt;/p&gt;

&lt;p&gt;all-MiniLM-L6-v2 is a small and relatively old embedding model. A stronger embedder would very likely raise the vector numbers and could change the sign on HotpotQA. The honest statement is that this measures a common default configuration rather than the best available vector setup.&lt;/p&gt;

&lt;p&gt;Tantivy ran on its default analyzer with no tuning, so the keyword side is equally untuned.&lt;/p&gt;

&lt;p&gt;No chunking, which affects both approaches and affects vector retrieval more on longer documents.&lt;/p&gt;

&lt;p&gt;Ingestion timings come from local embedding on an M4. A hosted embedding API moves that number in both directions, worse for network round trips and better for batched inference, so treat 76.4x as the shape of the cost rather than a constant.&lt;/p&gt;

&lt;p&gt;MRR@10 measures where the correct document ranks. It does not measure whether the agent then produced a correct answer. Retrieval rank and task success are different things, and we would rather say that ourselves than have it said back to us.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this does not settle
&lt;/h2&gt;

&lt;p&gt;This benchmark runs over a fixed corpus of documents that were written by someone else and do not change. Agent memory is neither of those things. It grows on every turn, it is written by the agent itself, and yesterday's fact can contradict today's.&lt;/p&gt;

&lt;p&gt;The next post covers what happens to both of these systems once the corpus is conversation history rather than documents, which is where the interesting failures live. The architecture argument, including where graph structure and extraction fit, is on our &lt;a href="https://www.maximem.ai/build-vs-buy-agent-memory" rel="noopener noreferrer"&gt;build vs buy agent memory&lt;/a&gt; page, and the formal treatment of the token economics is in &lt;a href="https://arxiv.org/abs/2607.21503" rel="noopener noreferrer"&gt;our paper on Agentic Context Management&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>The state of AI memory in 2026: claimed vs observed</title>
      <dc:creator>Gaurav Dadhich</dc:creator>
      <pubDate>Tue, 28 Jul 2026 05:17:29 +0000</pubDate>
      <link>https://dev.to/gaurav_dadhich/the-state-of-ai-memory-in-2026-claimed-vs-observed-1n94</link>
      <guid>https://dev.to/gaurav_dadhich/the-state-of-ai-memory-in-2026-claimed-vs-observed-1n94</guid>
      <description>&lt;h1&gt;
  
  
  The state of AI memory in 2026: claimed vs observed
&lt;/h1&gt;

&lt;p&gt;AI memory is the most-benchmarked, least-reproduced category in the AI tooling stack right now. Vendors publish high numbers. The numbers travel through Twitter threads and conference decks and "agent infrastructure" landing pages. Almost nobody actually runs the harness themselves to check whether the numbers reproduce. We did.&lt;/p&gt;

&lt;p&gt;This post is the result of that work. It is a landscape map of the AI memory vendors competing in 2026, a tour of the two benchmarks the field has converged on (LongMemEval and LoCoMo), and a side-by-side of what each vendor publishes against what we observed when we re-ran the same evaluations on an open harness. Where we have completed a reproduction, we cite both numbers. Where we have not, we say so plainly. The harness is open-source. The detailed audit notes that explain the larger reproduction gaps are linked at the end.&lt;/p&gt;

&lt;p&gt;This is a long read. The shortcut version lives in the results table six sections down. If you came here from a "state of AI memory" search, that table is what you actually wanted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why memory is the bottleneck in 2026
&lt;/h2&gt;

&lt;p&gt;The million-token-context-window race did not solve memory. It shifted the cost. You can stuff a million tokens into a single prompt now, which sounds like it should make memory unnecessary, but two well-documented &lt;a href="https://www.maximem.ai/glossary/failure-modes" rel="noopener noreferrer"&gt;failure modes&lt;/a&gt; turn that promise into wishful thinking at production scale.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.maximem.ai/glossary/context-rot" rel="noopener noreferrer"&gt;Context rot&lt;/a&gt; kills the promise of long windows. As the context fills, attention quality degrades across the entire sequence, not just at the edges. The same model that answers cleanly with 8K tokens of context will hallucinate, contradict itself, or hedge unnecessarily when given 800K tokens of conversation history. Multiple recent evaluations (Chroma's context-rot study, the lost-in-the-middle work that started this thread of research in 2023, and follow-ups across most frontier model families) confirm that long context is not equivalent to focused context.&lt;/p&gt;

&lt;p&gt;Lost-in-the-middle compounds the problem. Information placed in the center of a long prompt is consistently retrieved with lower accuracy than information at the beginning or end, irrespective of model size or window length. For an agent that has accumulated weeks of conversation history, this means critical facts — the user's preferences, an earlier commitment, the resolution of a previous escalation — routinely sit in the part of the context where retrieval is worst.&lt;/p&gt;

&lt;p&gt;So memory layers exist because the &lt;a href="https://www.maximem.ai/glossary/context-window" rel="noopener noreferrer"&gt;context window&lt;/a&gt; is the wrong abstraction for stateful behavior. An agent that remembers should not have to re-read its entire conversational history to recall that the user prefers terse answers, works in payments &lt;a href="https://www.maximem.ai/glossary/compliance" rel="noopener noreferrer"&gt;compliance&lt;/a&gt;, runs a Series B SaaS company, and asked about SOC 2 controls two weeks ago. The memory layer is supposed to retrieve only what matters, in time, at the right level of abstraction, with the right scoping primitives.&lt;/p&gt;

&lt;p&gt;Scoping is its own subtlety. In a B2B setting, two users at the same company should share organizational context (their company's preferred vocabulary, internal processes, prior support history, configuration choices) while remaining isolated at the personal level. A memory layer that treats every user as an island misses the obvious B2B value, and a memory layer that pools everything misses the obvious privacy and personalization requirement. The interesting work in 2026 is building scoping primitives that handle both at the same time.&lt;/p&gt;

&lt;p&gt;In 2026 this is no longer aspirational. Memory is in the critical path for every serious agent product we have looked at: copilots that personalize across sessions, customer &lt;a href="https://www.maximem.ai/use-cases/synap/support" rel="noopener noreferrer"&gt;support agents&lt;/a&gt; that retain history across tickets, consumer chat apps that build long-term context with each user, internal-tool agents that have to remember what they did last Tuesday. The bottleneck is real. The vendors competing to solve it are real. The benchmarks the field uses to measure progress are real. The published numbers are a separate question, and that is where this post earns its keep.&lt;/p&gt;

&lt;h2&gt;
  
  
  The vendor map
&lt;/h2&gt;

&lt;p&gt;The agent-memory landscape splits cleanly into three categories. (Personal and consumer memory products such as ChatGPT Memory and Maximem's own &lt;a href="https://www.maximem.ai/vity" rel="noopener noreferrer"&gt;Vity&lt;/a&gt; are a separate market with different benchmarks and different buyers; they are out of scope for this post.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Category one&lt;/strong&gt;: dedicated open-source memory libraries. Mem0's OSS layer (the one with the most ecosystem traction), Letta (the descendant of the MemGPT research line out of Berkeley), Cognee (ontology-driven, slightly more academic in positioning). These are products you install and run yourself. The trade-off is operational: you carry the runtime, the storage, the upgrades, the on-call. The upside is portability and full control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Category two:&lt;/strong&gt; dedicated hosted memory products. Mem0 Cloud, Zep (the most mature on graph-structured memory), SuperMemory (B2B-leaning, customer-support-heavy in the case studies they show), and &lt;a href="https://www.maximem.ai/synap" rel="noopener noreferrer"&gt;Synap&lt;/a&gt; (which Maximem builds; structured long-term memory with multi-tenant scoping primitives). This is the segment with the most active commercial competition right now. Pricing pages started looking like each other six months ago, which is usually a sign that buyers are starting to ask the same comparison questions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Category three&lt;/strong&gt;: memory features inside agent frameworks. LangGraph, LlamaIndex, the Vercel AI SDK, the OpenAI Agents SDK, and a handful of others ship minimal memory primitives as part of the framework. These cover the common case (recent-turn recall, simple key-value persistence) and stop short of the harder problems: entity resolution across surface forms, temporal reasoning over versioned facts, cross-conversation synthesis. If you need real memory and you are using one of these frameworks, you almost always end up wiring in a dedicated memory layer.&lt;/p&gt;

&lt;p&gt;A small but persistent group of teams still rolls their own memory layer in-house. The argument for it (data layer, compliance, portability) is real for the first few months and gets weaker the longer the system runs. Most in-house implementations we have seen end up reimplementing the obvious primitives (&lt;a href="https://www.maximem.ai/glossary/chunking" rel="noopener noreferrer"&gt;chunking&lt;/a&gt;, embedding, recency-decay retrieval, basic deduplication) without ever getting to the harder problems (entity resolution, temporal reasoning, scoping, multi-tenant isolation). The cost compounds. The right framing for in-house is not "we built it ourselves" but "we built a worse version and now we maintain it forever." A few teams need to roll their own for regulatory reasons. Most teams convince themselves they need to, regret it eighteen months later, and migrate to a vendor anyway.&lt;/p&gt;

&lt;p&gt;A 3-category diagram of this map sits below. Marker for the design team: &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqirwvzn87kgnbyp6.public.blob.vercel-storage.com%2Fsyndication%2Fimages%2F346853de2f888c7e9961.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqirwvzn87kgnbyp6.public.blob.vercel-storage.com%2Fsyndication%2Fimages%2F346853de2f888c7e9961.svg" alt="vendor-map-2026.svg" width="1200" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How the Field Benchmarks Itself
&lt;/h2&gt;

&lt;p&gt;Two benchmarks dominate published claims in 2026: LongMemEval and LoCoMo.&lt;/p&gt;

&lt;p&gt;LongMemEval came out of Adobe Research in 2024 and was accepted at &lt;a href="https://arxiv.org/abs/2410.10813" rel="noopener noreferrer"&gt;ICLR 2025&lt;/a&gt;. It tests how well a memory system can answer questions over a long, multi-session conversational history. 500 questions, distributed across six categories: single-session-user, single-session-assistant, single-session-preference, knowledge-update, temporal-reasoning, and multi-session. The hardest category by a wide margin is multi-session, because it requires the system to synthesize evidence from multiple separate conversations rather than pulling from a single recent thread. Published methodology uses an LLM-as-judge with a binary correct-or-wrong label.&lt;/p&gt;

&lt;p&gt;LoCoMo, from Snap Research at &lt;a href="https://snap-stanford.github.io/LoCoMo/" rel="noopener noreferrer"&gt;ACL 2024&lt;/a&gt;, focuses on long-form open-ended conversations. The benchmark contains five question categories. Industry convention (the convention Mem0, Zep, and most others follow) is to exclude the adversarial category and report on categories one through four. Roughly: multi-hop reasoning, temporal reasoning, open-domain opinion, and single-hop recall. Open-domain is the category where vendor prompt engineering tends to do the most lifting, because the gold answers often follow predictable patterns (an answer of "likely no" tends to be correct when the most recent referenced event involved a bad experience, for instance).&lt;/p&gt;

&lt;p&gt;Both benchmarks share a structural property worth understanding before reading any published number. The answer model and the judge model are not part of the memory system. They are separate LLMs that the vendor configures via prompt. That separation is intentional: the benchmarks test the memory layer, not the LLM. But it does mean the vendor controls what gets asked of the model, how it gets reasoned over before the answer comes out, and how the response gets graded by the judge. Three points of leverage. All in the prompt files. Which is where reproduction starts to matter.&lt;/p&gt;

&lt;h3&gt;
  
  
  How we re-ran the numbers
&lt;/h3&gt;

&lt;p&gt;Our harness operates on a simple principle. Use each vendor's paid hosted product (or the OSS layer at its recommended configuration when no hosted product exists). Ingest the benchmark dataset through their pipeline exactly as a customer would. Then run the questions through a standardized answerer and judge that we control, so we are measuring the memory layer rather than the vendor's evaluation stack.&lt;/p&gt;

&lt;p&gt;Concretely: gpt-5 as the answer model across the board, a binary judging prompt with explicit conditions for marking both CORRECT and WRONG (no "lean toward yes" bias, no one-directional override clauses, no encoded dataset hints), five-seed averaging to control for stochasticity, and the same ingestion configuration we would recommend to any builder using the vendor SDK in production.&lt;/p&gt;

&lt;p&gt;The headline reproduction finding so far is the gap on LongMemEval, and it has two parts because we ran Mem0 twice. Before Mem0's April 14, 2026 announcement of their new state-of-the-art numbers, we ingested the LongMemEval haystack into their hosted product and ran the questions through our standardized answerer and judge. We got 57.5%. After their April 14 push (which followed the prompt-tuning commits we will detail below), we re-ran the same evaluation against their updated hosted product. We got 73.8%. The Mem0 memory layer genuinely improved by 16.3 points across that window, which is real engineering progress worth acknowledging. The published claim from the same announcement was 93.4%, still 19.6 points above the post-April-14 reproduction on the same memory system and the same data.&lt;/p&gt;

&lt;p&gt;The reason the numbers differ is not the memory layer. It is what the vendor stacks on top of the memory layer at evaluation time. In Mem0's case specifically, this stack lives in the answer and judge prompt files at github.com/mem0ai/memory-benchmarks. We audited the files at the exact commits that ship with their published claims:&lt;br&gt;&lt;br&gt;
Here are the &lt;a href="https://github.com/mem0ai/memory-benchmarks/blob/bd063eea04de4f8a19927beea155afa094a01905/benchmarks/longmemeval/prompts.py" rel="noopener noreferrer"&gt;LongMemEval prompts&lt;/a&gt; (committed April 3, 2026) and for the &lt;a href="https://github.com/mem0ai/memory-benchmarks/blob/edcd6f1d42400837b1fcb6997716f1769dc51a37/benchmarks/locomo/prompts.py" rel="noopener noreferrer"&gt;LoCoMo prompts&lt;/a&gt; (committed April 9, 2026). Both land before Mem0's April 14 number announcement; the file-level evidence of prompt-tuning is built into Mem0's own commit history (their April 3 commit message reads, in part: "Sync prompts from evals: CONTEXT CHECK, Rule 14 (contradictions), BIAS CHECK in judge, 5-step FINAL CHECK").&lt;/p&gt;

&lt;p&gt;The mechanisms surface clearly once you read those files. There are 14 dataset-specific equivalence rules in the answer prompt that map 1-to-1 to specific public LongMemEval question_ids (samples include "chandelier counts as jewelry" at line 145 and "scratch grains count as new layer feed" at line 147). There is a hidden chain-of-thought block ( tags at lines 53 and 65 &lt;a href="https://github.com/mem0ai/memory-benchmarks/blob/bd063eea04de4f8a19927beea155afa094a01905/benchmarks/longmemeval/prompts.py#L53-L65" rel="noopener noreferrer"&gt;here&lt;/a&gt; where those rules get applied before the visible answer is emitted; the judge only ever sees the cleaned answer. There is an explicit "lean toward yes" instruction in the LongMemEval judge prompt at line &lt;a href="https://github.com/mem0ai/memory-benchmarks/blob/bd063eea04de4f8a19927beea155afa094a01905/benchmarks/longmemeval/prompts.py#L269" rel="noopener noreferrer"&gt;269&lt;/a&gt; paired with a 5-step gauntlet to clear before marking anything WRONG at line &lt;a href="https://github.com/mem0ai/memory-benchmarks/blob/bd063eea04de4f8a19927beea155afa094a01905/benchmarks/longmemeval/prompts.py#L328" rel="noopener noreferrer"&gt;328&lt;/a&gt; , and no symmetric gauntlet before marking anything CORRECT. There is a one-directional gold-override clause in the LoCoMo judge at line &lt;a href="https://github.com/mem0ai/memory-benchmarks/blob/bd063eea04de4f8a19927beea155afa094a01905/benchmarks/longmemeval/prompts.py#L328" rel="noopener noreferrer"&gt;212&lt;/a&gt; that can promote a wrong prediction to correct when "evidence supports" it, but explicitly cannot demote a correct prediction to wrong when evidence contradicts it.&lt;/p&gt;

&lt;p&gt;Marker for design: this is the section where the receipt-card screenshots belong, inline. Each screenshot is captioned with the file:line citation already in the prose.&lt;/p&gt;

&lt;p&gt;Every one of these findings is documented with verbatim quotes pinned to the specific commit and line, SHA-256 hashes on mirrored copies of both prompt files, and Wayback Machine archive URLs for independent third-party timestamped copies. The full evidence chain sits in the receipts section at the end of this post.&lt;/p&gt;

&lt;p&gt;This pattern is not unique to Mem0. We are extending the testing to other vendors and will publish their reproductions as they complete. Across the vendors measured so far, the gap between published and observed tracks directly with how much benchmark-specific prompt engineering sits between the memory system and the headline number. It does not track with the quality of the memory system itself.&lt;/p&gt;

&lt;p&gt;Synap, our own product, was tested through the same harness with no benchmark-specific prompt advantages. Our numbers appear in the results table below alongside everyone else's, in every category we have measured, including the categories where we are weaker than the published competition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;Reproduction table, LongMemEval, mid-2026:&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Fbk2p9fnsn59fj9d68ikj.webp" class="article-body-image-wrapper"&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%2Fbk2p9fnsn59fj9d68ikj.webp" alt="ChatGPT Image May 27, 2026, 01\_43\_04 PM.png" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Zep number reproduced on April 10, 2026 harness; Zep has not independently verified the configuration we used.&lt;/p&gt;

&lt;p&gt;The Mem0 row is the one to read carefully. The 57.5% to 73.8% lift across the April 14 product update is real, and it is improvement Mem0 has earned the right to claim. The 73.8% to 93.4% jump from observed to published, however, is not attributable to the memory system. That part of the gap maps cleanly onto the prompt mechanisms documented in the methodology section above.&lt;/p&gt;

&lt;p&gt;Per-category breakdown, LongMemEval (Synap on current harness):&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Fuxwv9975o2zt828u5nu3.webp" class="article-body-image-wrapper"&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%2Fuxwv9975o2zt828u5nu3.webp" alt="ChatGPT Image May 27, 2026, 01\_44\_47 PM.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Fwu4r7ts81k07izv1iguo.webp" class="article-body-image-wrapper"&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%2Fwu4r7ts81k07izv1iguo.webp" alt="ChatGPT Image May 27, 2026, 01\_47\_28 PM.png" width="800" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The reproduction gap is the most interesting column in any of these tables. It is, roughly, a measure of how much non-memory-layer engineering is sitting between the underlying system and the headline number a vendor publishes. The harness, the methodology, and the seeds are documented in the section above and in the repo linked at the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is hard, what is coming
&lt;/h2&gt;

&lt;p&gt;Genuine cross-session synthesis is the hardest unsolved piece. Today, even the strongest memory layers do per-session extraction well and struggle to link the same entity across sessions when the surface representation differs. The benchmarks reflect this directly: LongMemEval multi-session is the lowest score for almost every vendor on the leaderboard. Solving it is part vector retrieval, part graph reasoning, and part ontology engineering, which is why no single team has nailed it yet.&lt;/p&gt;

&lt;p&gt;Temporal reasoning at scale is the next frontier. Calculating "what was the state of X two months ago" requires the memory system to maintain versioned facts and answer questions against a specific point in time, not just retrieve the current version and call it good. Most vendors approximate this with date metadata and good retrieval. Few do it as a first-class feature. This will start to matter more as agents move into use cases where past state is operationally consequential: compliance, audit logging, longitudinal personalization, financial agents that need to reason about what was true at a transaction date.&lt;/p&gt;

&lt;p&gt;Multi-tenant isolation paired with intelligent organizational sharing is where the enterprise segment gets decided. Enterprise buyers ask about this within the first three calls, and most memory products treat it as a configuration concern rather than an architectural one. The hard version is harder than it sounds: isolate users by default, share organizational context (vocabulary, processes, prior decisions) automatically when appropriate, expose the boundary as a primitive rather than a setting, and do all of it in genuinely shared infrastructure. The vendors that build this as a first-class primitive will win the enterprise segment over the next two years.&lt;/p&gt;

&lt;p&gt;Memory is the data layer for AI. The companies treating it as a feature will lose to the companies treating it as a category. That is the bet behind every serious memory vendor in 2026, including us.&lt;/p&gt;

&lt;h2&gt;
  
  
  Receipts and reproduction
&lt;/h2&gt;

&lt;p&gt;Everything in this post is reproducible.&lt;/p&gt;

&lt;p&gt;The harness we built and ran is open-source &lt;a href="https://github.com/maximem-ai/memory_and_context_eval_harness" rel="noopener noreferrer"&gt;here.&lt;/a&gt; One command runs the standardized binary-judge configuration against either ingest pipeline. Pull requests welcome, from vendors and independent researchers both.&lt;/p&gt;

&lt;p&gt;The Mem0 evidence chain, in full:&lt;/p&gt;

&lt;p&gt;- LongMemEval &lt;a href="http://prompts.py" rel="noopener noreferrer"&gt;prompts.py&lt;/a&gt; pinned at commit bd063eea04de4f8a19927beea155afa094a01905 (committed April 3, 2026 by Soumil Rathi). The 14 dataset-equivalence rules live at lines 138-148. The hidden chain-of-thought instruction lives at lines 53 and 65. The "lean toward yes" bias check is line 269. The 5-step FINAL CHECK before marking WRONG is lines 328-334.&lt;/p&gt;

&lt;p&gt;- LoCoMo &lt;a href="http://prompts.py" rel="noopener noreferrer"&gt;prompts.py&lt;/a&gt; pinned at commit edcd6f1d42400837b1fcb6997716f1769dc51a37 (committed April 9, 2026, same author). The opinion-question shortcuts are lines 81-82. The hardcoded LoCoMo session window ("All events occurred in 2022-2024. Never output 2025 or 2026.") is lines 64-65. The one-directional gold-override clause is line 212.&lt;/p&gt;

&lt;p&gt;- We mirrored both files locally at those commits. SHA-256 of the LongMemEval &lt;a href="http://prompts.py" rel="noopener noreferrer"&gt;prompts.py&lt;/a&gt;: ba8cf60d26f1390ecbef0f07b3e950556fe3bc5a37ba4b5343f28217f18c144f. SHA-256 of the LoCoMo &lt;a href="http://prompts.py" rel="noopener noreferrer"&gt;prompts.py&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;8ebac1ef60e9ab5caf99079fdaac038b85472e81491ed35e2d2655f3927c76c2. Any independent reproducer can fetch either file at the commit and confirm the hash.&lt;/p&gt;

&lt;p&gt;- Wayback Machine archive of the LongMemEval &lt;a href="http://prompts.py" rel="noopener noreferrer"&gt;prompts.py&lt;/a&gt; at the pinned commit: web.archive.org/web/20260505163741/... (captured May 5, 2026).&lt;/p&gt;

&lt;p&gt;Benchmark sources:&lt;/p&gt;

&lt;p&gt;- &lt;a href="https://arxiv.org/abs/2410.10813" rel="noopener noreferrer"&gt;LongMemEval&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;- &lt;a href="https://snap-stanford.github.io/LoCoMo%20(https://snap-stanford.github.io/LoCoMo/" rel="noopener noreferrer"&gt;LoCoMo&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Disclosures: we tested Mem0 through their paid hosted product, ran their published benchmark harness both verbatim and modified, and read their &lt;a href="http://prompts.py" rel="noopener noreferrer"&gt;prompts.py&lt;/a&gt; at the commits above. SuperMemory and Zep were tested on our April 10, 2026 harness (numbers cited in the table). We have not yet completed LoCoMo reproduction for Mem0's post-April-14 product; that run is in progress and will update the table when complete. We have not yet ingested Letta or Cognee on the harness.&lt;/p&gt;

&lt;p&gt;Mem0 has been invited to respond publicly. If they publish a correction with evidence we will update the post. The repo accepts pull requests from any vendor who wants their configuration tested differently. Reproducibility cuts in both directions, and we would rather have the table be right than be flattering.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Agent Memory Is Not Merely a Storage &amp; Retrieval Problem, It Is an Architecture Problem.</title>
      <dc:creator>Gaurav Dadhich</dc:creator>
      <pubDate>Sat, 25 Jul 2026 06:21:18 +0000</pubDate>
      <link>https://dev.to/gaurav_dadhich/agent-memory-is-not-merely-a-storage-retrieval-problem-it-is-an-architecture-problem-3e1j</link>
      <guid>https://dev.to/gaurav_dadhich/agent-memory-is-not-merely-a-storage-retrieval-problem-it-is-an-architecture-problem-3e1j</guid>
      <description>&lt;p&gt;Most teams building AI agents are treating memory and inference cost as something the next model release will eventually fix. They believe that a bigger context window, a smarter retriever, a cheaper token rate, etc. would absolve the need for a system for solving agent memory. &lt;/p&gt;

&lt;p&gt;This posture is convenient but it is wrong. What an agent remembers, when it forgets, and how much it costs to reason are architectural decisions. They get made long before any model is involved, and no amount of model improvement fixes a bad architecture underneath it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory is a lifecycle, not a buffer
&lt;/h2&gt;

&lt;p&gt;Most agent systems today treat context as one shared blob: everything goes in, nothing meaningfully comes out, and the "solution" to running out of room is a bigger window. That is not a memory system, it is a pile.&lt;/p&gt;

&lt;p&gt;A lifecycle approach breaks this into stages that each need their own design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ingestion: what gets written to memory in the first place, and at what granularity&lt;/li&gt;
&lt;li&gt;Scoping: what is relevant to this agent, this user, this task, versus what is just noise that happened to be nearby&lt;/li&gt;
&lt;li&gt;Decay: what loses relevance over time and should be forgotten deliberately, not accidentally truncated when the buffer fills up&lt;/li&gt;
&lt;li&gt;Retrieval: what gets pulled back into context for a given turn, and why&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Treat these as one undifferentiated blob and you get exactly the failure modes everyone complains about: agents that "forget" things that mattered and "remember" things that did not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the cost actually goes
&lt;/h2&gt;

&lt;p&gt;Most of the token spend in agent systems is not the reasoning itself, it is carrying forward context that no longer earns its place. Every stale fact, every resolved sub-task, every turn of small talk that gets re-sent on every subsequent call adds up, and it adds up silently, because nothing in a shared-buffer architecture prompts you to ask whether that context is still worth its cost.&lt;/p&gt;

&lt;p&gt;Getting this right requires treating cost as a lifecycle property too, not a line item you optimize after the fact.&lt;/p&gt;

&lt;h2&gt;
  
  
  We argue a methodology and 5 primitives would be a better approach
&lt;/h2&gt;

&lt;p&gt;I wrote this up formally in a 23-page paper, "Agentic Context Management". It includes a full evaluation harness and the underlying study data, so the argument is not just conceptual, it is something you can check.&lt;/p&gt;

&lt;p&gt;This is the same thinking behind the memory work we have been doing at Synap, now written up with data behind it.&lt;/p&gt;

&lt;p&gt;Paper: arxiv.org/abs/2607.21503&lt;/p&gt;

&lt;p&gt;Genuinely interested in where people think the lifecycle framing breaks down, especially anyone running multi-agent systems where scoping gets a lot harder.&lt;/p&gt;

&lt;p&gt;About Author:&lt;br&gt;
I am the founder of Maximem.ai - an agentic context management and agent memory company. &lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>architecture</category>
      <category>llm</category>
    </item>
    <item>
      <title>How to Give Your AI a Memory That Works Across ChatGPT, Claude, and Gemini</title>
      <dc:creator>Gaurav Dadhich</dc:creator>
      <pubDate>Fri, 06 Mar 2026 17:45:19 +0000</pubDate>
      <link>https://dev.to/gaurav_dadhich/how-to-give-your-ai-a-memory-that-works-across-chatgpt-claude-and-gemini-3pig</link>
      <guid>https://dev.to/gaurav_dadhich/how-to-give-your-ai-a-memory-that-works-across-chatgpt-claude-and-gemini-3pig</guid>
      <description>&lt;p&gt;Every time you open a new ChatGPT thread, start a fresh Claude conversation, or switch to Gemini for a different perspective, you lose something valuable: context.&lt;/p&gt;

&lt;p&gt;Your AI does not remember what you discussed five minutes ago in another tool. It does not know your preferences, your past decisions, or the research you bookmarked last week. Every interaction starts from zero.&lt;/p&gt;

&lt;p&gt;If you use multiple AI tools daily (and most power users do), this is the single biggest friction point in your workflow. Let's talk about why this happens, what "AI memory" actually means, and how to fix it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: AI Conversations Are Stateless
&lt;/h2&gt;

&lt;p&gt;Large language models are stateless by design. Each conversation exists in isolation. When you close a tab or hit a token limit, that context is gone. There is no built-in mechanism for ChatGPT to know what you told Claude, or for Gemini to pick up where ChatGPT left off.&lt;/p&gt;

&lt;p&gt;This creates three practical problems:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Repetitive onboarding.&lt;/strong&gt; You end up re-explaining your role, preferences, and project context every time you start a new session. If you have spent 30 minutes teaching ChatGPT about your codebase, that knowledge vanishes the moment you switch to Claude for a second opinion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Fragmented knowledge.&lt;/strong&gt; Your AI interactions are scattered across platforms with no connection between them. The research you did in Gemini, the code review in Claude, and the brainstorming session in ChatGPT all live in separate silos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Lost continuity.&lt;/strong&gt; Token limits mean that even within a single platform, long conversations get truncated. The AI literally forgets what you discussed earlier in the same thread.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "AI Memory" Actually Means
&lt;/h2&gt;

&lt;p&gt;When we talk about giving AI a memory, we are not talking about fine-tuning models or modifying LLM weights. We are talking about a layer that sits between you and the AI tools you use, maintaining a persistent record of context that can be injected into any conversation on any platform.&lt;/p&gt;

&lt;p&gt;Think of it as a shared context layer. The key components are:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A memory graph&lt;/strong&gt; that stores structured information about your interactions, preferences, and knowledge. This is not a raw transcript dump. It is semantically indexed information that can be retrieved and injected based on relevance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cross-platform synchronization&lt;/strong&gt; that makes this memory available regardless of which AI tool you are using. Your ChatGPT context becomes available in Claude, and vice versa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Selective context injection&lt;/strong&gt; that pulls in only the relevant memories for a given conversation, rather than flooding the AI with everything it has ever learned about you.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Vity Approaches This
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.maximem.ai/download-extension" rel="noopener noreferrer"&gt;Vity&lt;/a&gt; is a Chrome extension we built at Maximem to solve exactly this problem. Here is how it works in practice:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unified memory across platforms.&lt;/strong&gt; Vity maintains a single memory graph that works across ChatGPT, Claude, Gemini, and OpenClaw. When you establish context in one tool, that context is available in all of them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bookmark integration.&lt;/strong&gt; Vity syncs your Chrome bookmarks and X/Twitter bookmarks into your AI's active memory. That article you saved last week? Your AI can now reference it without you having to paste the link.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Privacy-first architecture.&lt;/strong&gt; All memory data is encrypted at rest and in transit. Your data stays yours. There is no model training on your interactions, no selling of your context to third parties.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WaitPro contextual flashcards.&lt;/strong&gt; While you wait for AI responses to generate, Vity surfaces contextual flashcards from your bookmarked content, turning idle seconds into micro-learning moments.&lt;/p&gt;

&lt;h2&gt;
  
  
  The OpenClaw Memory Plugin
&lt;/h2&gt;

&lt;p&gt;We recently launched the &lt;a href="https://www.memoryplugin-for-openclaw.com/" rel="noopener noreferrer"&gt;Memory Plugin for OpenClaw&lt;/a&gt;, which extends Vity's persistent memory to OpenClaw's agent ecosystem. If you are building or using OpenClaw agents, this plugin gives those agents access to your full cross-platform memory graph, so they can operate with full context about your preferences and past interactions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters for Developers
&lt;/h2&gt;

&lt;p&gt;If you are building AI-powered applications, the memory problem is one you will need to solve eventually. Users expect continuity. They expect their tools to know them over time. Stateless interactions feel broken once you have experienced the alternative.&lt;/p&gt;

&lt;p&gt;The patterns we have implemented in Vity (semantic indexing, encrypted sync, selective retrieval) are applicable to any AI product that wants to offer persistent, private memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Vity is free to get started:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chrome Extension:&lt;/strong&gt; &lt;a href="https://www.maximem.ai/download-extension" rel="noopener noreferrer"&gt;maximem.ai/download-extension&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenClaw Memory Plugin:&lt;/strong&gt; &lt;a href="https://www.memoryplugin-for-openclaw.com/" rel="noopener noreferrer"&gt;memoryplugin-for-openclaw.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Install the extension, and your AI tools will start building memory from your very next conversation. No configuration required.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I am Gaurav Dadhich, CEO and Founder of &lt;a href="https://www.maximem.ai" rel="noopener noreferrer"&gt;Maximem&lt;/a&gt;. We are building private AI memory infrastructure. If you have questions about cross-platform AI memory or want to discuss the architecture behind Vity, drop a comment below or connect with me on X.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
