AI & Agents

What Is an MCP Server? A Plain-English Guide for Developers

What is an MCP server? In plain English, it's the piece that gives an AI model real hands, tools it can actually call. Here's how it works.

Red and black halftone illustration: a pegboard wall hung with tools, one hook empty (TheNotificationApp)

Ask a language model to restart your server, check the database, or text you when the build's done, and it'll write you flawless code to do it, then stop cold. It can't run anything. It's a brilliant brain in a jar with no hands. An MCP server is the thing that hands it a pair.

That gap used to be everyone's private problem. Every AI app bolted on tools its own way (a custom plugin here, a bespoke function-calling shim there), and none of it transferred. Switch clients and you rebuilt all your integrations from scratch. The Model Context Protocol (MCP) is the standard that ended that, and an MCP server is the piece you actually build or connect to.

The plain-English definition

So, what is an MCP server? It's a small program that exposes a set of tools (real functions a model can call), over one shared protocol, so any AI client that speaks MCP can use them with zero custom glue.

Think of the old way as an N×M problem: every model client (Claude, Cursor, your own app) times every tool (GitHub, your database, a notification service) needed its own bespoke connector. MCP collapses that to N+M. Build the server once, and every MCP-capable client can talk to it. It's the difference between a drawer full of proprietary chargers and a single USB-C port.

Model Context Protocol, explained

MCP is an open standard, introduced by Anthropic in late 2024 and now supported across a growing list of AI clients. Underneath, it's a plain client-server setup:

  • The client is where you chat: Claude Desktop, Cursor, and a handful of others.
  • The server is the thing exposing capabilities: a GitHub server, a filesystem server, your own.

They talk over JSON-RPC, which is a fancy way of saying "structured messages back and forth." You don't have to care about the wire format; the libraries handle it. What matters is that a server can expose three kinds of things:

  • Tools: functions the model can call to do something (send a notification, run a query, open a PR).
  • Resources: data the model can read (a file, a record, a live value).
  • Prompts: reusable templates a user can trigger.

Tools are the part people mean nine times out of ten. That's where the "giving it hands" actually happens.

What happens when the model uses a tool

Walk through one round trip, because it's simpler than it sounds:

  1. The client connects to the server and asks, "what can you do?" The server answers with a list of tools and their input schemas.
  2. You ask a question. The model sees those tools and decides, on its own, that one of them fits.
  3. It emits a structured call (the tool name plus arguments), and the client runs it against the server.
  4. The server does the real work and hands back a result. The model folds that into its answer.

The important bit: the model never touches your credentials or your network directly. It only ever says "call this tool with these arguments." The server is what holds the API key and makes the request. That boundary is the whole security model.

A concrete example: an MCP server that pings your phone

Abstract is fine until you wire one up. Here's about the smallest useful MCP server there is: one that sends a push notification to your phone.

TheNotificationApp runs an MCP server you add to Claude as a custom connector. You sign in with Apple, no API keys to generate or paste, and Claude gains a single tool: send a notification. Now you can end a long agent run with "text me when you're done," and it will. The exact server URL and the click-by-click setup live in the MCP docs; if you want the full walkthrough, we covered connecting it to Claude step by step.

Under the hood, that tool wraps one ordinary HTTP call, the same one you could make yourself:

curl -X POST https://thenotification.app/api/sendNotification \
  -H "app_key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Refactor finished",
    "body": "All 20 files updated, tests green.",
    "link": "https://github.com/you/repo/pull/42"
  }'

The difference MCP makes: you don't write that call, and you don't decide when to fire it. The model does: it reads the tool's schema, fills in the title and body from whatever it just finished, and sends it at the right moment. Your only job was making the tool available.

Why build a server instead of just calling the API?

Fair question: if it's wrapping an HTTP POST, why not have the model print the curl and run it? Because a tool is a contract, not a snippet. The server tells the model exactly which arguments exist and what they mean, validates them, and keeps the credentials out of the chat transcript entirely. And because it's MCP, that same server works in Cursor, in Claude Desktop, in any client that speaks the protocol, with nothing rewritten. Build the integration once; use it everywhere. That's the payoff for a bit of extra structure over a raw API call.

The honest tradeoff

Fair warning: MCP is young. The protocol only landed in late 2024, and client support is still uneven: Claude and Cursor are all-in, plenty of other tools aren't there yet. And connecting a server means trusting it with whatever its tools can do, so read what a server actually exposes before you add it: a filesystem server can read your files, a shell server can run commands. Start low-stakes. A notification server is about as low-stakes as it gets: the worst it can do is buzz your phone. On TheNotificationApp's free tier you get 100 notifications total (a lifetime allowance, not a monthly reset), which is plenty to feel out whether "let the agent ping me" earns a place in your workflow before you pay a cent. If it sticks, Pro is $2.99/month for 1,000 a month.

Where this leaves you

MCP is boring plumbing in the best possible way: a standard dull enough that the interesting part, agents that actually do things, just works across every client you use. The fastest way to get it in your bones is to connect one server and watch a model reach for it on its own. A phone that buzzes when your agent finishes is a good first one to try. TheNotificationApp is worth a look if you keep walking away from long runs. The free tier is enough to prove it to yourself this afternoon.

Wire notifications into your AI tools

Once you have the concept, these are the per-client setups: