What Is MCP? MCP Servers Explained and Kept Safe
MCP (Model Context Protocol) is an open standard that lets AI apps like Claude, ChatGPT and Cursor connect to outside tools and data through small programs called MCP servers.

On this page
- What is MCP?
- What is an MCP server?
- How MCP works: hosts, clients, servers and transports (stdio vs HTTP)
- What does a tool call look like?
- MCP vs API: what's the difference?
- How to use MCP with Claude (and Claude Code)
- How to build a tiny MCP server (official Python SDK)
- What happened when we ran it?
- MCP security: what can go wrong and how to stay safe
- 1. A local server can do anything you can
- 2. Limit who can reach a local server
- 3. Never pass tokens straight through
- 4. Ask for the smallest scopes
- 5. Give data servers read-only access
- 6. Keep keys out of shared config
- What does a safe MCP setup look like?
- 7. Keep servers updated, and watch advisories
- Is an MCP server free or paid?
- FAQ
What is MCP? MCP, the Model Context Protocol, is an open standard that lets an AI app such as Claude, ChatGPT or Cursor plug into outside tools and data. Each tool sits behind a small program called an MCP server. The AI app asks the server what it can do, then calls those tools for you, so the model can read a file, query a database or open a ticket instead of only chatting.
By Gary, Greenlight My App. Checked Nov 2, 2026. How we checked this: we read the official MCP docs (intro, architecture, server tutorial and security best practices) and Anthropic's Claude Code MCP docs on Nov 2, 2026, and quote them below. Our team also built and ran the tiny server below with the official Python SDK (mcp 2.3.0) and the official MCP Inspector in a throwaway folder on Nov 2, 2026; the screenshots are from that run. Drafted with AI tools and reviewed by a person before publishing.
What is MCP?
MCP stands for Model Context Protocol. The official MCP docs (external) define it as "an open-source standard for connecting AI applications to external systems." Instead of every AI app writing its own plug-in for every tool, a tool is wrapped once as an MCP server, and any app that speaks MCP can use it.
The docs use a hardware comparison: "Think of MCP like a USB-C port for AI applications." One port shape, many devices.

It's already broadly supported. Per the same page: "AI assistants like Claude and ChatGPT, development tools like Visual Studio Code, Cursor, MCPJam, and many others all support MCP."
Other meanings: MCP also stands for Microsoft Certified Professional, and in medicine for the metacarpophalangeal (knuckle) joint. This page is about the AI protocol.
What is an MCP server?
An MCP server is a small program that exposes a set of abilities to an AI app in a standard format. Those abilities come in three kinds: tools the model can call, resources it can read, and prompts it can reuse. A GitHub server might offer "create issue"; a database server might offer "run read-only query."
The architecture docs call these "primitives":
| Primitive | What it is | Example |
|---|---|---|
| Tools | Actions the AI app can call | create_issue, run_query, send_message |
| Resources | Data the app can read as context | A file, a database schema, a doc page |
| Prompts | Reusable prompt templates | "Summarize this pull request" |
A server can run on your own machine (a local server) or on someone else's (a remote server). That one fact decides most of the security questions later in this post.
How MCP works: hosts, clients, servers and transports (stdio vs HTTP)
MCP has three roles. The host is the AI app you use, such as Claude Code or Claude Desktop. For each server it connects to, the host creates one client. Each client talks to one server. They exchange JSON-RPC 2.0 messages over a transport: stdio for local servers, Streamable HTTP for remote ones.
The architecture page (external) puts it this way: an "MCP host — an AI application like Claude Code or Claude Desktop — establishes connections to one or more MCP servers," creating "one MCP client for each MCP server."

