Skip to main content
FreeDiscordTools
← Back to Blog

What is MCP? Model Context Protocol & MCP Servers Fully Explained (2026)

Published on June 20, 2026·FreeDiscordTools

The Bespoke Integration Nightmare: AI in a Sandbox

Imagine purchasing a state-of-the-art computer, only to find that it lacks USB ports, HDMI connectors, or internet access. It has no way to interface with the outside world. To connect a printer or a keyboard, you would have to open the computer chassis, solder wires directly to the motherboard, and write a custom driver from scratch. This is exactly what developers faced when building AI-powered applications before the arrival of the Model Context Protocol (MCP).

Large Language Models (LLMs) are incredibly smart. They write code, draft essays, and analyze complex logical problems. However, by default, they are locked inside an execution sandbox. They have no access to your local files, no knowledge of your customer database, no capability to query real-time APIs, and no power to run terminal commands. To give them these powers, developers built custom, bespoke integration code for every single tool and model. A database connection code for Claude could not be used with Gemini. An API integration wrapper in Cursor had to be rewritten for Zed. This fragmented approach led to duplicate codebases, security vulnerabilities, and massive engineering overhead.

This is the problem solved by the Model Context Protocol (MCP). Created by Anthropic and open-sourced to the community, MCP acts as the "USB-C port" for AI models. It defines a single, open standard for how AI clients (like Claude Desktop or Cursor) connect to external servers (which expose databases, APIs, and tools). Write the integration once as an MCP server, and any compliant AI application can use it instantly.

Why MCP Matters: Instead of building 50 custom integrations for 5 different AI clients (250 distinct adapters), developers build 50 MCP servers that work automatically across all 5 clients. This standard shifts the focus from writing glue code to building rich tools.

What is Model Context Protocol (MCP)?

The Model Context Protocol (MCP) is a standardized, open-source protocol that establishes a secure, structured communication channel between AI applications (clients) and external data sources or tools (servers). The protocol utilizes JSON-RPC 2.0 over standard transport channels (like stdio or HTTP with Server-Sent Events) to negotiate capabilities, request data, and execute functions.

By defining a shared contract, MCP decouples the AI model from the tooling layer. The AI client doesn't need to know how to query a database or scrape a web page; it simply asks the MCP server to do it. The server executes the operation and returns the results formatted in a way the model can easily digest.

The Three Core Primitives of MCP

An MCP server can expose three primary capabilities to a client. These are called the core primitives:

1. Tools (Action Execution)

Tools are executable functions that allow the AI to perform actions or compute results in the external world. A tool has a defined name, a description, and an input schema defined using **JSON Schema** or **Zod**. When the AI model decides it needs to take an actionfor instance, writing a file or calling an APIit issues a tool-call request. The client routes this request to the server, which runs the underlying code and returns the outcome.

Examples of tools include: search_web(query), run_query(sql), or send_slack_message(channel, text).

2. Resources (Context Injection)

