Different kinds of thing
You cannot replace RAG with MCP any more than you can replace caching with HTTP. RAG describes what happens: relevant text is found and put in front of the model before it answers. MCP describes how a model reaches a system: a standard way for a host to discover a server's tools and resources and call them. One is a pattern, the other is a wire. Put them in the same sentence and the honest version is "RAG over MCP", not "RAG or MCP".
The question is still worth answering, because behind it sits a real fork. Retrieval can run in two shapes. In the first, your code searches before every model call and pastes the results into the prompt - the classic pipeline. In the second, search is a tool the model can call during its turn, and the model decides whether, when, and how often to use it. MCP is the most common way to hand a model that tool, which is how the protocol ended up in the argument. The rest of this article compares the two shapes and says where the wire matters.
Shape one: retrieval as a step
The pipeline is RAG as most teams first built it. A question arrives; your code embeds it, queries the index, takes the top k passages, builds a prompt, and makes exactly one model call. The model never knows a search happened. From its point of view the facts were simply in the prompt.
What you get for that rigidity is control. You know precisely what the model read, so you can cite it. Retrieval is a plain function with an input and an output, so you can test it on its own: for a set of known questions, did the right passage come back in the top k? Cost and latency are the same on every question - one embedding, one index query, one generation - which is what a budget wants. And the whole thing works with any model, including ones that cannot call tools at all.
What you give up is judgement. The pipeline searches when there is nothing to find and searches once when the answer needed two hops. A question that needs a policy passage and a customer record gets one blended query, and the passages that come back match neither well. The pipeline is only as good as the query your code writes, and your code has never read the question.
Shape two: retrieval as a tool
Give the model a function called search_docs(query, k) with a description of what it searches, and retrieval moves inside the model's turn. The model reads the question, decides a search is needed, writes the query itself, reads the results, and either answers or searches again with a sharper query. This is the agent loop with retrieval as one of the tools in it.
MCP enters here. The search function has to be exposed to whatever is running the model, and if that is a host you do not own - Claude Desktop, an IDE, a colleague's agent - you cannot edit its prompt, so a pipeline is not even available to you. An MCP server that publishes search_docs as a tool is the door every one of those hosts can open. The protocol's own primitives map onto the two shapes cleanly: a tool is model-controlled, so a search tool is shape two; a resource is application-controlled, so a host that pulls a resource into the prompt before the model speaks is running shape one over the same wire. MCP does not pick a side. It carries both.
The tool shape buys adaptivity and pays in predictability. The model can chain searches, reformulate, and stop early when the first hit is enough. It can also decide not to search and answer from memory, or search six times on a question worth one, and every search is another model turn on the bill and the clock. What it read is in the trace, but what it used is not - unless you instruct it to cite, the citation is now the model's claim rather than your code's record.
The same search, both ways
Both shapes can share one retrieval function - drop the retrieve() from Inside a RAG pipeline into search.py. The pipeline calls it before the model; the tool version hands it to the model. Install openai, mcp, and the voyageai package the retriever embeds with, set OPENAI_API_KEY and VOYAGE_API_KEY, and the two files below are complete.
Read the two files as a diff and the comparison writes itself. The pipeline has a query string chosen by your code (the raw question) and a k chosen by your code; the server has neither - both are now parameters the model fills in, and your only remaining lever is the ceiling. The pipeline's instruction, "answer only from the context", lives in your prompt; in the tool version the docstring is your instruction, because the description is the only thing the model reads before deciding whether to call. Write it as carefully as you would write the prompt.
Side by side
The two shapes on the axes that actually decide between them:
| Axis | Pipeline (retrieval as a step) | Tool (retrieval over MCP) |
|---|---|---|
| Who decides to search | Your code, before every call | The model, when it judges it needs to |
| Searches per question | Exactly one, fixed k |
Zero to many; query and k chosen by the model |
| Cost and latency | Constant: one retrieval, one generation | Variable: every search adds a model turn |
| Freshness | As fresh as the last re-index | Live if the tool queries the source; index-fresh if it wraps one |
| Evaluating retrieval | In isolation: did the right passage come back? | Inside the run: read the trace to see what it searched |
| Citations | You know exactly what the model read | You know what it fetched, not what it used, unless it cites |
| Access control | A filter on the query, in your code | The server's permissions, per user and per tool |
| Hosts you do not own | Unavailable: you have to own the prompt | Any MCP host can list the tool and call it |
| Typical failure | A silent retrieval miss; the model answers from memory | The model never searches, or searches far too often |
Where they combine
Most production systems do not choose. Three combinations come up again and again:
- The index behind the tool. Everything from the RAG article - chunking, embeddings, the vector store, hybrid keyword search - still has to exist. The MCP server is a thin door in front of it. "RAG or MCP" dissolves here: the pipeline's hard part is the index, and the tool shape reuses it unchanged.
- Pre-fetch, then let the model dig. Your code runs one pipeline retrieval on the raw question so the first model turn already has the obvious passages, and the same search is also available as a tool for follow-ups. Cheap questions finish in one turn; hard ones get the loop.
- Resources for the known, tools for the unknown. Context you can name in advance - the customer's account, the open ticket, the current file - goes in as an MCP resource the host attaches before the model speaks. Context that depends on what the question turns out to be goes behind a tool.
The common thread is that the split is by who knows what to fetch. When your code knows, fetch it up front and spend no model turns on it. When only the model can tell after reading the question, hand it the tool.
Which to pick
If you remember one rule: pick by who is in a position to write the query.
- Pipeline when every question needs the same kind of context, when cost and latency have to be predictable, when you need to evaluate retrieval separately from generation, or when the model in front of you does not call tools. A support bot over one policy corpus is a pipeline.
- Tool over MCP when questions vary in what they need, span several sources, or take more than one hop; when the consumer is a host you do not control; or when several hosts should share one retrieval capability. An internal assistant that answers from the wiki, the ticket tracker, and the data warehouse is a set of tools.
- Both when you have a good index already and the agent is the new consumer. Put the pipeline's search behind a server and keep the pipeline for the surfaces you own.
And the answer to the question this started with - "do we still need RAG now that we have MCP" - is that MCP changed who calls the search and how it is plugged in. It did not change what the search is made of. The index still has to be built, kept fresh, and tested for misses, whichever side of the wire triggers it.
References
- Model Context Protocol - specification (tools, resources, prompts)modelcontextprotocol.io
- MCP Python SDK - FastMCP server referencegithub.com/modelcontextprotocol
- Anthropic - Building effective agents (the augmented LLM: retrieval, tools, memory)anthropic.com/research
- Lewis et al. - Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasksarxiv.org/abs/2005.11401