The two transports, in the docs' words:
- Stdio: "Uses standard input/output streams for direct process communication between local processes on the same machine."
- Streamable HTTP: "Uses HTTP POST for client-to-server messages with optional Server-Sent Events for streaming capabilities." It "supports standard HTTP authentication methods including bearer tokens, API keys, and custom headers. MCP recommends using OAuth to obtain authentication tokens."
What does a tool call look like?
When a host connects, it asks the server for its tool list with tools/list, then calls one with tools/call. A trimmed call looks like this:
{
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "word_count",
"arguments": { "text": "ship it safe" }
}
}The real message in today's docs also carries a _meta block with the protocol version (2026-07-28 on Nov 2, 2026); we trimmed it to show the parts that matter.
The model never runs code itself. It asks the host to call a tool; the host passes the request to the right server; the server runs its own code and sends back a result.
MCP vs API: what's the difference?
An API is how one service lets programs talk to it, and each API has its own shape. MCP is a layer above APIs: one common format that AI apps use to discover and call tools, whatever API sits behind them. Many MCP servers are thin wrappers around an existing API.
| A regular API | MCP | |
|---|---|---|
| Who it's for | Any program | AI apps (hosts) and their models |
| Shape | Different for every service | One protocol for every server |
| Discovery | You read the docs | The host asks tools/list at runtime |
| Auth | Whatever the service uses | stdio inherits your local access; HTTP uses tokens, OAuth recommended |
| Example | A REST call to create a GitHub issue | A create_issue tool on a GitHub MCP server |
So it's not MCP or an API. The GitHub MCP server still calls GitHub's API; MCP just gives every AI app the same way to ask for it. If API keys are new to you, start with what is an API key.
How to use MCP with Claude (and Claude Code)
In Claude Code, you add a server with one command: claude mcp add, plus --transport http and a URL for a remote server, or -- and a launch command for a local one. Then type /mcp inside Claude Code to check its status and sign in. Claude Desktop reads servers from a JSON config file.
From Anthropic's Claude Code MCP docs (external), a remote server:
claude mcp add --transport http notion https://mcp.notion.com/mcpA local stdio server, with a key passed as an environment variable (fake key shown):
claude mcp add --env AIRTABLE_API_KEY=XXXX --transport stdio airtable -- npx -y airtable-mcp-serverThe docs explain the --: "Everything after -- is passed to the server untouched." Manage servers with claude mcp list, claude mcp get <name> and claude mcp remove <name>.
Scopes matter for secrets. Claude Code stores servers in three scopes. Local (the default) and user scope live in ~/.claude.json; project scope writes a .mcp.json file meant to be committed. The docs suggest local scope for "servers with credentials you don't want in version control." If you use project scope, reference keys as ${API_KEY} variables instead of pasting them. Claude Code expands those from your environment. This is the docs' own example of a committed .mcp.json that holds no secret at all:
{
"mcpServers": {
"api-server": {
"type": "http",
"url": "${API_BASE_URL:-https://api.example.com}/mcp",
"headers": {
"Authorization": "Bearer ${API_KEY}"
}
}
}
}The :- part sets a default. One catch from the docs: if a variable isn't set and has no default, the config still loads, and Claude Code "uses the unexpanded $ text as-is," with a warning in claude mcp list. So check that list after a fresh clone.
For Claude Desktop, servers go in claude_desktop_config.json under an mcpServers key, each with a command and args.
How to build a tiny MCP server (official Python SDK)
The official server tutorial (external) builds servers with the Python SDK in about a dozen lines: create a project with uv, add the mcp package, decorate a function with @mcp.tool(), and run it over stdio. The docs require Python 3.10 or newer and "the Python MCP SDK 2.0.0 or higher."
Set up the project, following the tutorial's commands:
uv init notes
cd notes
uv add "mcp[cli]"Then save this as server.py. This is the exact file we ran on Nov 2, 2026 with mcp 2.3.0. It offers one harmless tool that adds two numbers, holds no secrets, and only listens on localhost when you switch it to HTTP:
import sys
from mcp.server.mcpserver import MCPServer
mcp = MCPServer("demo-tools")
@mcp.tool()
def add_numbers(a: float, b: float) -> float:
"""Add two numbers and return the sum."""
return a + b
if __name__ == "__main__":
if "--http" in sys.argv:
mcp.run(transport="streamable-http", host="127.0.0.1", port=8765)
else:
mcp.run(transport="stdio")
Two rules from the tutorial that trip people up:
- Never print to stdout in a stdio server. The tutorial says: "For STDIO-based servers: Never write to stdout." Stdout carries the protocol messages, so a stray
print()breaks them. Log to stderr instead. - Tools run with approval. The tutorial describes tools as "Functions that can be called by the LLM (with user approval)." Keep that approval step on.
To connect it to Claude Code, point a stdio entry at your start command (use your own absolute path):
claude mcp add --transport stdio notes -- uv --directory /ABSOLUTE/PATH/notes run server.pyThe docs also ship an inspector for testing a server without any AI app. For a built TypeScript server, their example is npx @modelcontextprotocol/inspector --cli node build/index.js --protocol-era modern --method tools/list.
What happened when we ran it?
We pointed the official MCP Inspector (CLI mode) at our server over stdio. Asking for tools/list returned one tool, add_numbers, with an input schema the SDK built from the Python type hints: two required numbers, a and b.

