
MCP (Model Context Protocol): Simply explained in 5 minutes
What MCP is, how it can save you time, and how it works behind the scenes
MCP, or Model Context Protocol, is the hot new trend right now, but it also sounds much more complicated than it actually is. In this article, I’ll simplify what MCP is for you, show you how you can use it to be more productive, and explain how it works behind the scenes.
What is MCP
Put simply, MCP is a way for LLMs to more easily integrate with external tools.
By default, when you talk to Claude, ChatGPT, or your Cursor IDE, if you ask it to “pull the latest errors from Sentry and fix them” it will have no idea what you’re talking about.
Similarly, it won’t know how to do any of these:
Read the PRD your PM provided and write tests that meet requirements
Read the messages in your #alerts channel in Slack and debug them
Create JIRA tickets for some code you found that needs to be refactored
MCP allows you to do all of these. It’s a standard protocol that engineers can follow to expose these tools to LLMs.
Below is a simplified diagram of the MCP mental model:
There are two key components
MCP Client: Various clients and apps you use, like Cursor, know how to talk using the “MCP Protocol.”
MCP Servers: Providers like Sentry, Slack, JIRA, Gmail, etc. set up adapters around their APIs that follow the MCP Protocol. Any engineer can also open source their own!
Note: The official term they’re called is MCP Servers, but the design pattern at play is the adapter pattern. They convert a message like “Get me the recent messages in the #alerts channel” to a request that can be sent to the Slack API.
So why was MCP introduced? It solves the problem of needing to manually integrate the different APIs you want to use. If you’ve ever tried talking to 3rd-party APIs, you know how much of a pain it is to integrate all the different API types and patterns. MCP solves that by forcing these providers to follow one standard interface.
We’ll dive more into what that interface looks like soon. First, let’s look at a practical case of how MCP is useful.
How it’s useful in practice
Let’s say an error appears in the browser console, and you want Cursor to solve it.
We can hook up an MCP Server to Cursor that can give Cursor “superpowers.” It’ll let Cursor read the console logs, take screenshots, and interact with the browser to test if it solved the problem. For this, I used the AgentDesk BrowserTools MCP.
Once the MCP is set up, I opened a Cursor composer window and said:
“Read from the browser console logs and fix the tooltip ref issue”
Without needing to copy-paste anything, I could tell it to read from the browser logs to fix the issue. Not only that, but it can use this tool and others to check itself. Here’s an example when using “Agent mode”
The custom tooltip approach actually got rid of the error! Now, if that’s the best approach… I didn’t think so, but that’s just a matter of re-prompting.
It was cool to see the MCP tool in use when in Agent mode. Cursor did all the things a developer would do, thinking through each step of the problem as it got stuck and identifying different tools to use. You could envision setting Cursor up with all the tools we have access to, like docs search, Slack conversations, reading from PRDs or design docs, and more. With all those tools at its disposal, it’ll become more powerful and can save you even more time.
How it actually works behind the scenes
To see how MCP works, let’s look at an actual integration—it’s simpler than you’d think. This mcp-servers repo has ones for Google Drive, GitHub, Slack, Sentry, Postgres, and more.
The Slack MCP Server is only one file. There are 3 things happening:
Defining a set of tools for the MCP Server to implement
Creating the server to listen for incoming requests
Defining a `switch` case that receives the tool call and calls the underlying external API, like the Slack API.
Part 1: Defining the tool
Each tool exposed to the client follows the “Tool” interface.
interface Tool {
name: string;
description: string;
inputSchema: InputSchema;
}
interface InputSchema {
type: ...;
properties: ...;
required: ...;
}
Here’s a “getChannelHistoryTool” in the Slack MCP:
const getChannelHistoryTool: Tool = {
name: "slack_get_channel_history",
description: "Get recent messages from a channel",
inputSchema: {
type: "object",
properties: {
channel_id: {
type: "string",
description: "The ID of the channel",
},
limit: {
type: "number",
description: "Number of messages to retrieve (default 10)",
default: 10,
},
},
required: ["channel_id"],
},
};
Cursor, or the MCP client, needs to provide the channel ID, and the Slack MCP will return the most recent 10 messages in that channel.
Part 2: Starting the server
Next, we create the server that will handle the incoming tool requests from Cursor, or the MCP Client.
const server = new Server(
{
name: "Slack MCP Server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
Part 3: Handling incoming tool calls
We need to give the server a handler to respond to tool calls, like if Cursor asks for the recent messages in a channel. Here’s what that looks like (full code here):
server.setRequestHandler(
CallToolRequestSchema,
async (request: CallToolRequest) => {
switch (request.params.name) {
case "slack_get_channel_history":
// call slack client and return messages
... other tool call case statements
}
})
Part 4: Wiring up transport between Client/Server
There’s one more, hidden part you don’t need to worry too much about, but it might be interesting for you. It’s these lines at the very bottom:
const transport = new StdioServerTransport();
await server.connect(transport);
As you’ll see in the next step, we set up this MCP server to run directly in Cursor. These two lines allow the MCP client and server to communicate more simply than standard HTTP requests. Instead, they can read from standard IO when communicating. More details are here.
How to add an MCP to Cursor
Each MCP will have its own instructions, but in general, you just need your MCP client (Cursor in this case) to run the MCP server. Things get more complicated when you need additional integrations, API keys, or permissions.
To start, let’s use the Puppeteer MCP Server which will let Cursor interact with our browser.
Create a `.cursor/mcp.json` file as directed from the Cursor docs.
Look for the “NPX” command section in the MCP Server docs.
Paste the npx command in the mcp.json file.
{
"mcpServers": {
"puppeteer": {
"args": [
"-y",
"@modelcontextprotocol/server-puppeteer"
],
"command": "npx"
}
}
}
Now, I open the command palette, go to “Cursor settings,” then enable the MCP.
After clicking to enable it, the circle will turn green and it will be marked as “Enabled.”
Now, when I give Cursor a command in the command palette, it can use Puppeteer to control the browser!
The process for setting up other MCPs is the same—it just might involve other pre-setup steps or adding environment variables. For example, the Slack MCP needs you to add a Slack App, then in your `.cursor/mcp.json` file add env variables for `SLACK_BOT_TOKEN` and `SLACK_TEAM_ID`. Full setup can be found here.
📖 TL;DR
What is MCP: It’s a way for LLMs to more easily integrate with external tools.
How MCP is useful: It gives the LLM ways to behave more like a real developer, such as reading from docs, Slack, browser logs, etc.
How it works behind the scenes: A provider, like Slack, sets up a wrapper around its API that follows the standard MCP interface. That wrapper is wired up to the MCP Client in a host like Cursor IDE. The LLM now knows how to call all the tools that Slack provides.
How to add an MCP to Cursor: Follow the docs for the given MCP server you want to add. Usually, it involves updating `.cursor/mcp.json` with the correct contents so Cursor knows how to run the MCP.
Resources:
👏 Shout-outs of the week
— I came across this gem of a newsletter to learn more about AI under the hood. Thank you, Shrivu, for this article explaining how Cursor works, sharing Cursor’s system prompt, and giving best practices for writing rules and instructions.Announcement: Paid subscribers to the newsletter can now access a discount on WriteEdge. We recently added a chat feature that gives you high-quality feedback on your technical docs. Next week’s article will dive into how it’s built behind the scenes!
Thank you for reading and being a supporter in growing the newsletter 🙏
We’re almost at 90k, let’s get there this week!
You can also hit the like ❤️ button at the bottom of this email to support me or share it with a friend to earn referral rewards. It helps me a ton!
Thank you for sharing. I didn’t know there was a term called MCP. I’m going to practice it soon.
Great article Jordan, super interesting and well written as always :)
And thanks for sharing Shirvu’s article, really enjoyed it too!