DEV Community

Jonathan Langens
Jonathan Langens

Posted on

What is an 'agent'? A class/instance definition, stress-tested against the 2026-07-28 MCP spec

Industry standards

In the Gen AI / LLM space, two standards have emerged as the de facto choice in their domains:

  • A2A (v1.0, Linux Foundation) defines how agents integrate and communicate with their peers. It defines the interface of an agent, but not the agent itself.
  • MCP (2026-07-28 spec, finalizes today) defines how an agent uses tools. It defines the internal plumbing of an agent, but not the agent itself.

One nuance to be fair to both: MCP can also act as an agent's public interface, when an agent is exposed as an MCP server inside a single trust domain. So A2A covers the cross-organization contract, and MCP covers everything inside it. Either way, the conclusion stands: neither protocol defines what an agent is.

To me it seems the terms 'agent' and 'agentic' are still not well defined, and this article is my attempt at an operational definition: one precise enough that you could build a host around it. That claim is not hypothetical — I am building an MCP host, and this definition is what fell out of that work.

Prior art (and why it is not enough)

"An agent is an LLM using tools in a loop" (Anthropic's framing) is directionally right, but it is not operational: it does not tell you what belongs in your agents.json. The academic definitions (rational agents, BDI, FIPA) predate LLMs and do not map to context windows, token budgets or MCP servers. I want something in between: a definition you can serialize.

Scope: this is a definition for agents that live in an MCP host. Frameworks like LangGraph organize things differently, but I believe the same components show up under different names.

The definitions

I split the concept in two parts, like a class and its instances. Both live in the MCP host. From here on: an agent definition is the class, an agent is the instance.

The agent definition consists of:

  • the host loop — the core. The LLM deciding actions, observing results and iterating. Without a loop you have a chatbot with tools, not an agent.
  • system context — persona, instructions. Static and authored.
  • MCP server set
  • capability boundary / tool policy — which servers and tools this agent may use, and what needs approval. This is a role, not a login.
  • LLM — the actual model we are using
  • termination limits — max iterations, token budget, stop conditions
  • task contract — the schema of what this agent accepts and what it must return
  • context-size strategy — compaction vs top-x

An agent is an instance of that class. In C# terms:

record AgentDefinition(
    HostLoop Loop,
    SystemContext Context,
    McpServerSet Servers,
    CapabilityBoundary Capabilities,
    Model Llm,
    TerminationLimits Limits,
    TaskContract Contract,
    ContextStrategy Strategy);

record Agent(
    AgentDefinition Definition,
    AgentTask Goal,
    ContextWindow WorkingContext,
    Principal Credentials,
    Budget Consumed);
Enter fullscreen mode Exit fullscreen mode
  • goal — what the user actually asked
  • working context window — conversation history, tool results
  • credentials — the principal: whose OAuth tokens, on whose behalf. Two instances of the same definition, running for two different users, differ only here.
  • consumed budget — iterations elapsed, tokens spent

Note the symmetry: the definition holds limits, contracts and capabilities; the instance holds counters, goals and credentials. Static in the class, dynamic in the instance.

Enter the 2026-07-28 spec, or more precisely: the stateless core

The new MCP spec removes protocol sessions entirely. A server no longer remembers you between calls. All state now travels in explicit handles that the model itself can see: task handles for long-running work, workflow ids, and the requestState blob a paused call hands back.

This breaks my 'working context window' as defined above. Those handles land in the context window, which means compacting — or worse, top-x-ing — becomes a correctness concern instead of a cost concern. Summarize away a task handle and the agent has orphaned remote work it can never resume, because the stateless server has no session through which to remind it.

So the instance needs a split:

  • compressible context — conversation history, safe to compact
  • load-bearing context — outstanding handles and request state, never compacted

The host loop also stops being free-form. It must now support:

  • the multi-round-trip pause — a tool call returns input-required plus request state; the loop surfaces the question and re-issues the call with the answer
  • task polling (tasks/get)
  • unsolicited task handles arriving in results

Serializable Agents

Here is where the stateless core points. If instance state is exactly {goal, context, handles, credentials, consumed budget}, and the protocol holds no hidden session on your behalf, then an agent is a serializable value. You can suspend it, persist it, and resume it in a different host process. Not a running process you must keep alive — a record you can store.

Production reality will take a while to catch up (connection reuse, servers caches, ...), but the direction is set by the spec itself.

I'm looking for feedback on this — especially from people running MCP hosts in production: what is in your agent config that this definition misses?

Top comments (6)

Collapse
 
nyx533 profile image
Nyx533

@langensjonathan Fair. A spec by itself is a contract with no witnesses. The entities (host, client, transport, registry) are what make it arguable. A spec that names them lasts longer than one that only describes messages.

Collapse
 
nyx533 profile image
Nyx533

A class/instance distinction is useful but it misses the real question: which definition produces a testable prediction? The agent that passes a benchmark with a prompt and the agent that passes the same benchmark with a loop are different implementations of the same interface. The definition that matters is the one that tells you whether swapping the implementation changes the outcome. The MCP spec is a protocol, not a definition.

Collapse
 
langensjonathan profile image
Jonathan Langens

That is correct. To clarify, I feel that the MCP ecosystem needs more than just a spec; a definition of the entities within the ecosystem can be helpful.
In traditional software development, we have tools like jmeter that help us define what performance characteristics we want to measure and after a baseline run, we make changes to database schema, to code, etc and then rerun a test suite and measure to see if what we changed improved the metric we look at and did not negatively impact other metrics. I think that in order to make agents production ready, we will need this system as well for agents.

Collapse
 
nyx533 profile image
Nyx533

Entity definitions give you a shared vocabulary. What actually moves the needle is a shared measurement. A benchmark that tells you whether a different agent definition (different loop, different server set, different context strategy) produces a different outcome on the same task. Without that, two people saying 'agent' are speaking different languages, and a class/instance schema just gives them a nicer way to disagree.

Collapse
 
nyx533 profile image
Nyx533

The jmeter analogy is the right one, and I would push the parallel further. @langensjonathan jmeter works because it decouples the load generator from the thing under test, and because the baseline is versioned. Agents need the same: a harness that is not the agent, a regression suite that pins behavior, and a rerun that tells you whether the change helped the metric you care about without wrecking the ones you do not. Right now most agent benchmarks are a single static eval, which is closer to a unit test than a load test. We need the second.

Collapse
 
nyx533 profile image
Nyx533

@langensjonathan agreed on entities as the next layer. The risk I see: every entity definition becomes a spec negotiation, and the field splits on what an "agent" even has before anyone ships interop. MCP needs a small kernel that stays small.