Then we called the tool with a=2 and b=40. It returned 42, both as text and as structuredContent, with "isError": false:
npx -y @modelcontextprotocol/inspector@latest --cli venv/bin/python server.py --method tools/call --tool-name add_numbers --tool-arg a=2 --tool-arg b=40
Next, the HTTP transport. Started with --http, the server listened on 127.0.0.1:8765 only, and the inspector reached it at http://127.0.0.1:8765/mcp. Nothing on another machine could connect.

Finally, we added it to Claude Code 2.1.316 as a project server in a .mcp.json file. claude mcp list showed it as "Pending approval (run claude to approve)". A project server from a shared .mcp.json waits for your approval before it runs. We didn't sign in to a paid Claude account for this post, so we stopped there.

MCP security: what can go wrong and how to stay safe
An MCP server is code you run, holding keys you give it. The official security guide warns about malicious local servers, token passthrough, server-side request forgery, session hijacking and over-broad scopes. The short version: install only servers you trust, give each one the smallest key it needs, and keep tool approvals on.
1. A local server can do anything you can
The MCP security best practices guide (external) tells clients to "Warn that MCP servers run with the same privileges as the client." Its example of a malicious startup command is one that installs a package and then uploads your SSH private key with curl. A one-line config entry is a program install. Read it like one.
The guide's advice for clients: show the exact command before running it and require explicit approval. Anthropic's Claude Code docs add: "Verify you trust each server before connecting it. Servers that fetch external content can expose you to prompt injection risk."
2. Limit who can reach a local server
For local servers, the guide says: "Use the stdio transport to limit access to just the MCP client." If a local server must use HTTP, it should "Require an authorization token" or use unix domain sockets or other restricted IPC, so other websites and programs on your machine can't call it.
3. Never pass tokens straight through
Server authors: the guide is blunt. "MCP servers MUST NOT accept any tokens that were not explicitly issued for the MCP server." A server that forwards whatever token it receives to an upstream API becomes a way around that API's own checks.
4. Ask for the smallest scopes
The guide warns against wildcard or "everything" scopes. For a GitHub server, that means a fine-grained token for the one repo it needs, read-only if possible, instead of a classic token with full repo access.
5. Give data servers read-only access
Anthropic's own database example in the Claude Code docs carries the advice "Use a read-only database user." The same idea applies to any data server: if the AI only needs to read, the credential shouldn't be able to write or delete. A prompt-injected instruction can't drop a table that the key can't touch.
6. Keep keys out of shared config

Keys in a committed .mcp.json end up in Git history. Use local scope or ${VAR} references, and keep the real values in your shell or a secret manager. If a key did leak, our guide on what to do when an AI API key is stolen walks through revoking it.
What does a safe MCP setup look like?
Most risk comes down to four choices you make at install time. Here's the same server set up two ways:
| Choice | Safer setup | Riskier setup |
|---|---|---|
| Where it comes from | The vendor's official server, or code you've read | A random repo or package you found in a thread |
| How it's reached | stdio, or HTTP with a token on localhost | HTTP on a public port with no auth |
| What key it holds | A scoped, read-only token for one service | A full-access token or an admin database login |
| Where the key lives | An environment variable or ${VAR} reference | Pasted into a committed .mcp.json |