Resources are read-only data sources that provide the AI with static or dynamic context. Resources are identified by unique URIs (e.g., file:///workspace/src/app.ts or api://docs/mcp-setup). The client can query these resources to retrieve snapshots of code, documentation files, configuration settings, or database schemas. Because they are read-only, resources are a safe way to inject data into the model's context window without risking destructive modifications.

3. Prompts (Pre-configured Templates)

Prompts are reusable templates stored on the server that help users structure their interactions with the AI. They can contain pre-written instructions and placeholders for variables. An MCP server for git, for example, might expose a prompt called review-code that tells the model exactly how to perform a security review on a specified file path. Prompts encode expert workflows directly into the server.

Before MCP vs. After MCP: The Architecture Shift

To see how revolutionary the protocol is, examine this comparative table of development before and after the MCP standard:

Before MCP With MCP Protocol
Bespoke API wrappers rewritten for every tool and app. One universal standard. A server built once works everywhere.
Platform lock-in. Tools tied to Cursor don't work in Claude. Platform agnostic. Works in Claude, Cursor, Zed, and custom apps.
Fragile client logic. Custom parsers for diverse JSON formats. Strict JSON-RPC contracts ensuring reliable message exchange.
Security handled ad-hoc. High risk of token exposure. Defined security boundaries. Sandboxed stdio processes.

How the Protocol Works Under the Hood: Technical Deep Dive

MCP is built on top of JSON-RPC 2.0, a lightweight remote procedure call protocol. In an MCP connection, there is always a **Client** (the AI app) and a **Server** (the tool provider). The communication is message-based, following a request-response pattern. Here is the step-by-step flow of an active session:

  1. Handshake & Initialization: The client spawns the server process (via stdio transport) or opens a network socket (via SSE transport). They exchange initialization requests to align on protocol versions and optional capabilities.
  2. Discovery: The client calls tools/list, resources/list, and prompts/list. The server replies with schemas containing descriptions and arguments for all available capabilities.
  3. Context Construction: The client formats the server schemas and registers them in the system instructions for the LLM. The model is now aware of the tools it can use.
  4. Tool Execution: When the model decides to run a tool, it generates a JSON block containing the tool's name and arguments. The client intercepts this tool call, builds a tools/call JSON-RPC request, and forwards it to the server.
  5. Response: The server executes the function locally, formats the output (text, images, or JSON), and replies. The client feeds the result back to the model, which resumes its task.

Available Transports: stdio vs HTTP SSE

MCP supports two main communication channels:

  • stdio Transport: The client launches the server as a local subprocess and communicates via standard input/output streams. This is the default transport for local tools (like filesystem search) because it inherits the client's local security context and doesn't expose any ports to the network.
  • Server-Sent Events (SSE) Transport: The client establishes an HTTP connection to a remote hosted server. The server sends events downstream via SSE, and the client sends requests upstream using HTTP POST. This is designed for hosted cloud services and collaborative enterprise data repositories.

Step-by-Step Tutorial: Building Your First MCP Server in TypeScript

Let's build a practical, functional MCP server from scratch. We will write a server that exposes a calculator tool and a local file explorer tool using Node.js, TypeScript, and the official @modelcontextprotocol/sdk package.

1. Initializing the Project

Create a new directory and initialize your project:

mkdir my-mcp-server
cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript ts-node @types/node

Create a basic tsconfig.json file in your directory:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "esModuleInterop": true,
    "strict": true,
    "skipLibCheck": true
  }
}

2. Writing the Server Code

Create a file named src/index.ts and add the following complete implementation:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import * as fs from "fs/promises";
import * as path from "path";

// Initialize the MCP server metadata
const server = new McpServer({
  name: "custom-utility-server",
  version: "1.0.0"
});

// Register Tool 1: Math Calculator
server.tool(
  "calculate",
  {
    operation: z.enum(["add", "subtract", "multiply", "divide"]).describe("Operation to perform"),
    a: z.number().describe("First operand"),
    b: z.number().describe("Second operand")
  },
  async ({ operation, a, b }) => {
    let result = 0;
    switch (operation) {
      case "add": result = a + b; break;
      case "subtract": result = a - b; break;
      case "multiply": result = a * b; break;
      case "divide": 
        if (b === 0) {
          return {
            isError: true,
            content: [{ type: "text", text: "Error: Division by zero is not allowed." }]
          };
        }
        result = a / b;
        break;
    }
    return {
      content: [{ type: "text", text: `Calculation result: ${result}` }]
    };
  }
);

// Register Tool 2: Read Local Directory
server.tool(
  "list_directory_contents",
  {
    dirPath: z.string().describe("Absolute path to the directory to list")
  },
  async ({ dirPath }) => {
    try {
      const resolvedPath = path.resolve(dirPath);
      const files = await fs.readdir(resolvedPath);
      const details = await Promise.all(
        files.map(async (file) => {
          const stats = await fs.stat(path.join(resolvedPath, file));
          return `${stats.isDirectory() ? "[DIR]" : "[FILE]"} ${file} (${stats.size} bytes)`;
        })
      );
      return {
        content: [{ type: "text", text: details.join("\n") || "Directory is empty." }]
      };
    } catch (error: any) {
      return {
        isError: true,
        content: [{ type: "text", text: `Failed to read directory: ${error.message}` }]
      };
    }
  }
);

