{"slug": "mcp-went-stateless-your-ai-agent-still-needs-state", "title": "MCP Went Stateless. Your AI Agent Still Needs State.", "summary": "The 2026-07-28 Model Context Protocol specification introduced a stateless protocol core, removing the session-oriented initialize flow and Mcp-Session-Id so requests can be handled independently across load-balanced servers. A developer analysis warns that stateless transport does not mean stateless workflow: long-running agents that pause for human approval must persist workflow state durably, since in-memory run tracking breaks when a follow-up request lands on a different instance after a deploy or restart. \"Stateless transport does not mean stateless workflow,\" the writeup argues, recommending persisted workflow state over process memory.", "body_md": "One of the more interesting changes in the AI engineering ecosystem in 2026 is happening below the model layer.\n\nThe latest MCP specification moved the protocol toward a **stateless core**.\n\nThat sounds like agents should become stateless too.\n\nThey shouldn’t.\n\nIn fact, as AI agents become longer-running, more autonomous, and capable of executing real actions, **application-level state becomes even more important**.\n\nThe distinction is simple:\n\nMCP should not need to remember your connection.\n\nYour agent absolutely needs to remember its work.\n\nThis difference becomes critical once you move from demos to production.\n\nWhat Changed in MCP?\n\nThe 2026-07-28 Model Context Protocol specification introduced a stateless protocol core.\n\nInstead of depending on persistent sessions between an MCP client and server, requests can carry enough information to be handled independently.\n\nThat means an MCP request can potentially hit:\n\nClient\n\n   |\n\n   v\n\nLoad Balancer\n\n   |\n\n   +------> MCP Server 1\n\n   |\n\n   +------> MCP Server 2\n\n   |\n\n   +------> MCP Server 3  \n\nwithout requiring the load balancer to keep routing a particular client back to the same server instance.\n\nThe new specification removed the old session-oriented initialize flow and Mcp-Session-Id, making requests more self-describing and much easier to scale using conventional HTTP infrastructure.\n\nThis is a good architectural change.\n\nBut there is an important trap here.\n\n**Stateless transport does not mean stateless workflow.**\n\nAn AI Agent Is Usually a State Machine\n\nImagine an agent responsible for refunding a customer.\n\nThe workflow might look like:\n\nUser asks for refund\n\n        |\n\n        v\n\nAgent investigates order\n\n        |\n\n        v\n\nChecks refund policy\n\n        |\n\n        v\n\nCalculates refund amount\n\n        |\n\n        v\n\nRequires human approval\n\n        |\n\n        v\n\n      PAUSE\n\n        |\n\n   [30 minutes]\n\n        |\n\n        v\n\nHuman approves\n\n        |\n\n        v\n\nExecute refund\n\n        |\n\n        v\n\nNotify customer  \n\nWhat happens during those 30 minutes?\n\nIf your agent state only exists inside:\n\nagent = Agent(...)\n\nresult = [agent.run](http://agent.run)(...)  \n\nyou have a problem.\n\nThe process might restart.\n\nA deployment might happen.\n\nThe request could reach another Kubernetes pod.\n\nThe machine could disappear.\n\nThe approval request could arrive hours later.\n\nThe workflow therefore cannot depend on process memory.\n\nYou need durable state.\n\nThe Wrong Architecture\n\nA common first implementation looks something like this:\n\npending_runs = {}\n\nasync def execute_agent(user_id, request):\n\n    result = await [agent.run](http://agent.run)(request)  \n\n```\nif result.requires\\_approval:  \n    pending\\_runs\\[[result.id](http://result.id)\\] = result  \n\n    return {  \n        \"status\": \"waiting\\_for\\_approval\",  \n        \"run\\_id\": [result.id](http://result.id)  \n    }\n```\n\nLater:\n\nasync def approve(run_id):\n\n    run = pending_runs[run_id]  \n\n```\nreturn await run.resume()\n```\n\nIt works perfectly...\n\nuntil you deploy it.\n\nConsider two instances:\n\n```\n         Load Balancer  \n          /         \\\\  \n         /           \\\\  \n    Server A       Server B\n```\n\nThe agent runs on Server A.\n\npending_runs[\"run_123\"]\n\nexists only in Server A's memory.\n\nThe user clicks:\n\nApprove\n\nThe load balancer sends the request to Server B.\n\nServer B asks:\n\nand gets:\n\nKeyError\n\nYour AI model isn't the problem.\n\nYour prompt isn't the problem.\n\nYour distributed system is.\n\nThe Better Architecture\n\nPersist the workflow state.\n\n```\n             ┌───────────────┐  \n             │     Client    │  \n             └───────┬───────┘  \n                     │  \n                     ▼  \n             ┌───────────────┐  \n             │ Load Balancer │  \n             └───────┬───────┘  \n                     │  \n         ┌───────────┴───────────┐  \n         ▼                       ▼  \n   ┌───────────┐           ┌───────────┐  \n   │ Server A  │           │ Server B  │  \n   └─────┬─────┘           └─────┬─────┘  \n         │                       │  \n         └───────────┬───────────┘  \n                     ▼  \n           ┌─────────────────┐  \n           │ Workflow State  │  \n           │                 │  \n           │ Postgres        │  \n           │ Redis           │  \n           │ Temporal        │  \n           │ Durable Runtime │  \n           └─────────────────┘\n```\n\nNow the agent runtime becomes replaceable.\n\nAny server can reconstruct the current workflow.\n\nSeparate Three Different Types of State\n\nThis is where production agent architecture becomes interesting.\n\nI usually think about agent state as three different layers.\n\n1. Conversation State\n\nThis is what the model needs to understand the interaction.\n\nFor example:\n\n{\n\n  \"messages\": [],\n\n  \"summary\": \"...\",\n\n  \"user_preferences\": {},\n\n  \"retrieved_context\": []\n\n}  \n\nThis state controls what the model knows.\n\n2. Workflow State\n\nThis is what your application needs to understand **where execution currently is**.\n\n{\n\n  \"workflow_id\": \"refund_39281\",\n\n  \"status\": \"WAITING_FOR_APPROVAL\",\n\n  \"current_step\": \"refund_confirmation\",\n\n  \"order_id\": \"ORD_8821\",\n\n  \"refund_amount\": 149.99\n\n}  \n\nThis is not prompt context.\n\nIt is distributed-system state.\n\n3. Side-Effect State\n\nThis tells you what the agent has already done.\n\n{\n\n  \"email_sent\": true,\n\n  \"refund_created\": false,\n\n  \"crm_updated\": true\n\n}  \n\nWithout this state, retries become dangerous.\n\nImagine:\n\nAgent calls refund API\n\n↓\n\nNetwork timeout\n\nAgent doesn't know whether refund succeeded\n\nAgent retries\n\nCustomer gets refunded twice\n\nThat is why production agents need **idempotency**.\n\nIdempotency Becomes Extremely Important\n\nEvery side-effecting tool should ideally support something similar to:\n\nrefund(\n\n    order_id=\"ORD_8821\",\n\n    amount=149.99,\n\n    idempotency_key=\"workflow_928_step_7\"\n\n)  \n\nThen:\n\nAttempt 1\n\nworkflow_928_step_7\n\n        ↓\n\nRefund $149.99  \n\nIf the workflow retries:\n\nAttempt 2\n\nworkflow_928_step_7\n\n        ↓\n\nAlready processed\n\n        ↓\n\nReturn existing result  \n\ninstead of creating another refund.\n\nThis applies to much more than payments.\n\nThink about:\n\nsend_email()\n\ncreate_ticket()\n\ndelete_resource()\n\npublish_post()\n\nupdate_crm()\n\nbook_meeting()\n\ndeploy_service()\n\ntransfer_money()  \n\nOnce AI agents can perform actions, **retry semantics become part of AI safety**.\n\nHuman Approval Is Also a Distributed Systems Problem\n\nHuman-in-the-loop workflows are becoming common for sensitive actions.\n\nAgent\n\n  |\n\n  v\n\nDraft action\n\n  |\n\n  v\n\nApproval required\n\n  |\n\n  +---------- PAUSE ----------\n\n                               |\n\n                               |\n\n                         Human approves\n\n                               |\n\n                               v\n\n                           Resume job  \n\nThe important word here is:\n\n**resume**\n\nYou don't want to restart the entire agent.\n\nYou want to continue from a durable checkpoint.\n\nModern agent frameworks increasingly expose this kind of pause/resume model. OpenAI's agent documentation, for example, describes storing serialized state when human review happens later and continuing the same run once the decision arrives.\n\nThis changes how we should think about agent execution.\n\nAn agent isn't necessarily:\n\nHTTP request\n\n    ↓\n\nLLM\n\n    ↓\n\nresponse  \n\nIt may instead be:\n\nStart\n\n ↓\n\nThink\n\n ↓\n\nTool\n\n ↓\n\nThink\n\n ↓\n\nTool\n\n ↓\n\nPause\n\n ↓  \n\n--- 4 hours later ---\n\n↓\n\nResume\n\n ↓\n\nTool\n\n ↓\n\nThink\n\n ↓\n\nComplete  \n\nThat is much closer to a workflow engine than a normal API request.\n\nDurable Execution Is Becoming Part of the Agent Stack\n\nLong-running agents introduce familiar distributed-system problems:\n\nprocess crashes\n\nnetwork failures\n\nduplicate messages\n\ntimeouts\n\nretries\n\npartial execution\n\nconcurrent updates\n\nhuman approvals\n\nscheduled execution\n\ndeployment during execution  \n\nThese problems existed long before LLMs.\n\nWe're just rediscovering them inside agent systems.\n\nA production architecture may therefore look like:\n\n```\n                    User  \n                     |  \n                     v  \n                API Gateway  \n                     |  \n                     v  \n             Agent Orchestrator  \n                     |  \n         ┌───────────┼───────────┐  \n         │           │           │  \n         v           v           v  \n       Model       Tools        MCP  \n         │           │           │  \n         └───────────┼───────────┘  \n                     |  \n                     v  \n            Durable Workflow  \n                     |  \n        ┌────────────┼────────────┐  \n        │            │            │  \n        v            v            v  \n     State DB      Queue       Event Log\n```\n\nFrameworks are increasingly acknowledging this requirement. LangChain, for example, describes durable execution, memory, human-in-the-loop support, multi-tenancy, and observability as infrastructure needed underneath long-running production agents.\n\nMCP and Durable Execution Solve Different Problems\n\nThis distinction is worth remembering.\n\nMCP answers:\n\nHow does an agent communicate with tools and external systems?\n\nDurable execution answers:\n\nHow does an agent reliably continue working over time?\n\nThey complement each other.\n\nYou might have:\n\nAgent\n\n  |\n\n  | MCP\n\n  v\n\nSalesforce  \n\nAgent\n\n  |\n\n  | MCP\n\n  v\n\nGitHub  \n\nAgent\n\n  |\n\n  | MCP\n\n  v\n\nSlack  \n\nwhile the overall workflow is managed separately:\n\nStep 1: Fetch GitHub issue\n\nStep 2: Analyze code\n\nStep 3: Generate patch\n\nStep 4: Run tests\n\nStep 5: Wait for approval\n\nStep 6: Create PR\n\nStep 7: Post Slack notification  \n\nThe MCP servers do not need to remember the entire workflow.\n\nThe orchestrator does.\n\nObservability Also Changes\n\nTraditional API monitoring might tell you:\n\nPOST /agent\n\n200 OK\n\nDuration: 4.2s  \n\nThat isn't enough.\n\nA production agent might execute:\n\nRun #8291\n\n├── Model call\n\n├── retrieve_documents\n\n├── Model call\n\n├── search_customer\n\n├── Model call\n\n├── update_customer\n\n├── approval_required\n\n├── PAUSED\n\n├── approval_received\n\n├── update_salesforce\n\n├── send_email\n\n└── complete  \n\nYou need to understand the complete trajectory.\n\nThat means tracking:\n\nmodel calls\n\ntool calls\n\ntool arguments\n\ntool responses\n\nlatency\n\ntoken usage\n\nretries\n\napprovals\n\nguardrail decisions\n\nstate transitions\n\nerrors\n\ncost  \n\nAgent platforms are moving in this direction as well. Current OpenAI tooling, for example, exposes structured tracing across model calls, tool calls, handoffs, guardrails, and custom spans.\n\nThe Production Pattern\n\nIf I were designing a serious agent system today, I would separate it roughly like this:\n\n┌───────────────────────────────┐\n\n│           API Layer           │\n\n└───────────────┬───────────────┘\n\n                │\n\n                ▼\n\n┌───────────────────────────────┐\n\n│      Agent Orchestrator       │\n\n│                               │\n\n│ Planning                      │\n\n│ Reasoning                     │\n\n│ Tool selection                │\n\n└───────────────┬───────────────┘\n\n                │\n\n       ┌────────┴────────┐\n\n       │                 │\n\n       ▼                 ▼\n\n┌─────────────┐    ┌───────────────┐\n\n│ MCP / Tools │    │ Workflow      │\n\n│             │    │ Runtime       │\n\n│ Stateless   │    │               │\n\n│ interface   │    │ Durable State │\n\n└─────────────┘    └───────┬───────┘\n\n                           │\n\n                   ┌───────┼───────┐\n\n                   ▼       ▼       ▼\n\n                  DB     Queue    Logs  \n\nNotice the separation:\n\nMCP            → tool interoperability\n\nLLM            → reasoning\n\nWorkflow layer → durability\n\nDatabase       → state\n\nQueue          → asynchronous execution\n\nTracing        → observability\n\nGuardrails     → control  \n\nTrying to make the LLM responsible for all of these concerns is where agent architecture usually starts falling apart.\n\nThe Bigger Lesson\n\nThe AI industry spent the first phase of the LLM boom asking:\n\nWhich model should we use?\n\nWhich prompt should we use?\n\nWhich agent framework should we use?\n\nThe more important production questions are increasingly becoming:\n\nHow does the workflow recover?\n\nHow do we resume execution?\n\nHow do we prevent duplicate side effects?\n\nWhere does state live?\n\nHow do we authorize tool calls?\n\nHow do we trace a 50-step execution?\n\nHow do we roll out a new agent version safely?\n\nHow do we replay failed workflows?\n\nHow do we evaluate complete trajectories?\n\nThese are not fundamentally AI questions.\n\nThey are **distributed systems questions**.\n\nAnd that might be one of the most important shifts happening in AI engineering right now.\n\nMCP becoming more stateless doesn't remove state from agent systems.\n\nIt simply puts state where it belongs.\n\n**In the application and workflow layer, not the transport protocol.**\n\nFinal Thought\n\nThe next generation of AI applications probably won't look like:\n\nUser → Prompt → LLM → Response\n\nThey will look more like:\n\nUser\n\n ↓\n\nAgent\n\n ↓\n\nPlanner\n\n ↓\n\nTools / MCP\n\n ↓\n\nDurable Workflow\n\n ↓\n\nEvents\n\n ↓\n\nApprovals\n\n ↓\n\nRetries\n\n ↓\n\nObservability\n\n ↓\n\nResult  \n\nThe model may be the brain.\n\nBut production reliability still comes from good systems engineering.\n\nAnd no amount of prompt engineering can replace that.", "url": "https://wpnews.pro/news/mcp-went-stateless-your-ai-agent-still-needs-state", "canonical_source": "https://dev.to/robin_singh_456fbe1f602b9/mcp-went-stateless-your-ai-agent-still-needs-state-2knj", "published_at": "2026-09-24 01:02:01+00:00", "updated_at": "2026-09-24 01:27:05.824886+00:00", "lang": "en", "topics": ["ai-agents", "agent-protocols", "ai-infrastructure", "developer-tools", "mlops"], "entities": ["Model Context Protocol", "MCP", "Kubernetes"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/mcp-went-stateless-your-ai-agent-still-needs-state", "markdown": "https://wpnews.pro/news/mcp-went-stateless-your-ai-agent-still-needs-state.md", "text": "https://wpnews.pro/news/mcp-went-stateless-your-ai-agent-still-needs-state.txt", "jsonld": "https://wpnews.pro/news/mcp-went-stateless-your-ai-agent-still-needs-state.jsonld"}}