What the "C" in MCP actually means
The C in MCP stands for context, which sounds simple until you try to pin it down. Context is one of the most overloaded words in AI right now. It means one thing when you're talking about a model's context window, another when you're talking about an MCP server, and something else again inside the code you write with FastMCP. After our first episode, a listener named Noah left a comment asking us to untangle exactly that: what does context mean across the model, the server, and the application layers? So for episode two of the Fast MCP podcast, his comment became the whole syllabus. Radhika Gulati (Product Marketing) sat down with Jeremiah Lowin (CEO) to work through it.
What follows is an edited version of that conversation.
So what is context, really?
If you interviewed a room full of AI engineers and forgot about MCP for a second, you'd get some version of the same answer. Context is everything available to the model that shapes its worldview and its behavior in a given moment, or, more literally, whatever gets sent over the wire to the model on the next call.
Those two definitions blur together, and today we're going to blur them on purpose. The context window refers to the actual tokens that go over as part of the next API call. Context modeling is more about making information available to the model whether or not it ends up using it. One is a subset of the other. But whenever we talk about context, we're talking about the information that steers the model away from its completely default behavior, starting with the very first thing you ask it.
When you type "hi" into a model, that word is its entire context. It's what the model responds to and bases its decision on, which is probably to say hello back. Then, as the model uses tools, reads resources, and picks up skills, it builds up more and more context inside a fixed window, and everything it accumulates informs every response that comes after.
Can a model have too much context?
Yes. The context window can overflow. Depending on how your client handles that, the model can genuinely get overwhelmed. Once upon a time it would simply crash, or the API would reject the request outright. That doesn't happen as often now, but the underlying constraint hasn't gone away.
The bluntest way to deal with it is truncation. If your window is 250,000 tokens, the 250,001st token just falls off the end, and only the most recent 250,000 go through. Today a very large window is a million tokens, which fits a genuinely ridiculous amount of information. A year or two ago, a hundred thousand tokens felt like the state of the art, the point where you thought, wow, you can actually fit so much in here. As windows grow, a model follows a long conversation much better, because it can literally see everything that happened. As you approach the edge of the window, more advanced clients start doing things like compaction, which is either a lifesaver that lets you keep going or a quiet disaster that throws away a critical detail you handed it earlier, depending on how it's been tuned.
Context engineering as a practice grew straight out of that constraint. The question it keeps trying to answer is how you consistently send the smallest, most effective context to a model when you can't just keep expanding forever.
Three different things we all call context
When Noah asked about app context, server context, and model context, he put his finger on a classic problem: we've used one word to mean a bunch of things that have nothing to do with each other, beyond the fact that we picked the same word for all of them.
In FastMCP, and in the MCP SDK underneath it, there's an object literally called Context. It carries the context of an MCP request: which tool was called, when, with what authentication, and so on. That is completely separate from the context going in and out of the model. The C in MCP is the model's context, not the server's. Reusing the word inside FastMCP sounds like a ridiculous decision when you say it out loud, but every application framework has some notion of what's happening right now, and server authors really do need it. It's just a different thing from the context a model reasons over.
A quick detour: MCP servers have nothing to do with LLMs
This is worth calling out even though it feels like a tangent. An MCP server has nothing to do with LLMs, except that it happens to be called by one most of the time.
People sometimes assume a server is an AI product, that somewhere inside it a model is being invoked. Usually it isn't. An MCP server is most often very traditional, deterministic software that exposes capabilities and information, built to be used by a model that is hosted and runs entirely somewhere else. The way we want MCP to be used, that model isn't just outside the server, it's in a completely different place, and the server is being used remotely as a centralized repository of business logic and information.
So while there is a context object inside the server, the more important point is the other one: the server itself is meant to become part of the model's context. And that is exactly where MCP got itself into trouble.
The handshake lobotomy
When a model connects to an MCP server, it learns what tools are available and what instructions the server carries. For a large server, that alone can be an extraordinary amount of context, meta-information about everything the server can do, much of which has nothing to do with the task in front of it.
A poorly written client downloads all of it and shoves it into the model's brain with no concern. Connect to a big server just to say hello, just to find out what's on it, and you might spend 30,000 or 40,000 tokens of a 250,000 token window before you've done anything useful at all. That's a hell of a lot of context burned on a handshake, and we haven't even reached anything actionable yet.
As a server author you don't control that, and it isn't really your responsibility to. As a client author, you have real choices about how to manage context from a variety of sources, and a lot of early clients made bad ones. That's the wrong foot MCP started out on.
What skills got right: progressive disclosure
One reason skills became so appealing to a lot of people, Jeremiah included, is that they were designed from the very start to be progressively disclosed. No matter how long a skill is, the first thing the model reads is its name and a description that's supposed to be only a couple of sentences. Then it decides whether to read the rest.
That protects the model from the same handshake lobotomy. It spends a tiny bit of context noticing that the skill exists, then chooses to take on more. MCP never had that as an architectural decision.
Over the last several months, clients have started to close the gap. Claude, for example, now has tool search turned on by default. When it handshakes with a server it does still download the available tools, but instead of dumping them into the model, it holds them behind a new meta tool. The model just knows that if it needs a tool, it can search for one, and then it has another tool for actually using it. That single change was one of the first real defenses against the context pollution that downloading every tool would otherwise cause.
What a good MCP server looks like now
Jeremiah has given a talk a few times called "Your MCP Server Is Bad and You Should Feel Bad." The original version was shaped entirely by the handshake problem. No matter how good a job you did as a server author, connecting still dumped a huge list of tools into the model, so the advice boiled down to building the smallest useful server you could, with as few tools and as short descriptions as possible.
That's a disappointing message to give people who want to build something rich and interesting. It really amounts to saying clients are bad, so your server has to be bad too. The good news is that as clients have improved, with tool search and code mode, you can add a 26th tool, a 27th, a 99th, and not overload the system.
A couple of principles still shine through, though. Designing a server the way you'd design a REST API is usually the wrong instinct. With a REST API you do discovery once, then write a script that iterates quickly through many calls, so breadth is good. With a model, discovery happens constantly, and it's relatively expensive, because every fresh session has to learn the surface area again. So you want the discovery surface as small as possible, which is the opposite of a broad API.
The same logic applies to how you shape a workflow. If a common task takes seven atomic tool calls, the model pays for seven slow request-response cycles, each one dragging an increasingly large context window over the wire. Code mode can help here, but we shouldn't lean on it to excuse a badly designed server. The deeper reason isn't only latency or tokens. When the model later looks back at its own history and sees a single call to refund_customer, it knows exactly what happened and gets relevant information back. Seven separate calls that add up to the same refund leave behind a trail of ancillary detail that muddies the record the model is reasoning over. So we design servers to be useful in context: parsimonious enough to stay inside the window, and actionable enough that whatever comes back genuinely steers the model, because that history is the permanent record shaping its worldview.
So what does the C actually mean?
With all of that, we can finally get at the C. A model context protocol is a protocol for exposing a standard set of capabilities, with an expected set of outcomes, that form the context of the model, its knowledge at any given moment.
The most common capability is tools. Almost every hello-world MCP server is a tool call: you tell it your name and it says hi, or, for some reason, it fetches the weather. In an API setting we'd never think of that as context. In an LLM setting, context is the only thing that influences what the model does next. Even when a model makes a tool call, it doesn't really know it called a tool, or that any business logic ran. It knows it did something nominally called using a tool, and that something came back. It only ever processes tokens in and tokens out. A tool call is useful because it takes a side effect on the world, but from the model's point of view, if the information that comes back doesn't affirm that side effect, the effect might as well not have happened.
Resources were supposed to be just as common a way to add context, and they aren't, not close. A tool is like a POST to a REST API; a resource is like a GET, where you're just reading information at some URI into your context. That maps much more cleanly onto the idea of a protocol for delivering information into context. But tools took off anyway, because being able to plug into a remote server and pull down business logic felt more useful in the moment. The pitch that your agent can do things for you was simply stronger than the pitch that your agent can learn things for you.
How FastMCP makes servers more efficient
For a while we thought there wasn't much we could do about efficiency. Our job was to help people build the best server possible, and then we were at the mercy of client authors for how well that server got presented to the model. The trouble is that a lot of clients are bad, and their authors don't seem especially interested in improving how they interface with a server.
So we did something that was unusual at the time and has since become popular. We added tool search directly, the ability to search a server's tools instead of downloading all of them up front, which has an obvious impact on the context window. We also added code mode, an idea that came out of Cloudflare. Instead of asking the model to call five tools in sequence, where the output of one is the input to the next, the model writes a small script that calls those tools the way you'd script against an SDK, and it runs in a sandbox.
When you turn on code mode, a client that connects to your server doesn't see a hundred tools. It sees two: one to search for the available tools, and one to send a small script to be run. There's a discovery phase where the model works out what's on the server, and then an execution phase that's ideally a single call, though in practice it takes two or three tries to get right. If you're only making one chain of calls, you might not see much benefit. Over a long conversation, or a session that processes many items the same way, it's dramatic, because once the model works out the kinks the first time, every later item one-shots through the same script. We've seen north of 90% savings in both tokens and time.
The part we care about most is that this is something you add to the server itself with a single line. Even the dumbest client in the world gets the benefit the moment it connects to a code-mode-enabled FastMCP server, instead of waiting for that client to implement it.
A PSA on the MCP SDK v2, and FastMCP 4
One thing is worth shouting about, because the timing is tricky. As we recorded this, the beta of the official MCP SDK version 2 had just landed, and it's close to a full rewrite. For people using the MCP SDK directly, it's full of breaking changes.
So here's the PSA. If you use the MCP SDK, not FastMCP, and you're happy with how your server works, pin that dependency below version 2. When v2 releases, which we expect at the end of July, an unpinned dependency will most likely update on your next deploy and break your server. We're being as loud as we can about this: test your servers against it now.
FastMCP is already a fairly solid layer between users and the low-level SDK, so we expect a relatively small set of breaking changes there, even though a few things are changing in the protocol itself. Sampling, one of Jeremiah's favorite features and part of the reason FastMCP exists at all, has been removed from the protocol. It's supported for about another year, but we have to deprecate it. Oddly enough, because the FastMCP object used to live in the SDK's v1 and is gone in v2, the fastest path for some people may be to switch their import over to FastMCP and keep writing servers the way they always have. We're strongly considering releasing all of this as FastMCP 4, not because there are that many breaking changes, but to make it unmistakable that the whole surface underneath has changed.
Wrapping up
Our syllabus this time came from a single comment, and we're glad to keep working that way. The most honest thing we can say, same as last episode, is that we're still figuring plenty of this out ourselves. This is our current best understanding, and it will keep changing.
If something about context, or anything else in the MCP space, is confusing you, leave a comment. We read them, we respond to them, and we'll turn the good ones into the next conversation.