// Start the server using stdio transport
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Custom MCP Server running on stdio transport");
}

main().catch((error) => {
  console.error("Fatal error in main:", error);
  process.exit(1);
});
Crucial Server Practice: Always direct server status logs (like "Server running") to console.error. The main stdout stream is reserved exclusively for the JSON-RPC protocol messages. Sending plain text to stdout will corrupt the handshake and crash the client connection.

3. Building the Server

Add a build step in your package.json:

"scripts": {
  "build": "tsc",
  "start": "node dist/index.js"
}

Run npm run build to compile the TypeScript code into JavaScript.

How to Connect the Server to AI Clients

Now that your server is compiled, you can plug it into standard developer-facing AI clients. Here are the config details:

1. Claude Desktop Configuration

Claude Desktop is the flagship client. Open your configurations file:

  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

Add your server to the mcpServers dictionary:

{
  "mcpServers": {
    "my-custom-server": {
      "command": "node",
      "args": ["C:/path/to/my-mcp-server/dist/index.js"]
    }
  }
}

Restart Claude Desktop. You will see a small plug icon in the prompt box, indicating that Claude has discovered and registered your calculator and directory tools.

2. Cursor Configuration

To configure your custom server in Cursor:

  1. Go to Settings → Cursor Settings → Features → MCP.
  2. Click + Add New MCP Server.
  3. Set the name to my-custom-server, transport to command, and value to node C:/path/to/my-mcp-server/dist/index.js.
  4. Click Save. Cursor will connect to the process and show green status indicators next to the registered tools.

MCP Security Model: Keeping the Sandbox Safe

Giving an AI model access to your local machine is inherently risky. A malicious tool could wipe your hard drive, access credentials, or leak sensitive source code. MCP implements strict security boundary rules to protect the user:

  • User Authorization: compliant clients surface notifications to the user before running destructive tools. For instance, if the model attempts to run a tool to write code, the client alerts the user with a prompt asking for permission.
  • Standard Streams Separation: The stdio transport model sandboxes the process context. The server has access only to the file directory ranges it was explicitly launched in, preventing general access hikes.
  • Authentication on SSE: Remote connections over HTTP SSE require standard API key authorization or OAuth wrappers, ensuring only authenticated clients can trigger backend database servers.

The Rising MCP Ecosystem: Popular Community Servers

The standard has triggered massive community growth. There are thousands of pre-built MCP servers you can use without writing code. Highlights include:

  • Filesystem Server: Exposes local directory search, file reads, and edits to Claude and Cursor.
  • GitHub Server: Lets the AI view issues, open pull requests, look up commit logs, and search repositories.
  • Puppeteer Server: Allows the AI to browse the web, click navigation targets, enter form parameters, and capture page screenshots.
  • PostgreSQL / MySQL Servers: Exposes SQL database structures and tables so the AI can write, run, and verify database scripts.

Frequently Asked Questions About Model Context Protocol

What is MCP in AI?
MCP stands for Model Context Protocol. It is an open-source standard designed by Anthropic that defines how AI models connect to external tools, database systems, and APIs. It functions like a universal USB adapter for AI systems.
What is an MCP server?
An MCP server is a standalone process that connects to a specific data source or tool (like a file directory or database) and exposes its operations as tools, resources, or prompt templates using standard JSON-RPC protocol structures.
Does MCP only work with Claude models?
No. Although created by Anthropic, the standard is completely model-agnostic. Any LLM (including GPT-4, Gemini, and Llama) can consume tools from an MCP server as long as the client application (like Cursor or custom code) implements the protocol.
Why can't I use console.log in my MCP server code?
In local stdio transport, the server communicates with the client via stdout. Using console.log() writes standard text to stdout, corrupting the JSON-RPC format and causing the client to crash. Always direct custom debug messages to console.error(), which uses stderr.

Try the Tools

Explore our full collection of free utilities for Discord, developers, and job seekers.

View All Tools →