Worked example: a GitHub server for code review. You want Claude Code to read pull requests in one repo. The safer path is a fine-grained GitHub token limited to that repo with read access to pull requests and contents, stored as GITHUB_TOKEN in your shell and referenced as ${GITHUB_TOKEN}. If that token ever leaks, the damage is one repo, read-only, and you revoke it on GitHub in a minute. A classic token with full repo scope pasted into the config could push code to every repo you own.
7. Keep servers updated, and watch advisories
MCP servers are software, and software gets security fixes. Update servers like any dependency, remove ones you no longer use, and check the project's security advisories before upgrading. When a CVE lands for a server you run, read the official advisory or the NVD entry for the fixed version rather than a summary.
A checklist you can copy:
- I know who publishes this server and I've read its install command
- It runs over stdio, or over HTTP with a token or OAuth
- Its key is scoped to one service and the least access that works
- The key lives in an environment variable, not in a committed file
- Tool approval prompts are on in my AI app
- I've removed servers I no longer use. For remote servers, Claude Code's docs say to run
claude mcp logout <name>beforeclaude mcp remove <name>so the OAuth tokens are revoked where the server supports it
For coding agents specifically, pair this with Claude Code permissions and sandboxing and our Cursor security checklist. If you route several model providers through one gateway, LiteLLM shows the same least-privilege idea for API keys. And for the bigger picture of tools that act on their own, see what is an AI agent.
Is an MCP server free or paid?
The protocol and its official SDKs are open source and free to use. Most community servers are free to run too. But a server is often a front door to a paid service, so the calls it makes can cost money on that service's bill, and hosted remote servers may need a paid account.
| Kind of server | Cost of the server | What can still cost money |
|---|---|---|
| A server you write yourself | Free | Hosting, if you run it remotely |
| Open-source local server | Free | The API it calls with your key |
| A vendor's hosted remote server | Usually included with the vendor account | That vendor's plan or usage pricing |
Check each vendor's pricing page before connecting a server that can spend on your behalf, and set a spending limit on any API key you hand it.
FAQ
What is MCP in simple terms? A standard plug that lets AI apps use outside tools. A tool is wrapped once as an MCP server, and any app that speaks MCP can call it.
What are MCP servers? Small programs that offer tools, resources and prompts to an AI app. They run locally over stdio or remotely over Streamable HTTP.
What is MCP vs API? An API is one service's interface. MCP is a shared protocol AI apps use to discover and call tools, and many MCP servers wrap an existing API.
Does ChatGPT use MCP? Yes. The official MCP docs list Claude and ChatGPT among the AI assistants that support MCP, along with Visual Studio Code and Cursor.
Is MCP server free or paid? The protocol and SDKs are open source and free. A server can still call a paid API with your key, and hosted servers may need a paid account.
Is MCP safe? It's as safe as the servers you install. Local servers run with your privileges, so use trusted servers, least-privilege keys and approval prompts.
Do I need MCP for my app? Usually not. MCP connects AI apps to tools. If your app just calls one model API from its server, a normal API call is simpler.
How do I add an MCP server to Claude Code?
Run claude mcp add with --transport http and a URL, or -- and a launch command for a local server. Then check it with /mcp.
Connected your app to AI tools? Run a free scan with Greenlight My App to check your live site's public code for exposed API keys and missing security headers.
Sources
- Model Context Protocol: What is MCP? (checked Nov 2, 2026) (external)
- Model Context Protocol: Architecture overview (checked Nov 2, 2026) (external)
- Model Context Protocol: Build an MCP server (checked Nov 2, 2026) (external)
- Model Context Protocol: Security best practices (checked Nov 2, 2026) (external)
- Claude Code docs: Connect Claude Code to tools via MCP (checked Nov 2, 2026) (external)
On this site
Related posts

Claude Pro vs Max: Limits, Price and Which to Pick
Claude Pro vs Max compared: price, 5-hour and weekly limits, the new Ultra tier, Claude Code access, and when an API key is the better choice for apps.

What Is an AI Agent? How Agents Work and Stay Safe
What is an AI agent? How agents work, types and examples, agent vs chatbot, and how to limit what an agent can reach: files, keys, terminals and deploys.

What Is GitHub? Repos, Git vs GitHub and Secrets
What is GitHub? Git vs GitHub, what a repo is, how to make your first one, public vs private, and how to keep .env files and API keys out of it.
Get the next change before it bites
Greenlight tips and new blog posts: short, practical notes when Supabase, Lovable, Bolt, Cursor or another tool you build with changes something that affects your app, plus what to check. About twice a month.
We'll send a confirmation email first. Unsubscribe anytime. Privacy. Greenlight My App is independent and not affiliated with or endorsed by Supabase, Lovable, Bolt, Cursor or any other tool we mention.
Claude and Claude Code are trademarks of Anthropic; ChatGPT is a trademark of OpenAI; Cursor and Visual Studio Code belong to their owners. None is affiliated with Greenlight My App. Keys shown are fake placeholders. This page is general information, not professional security advice, legal advice, a security audit or a guarantee. Check your own setup against the vendor's current docs.