Productivity & Tools

The Complete Guide to MCP Servers: What They Are and Why They Matter

Serge Bulaev
The Complete Guide to MCP Servers: What They Are and Why They Matter

TL;DR

Learn what MCP (Model Context Protocol) servers are, how they work, and why they matter for AI-powered development. Covers architecture, transports, security, and how to build and connect your own MCP server.

What Is an MCP Server? The Protocol Powering AI Tool Use

If you've used Claude Code, Cursor, or Windsurf recently, you've probably seen references to MCP — the Model Context Protocol. It's becoming the standard way AI assistants connect to external tools and services. But what actually is an MCP server, and why should you care?

In plain terms: an MCP server is a service that exposes tools, data, and actions to AI models through a standardized protocol. Instead of writing custom API integrations for every AI tool, you build one MCP server and it works with every MCP-compatible client — Claude Code, Cursor, Windsurf, Cline, and dozens more.

What you'll learn in this guide:

  • What the Model Context Protocol is and why Anthropic created it
  • The MCP architecture: clients, servers, and transport layers
  • How to connect to an MCP server from Claude Code, Cursor, and other clients
  • How to build your own MCP server in TypeScript and Python
  • Real-world MCP use cases — from databases to social media automation
  • Security model and best practices

The Problem MCP Solves

Before MCP, every AI tool had its own way of connecting to external services. Claude had plugins. ChatGPT had function calling with custom schemas. Cursor had its own tool system. If you wanted your service to work with three AI clients, you built three separate integrations.

This is the N x M problem: N AI clients times M external services equals N*M custom integrations. It doesn't scale.

Before MCP

  • Custom plugin for each AI client
  • Different auth flows per platform
  • No tool discovery — hardcoded tool lists
  • Fragmented ecosystem, duplicated work
  • N clients x M services = N*M integrations

With MCP

  • One protocol, works with all clients
  • Standardized auth (Bearer tokens, OAuth)
  • Dynamic tool discovery — AI finds tools itself
  • Build once, connect everywhere
  • N clients + M services = N+M integrations

Anthropic released MCP as an open standard in late 2024. Think of it as what USB did for hardware peripherals — a universal connector. Before USB, every printer had its own cable and driver. MCP is the USB of AI tool integration.

MCP Architecture: Clients, Servers, and Transports

The Model Context Protocol has three core components. Understanding the architecture helps you decide whether to use an existing MCP server, build your own, or both.

MCP Client (Host)

The AI application the user interacts with. Claude Code, Cursor, Windsurf, or any tool that implements the MCP client spec. The client discovers available tools and sends requests.

MCP Server

The service that exposes tools, resources, and prompts. Can be a cloud service (like mcp.postpost.dev), a local process, or a self-hosted application. Handles tool execution and returns results.

Transport Layer

How clients and servers communicate. Three options: HTTP (remote), stdio (local process), or SSE (streaming). The transport is abstracted — tools work the same regardless of transport.

The Protocol Flow

Here's what happens when you ask Claude Code to "schedule a post for tomorrow":

1

Initialize

Client connects to server, exchanges capabilities, discovers available tools

2

Tool Call

AI model selects a tool, client sends a JSON-RPC request to the server

3

Execute

Server validates input, runs the tool handler, calls external APIs if needed

4

Response

Server returns structured result, AI model interprets it and responds to user

Under the hood, MCP uses JSON-RPC 2.0 as its message format. Every request and response follows this standard, making it easy to debug and inspect traffic.

What MCP Servers Expose

An MCP server can expose three types of capabilities:

Capability Description Example
Tools Actions the AI can execute. Each tool has a name, description, and JSON Schema for input parameters. create-post, query-database, send-email
Resources Read-only data the AI can access. Files, database records, configuration. file://project/README.md, db://users/123
Prompts Pre-built prompt templates the server suggests. Useful for complex workflows. generate-report, analyze-codebase

Most MCP servers primarily expose tools — that's where the real power is. The AI discovers available tools at connection time, reads their descriptions and input schemas, and then decides which tools to call based on the user's request.

MCP Transport Types: How Clients Talk to Servers

The transport layer determines how the client and server communicate. MCP supports three transports, each suited to different deployment scenarios.

HTTP

Remote servers over the network. Most common for cloud services. Stateless, scalable, easy to deploy.

stdio

Local process via stdin/stdout. Client spawns the server as a child process. Zero network latency.

SSE

Server-Sent Events for streaming. Good for long-running operations. Being superseded by Streamable HTTP.

Which transport should you use?

HTTP for any cloud-hosted MCP server (like Postpost, Stripe, or your own SaaS). stdio for local dev tools that need file system access (filesystem server, git server, SQLite). SSE is being phased out in favor of Streamable HTTP in the 2025-03-26 spec revision.

Connecting to an MCP Server: Client Configuration

Let's get practical. Here's how to connect an MCP server to the most popular AI clients. We'll use Postpost's MCP server as an example, but the pattern is the same for any remote MCP server.

Claude Code

Claude Code reads MCP configuration from .claude/mcp.json in your project root or home directory. See the full client setup guide for details.

// .claude/mcp.json
{
  "mcpServers": {
    "postpost": {
      "type": "http",
      "url": "https://mcp.postpost.dev",
      "headers": {
        "Authorization": "Bearer sk_YOUR_API_KEY"
      }
    }
  }
}

Cursor

// .cursor/mcp.json
{
  "mcpServers": {
    "postpost": {
      "type": "http",
      "url": "https://mcp.postpost.dev",
      "headers": {
        "Authorization": "Bearer sk_YOUR_API_KEY"
      }
    }
  }
}

Windsurf

// ~/.codeium/windsurf/mcp_config.json
{
  "mcpServers": {
    "postpost": {
      "serverUrl": "https://mcp.postpost.dev",
      "headers": {
        "Authorization": "Bearer sk_YOUR_API_KEY"
      }
    }
  }
}

Connecting a Local stdio Server

For local MCP servers (like the official filesystem or SQLite servers), the config specifies a command to run instead of a URL:

{
  "mcpServers": {
    "filesystem": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"]
    },
    "sqlite": {
      "type": "stdio",
      "command": "uvx",
      "args": ["mcp-server-sqlite", "--db-path", "./my-database.db"]
    }
  }
}

Security note

Never commit API keys to version control. Use environment variables: "Authorization": "Bearer ${POSTPOST_API_KEY}". Most MCP clients support environment variable interpolation in config files.

Building Your Own MCP Server

Building an MCP server is surprisingly straightforward. The official SDKs handle the protocol plumbing — you just define your tools and implement the handlers. Here's how to build a minimal MCP server in both TypeScript and Python.

TypeScript MCP Server

// server.ts — a minimal MCP server with one tool
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "weather-server",
  version: "1.0.0",
});

// Define a tool with typed input schema
server.tool(
  "get-weather",
  "Get current weather for a city",
  {
    city: z.string().describe("City name, e.g. 'San Francisco'"),
    units: z.enum(["celsius", "fahrenheit"]).default("celsius")
      .describe("Temperature units"),
  },
  async ({ city, units }) => {
    // Your actual logic here — call a weather API, query a database, etc.
    const response = await fetch(
      `https://api.weather.example/v1/current?city=${encodeURIComponent(city)}`
    );
    const data = await response.json();

    const temp = units === "fahrenheit"
      ? data.temp_c * 9/5 + 32
      : data.temp_c;

    return {
      content: [
        {
          type: "text",
          text: `Weather in ${city}: ${temp}°${units === "fahrenheit" ? "F" : "C"}, ${data.condition}`,
        },
      ],
    };
  }
);

// Start the server with stdio transport
const transport = new StdioServerTransport();
await server.connect(transport);

Python MCP Server

# server.py — a minimal MCP server with one tool
from mcp.server.fastmcp import FastMCP
import httpx

mcp = FastMCP("weather-server")

@mcp.tool()
async def get_weather(city: str, units: str = "celsius") -> str:
    """Get current weather for a city.

    Args:
        city: City name, e.g. 'San Francisco'
        units: Temperature units — 'celsius' or 'fahrenheit'
    """
    async with httpx.AsyncClient() as client:
        resp = await client.get(
            "https://api.weather.example/v1/current",
            params={"city": city}
        )
        data = resp.json()

    temp = data["temp_c"]
    if units == "fahrenheit":
        temp = temp * 9 / 5 + 32

    symbol = "F" if units == "fahrenheit" else "C"
    return f"Weather in {city}: {temp}°{symbol}, {data['condition']}"


if __name__ == "__main__":
    mcp.run(transport="stdio")

Key principle: great tool descriptions

The AI model reads your tool names, descriptions, and parameter schemas to decide when to call each tool. Vague descriptions like "do stuff" lead to poor tool selection. Be specific: "Get current weather conditions including temperature, humidity, and wind speed for a given city."

Deploying as an HTTP Server

For production deployments, you'll want an HTTP transport so clients can connect remotely. Here's the TypeScript version adapted for HTTP:

// http-server.ts — MCP server with HTTP transport
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import express from "express";

const app = express();
const server = new McpServer({ name: "my-api", version: "1.0.0" });

// Define your tools here (same as before)
server.tool("my-tool", "Description", { /* schema */ }, async (args) => {
  // handler
});

// Mount MCP on an Express route
app.post("/mcp", async (req, res) => {
  const transport = new StreamableHTTPServerTransport("/mcp");
  await server.connect(transport);
  await transport.handleRequest(req, res);
});

app.listen(3000, () => {
  console.log("MCP server running on http://localhost:3000/mcp");
});

Real-World MCP Use Cases

MCP isn't just a protocol specification — it's already powering real production systems. Here are the most impactful categories of MCP servers in the ecosystem today.

Database Access

Query PostgreSQL, MySQL, SQLite, or MongoDB via natural language. The AI writes and executes SQL for you. Examples: mcp-server-sqlite, mcp-server-postgres.

File System & Code

Read, write, and search files. Git operations. Code analysis. Examples: @modelcontextprotocol/server-filesystem, mcp-server-git.

Social Media & Marketing

Schedule and publish content across platforms. Postpost's MCP server connects to 11+ platforms including Instagram, LinkedIn, X, Telegram, and YouTube.

DevOps & Infrastructure

Monitor servers, manage Kubernetes clusters, check CI/CD pipelines. Examples: GitHub MCP server, Cloudflare Workers MCP.

Web Browsing & Search

Fetch web pages, search the internet, extract structured data. Playwright MCP for browser automation, Brave Search MCP.

Communication

Send emails, Slack messages, SMS. Integrate with CRM systems. Examples: Resend MCP, Slack MCP server.

Example: Postpost as a Social Media MCP Server

Postpost is a social media management platform that exposes its full functionality through an MCP server at mcp.postpost.dev. This is a good example of how a SaaS product can offer MCP as an integration channel alongside its REST API and web dashboard.

When you connect Postpost's MCP server to Claude Code, the AI gains access to 18 tools:

18

MCP tools for content management

11+

Social platforms supported

HTTP

Transport — works from any client

Here's what a natural language interaction looks like with the Postpost MCP server connected:

You: List my connected social media accounts

Claude: I found 4 connected accounts:
1. @yourcompany on Instagram (ID: instagram-17841400...)
2. Your Company on LinkedIn (ID: linkedin-urn:li:org:...)
3. @yourcompany on X/Twitter (ID: x-12345...)
4. Your Telegram Channel (ID: telegram-chat-100...)

You: Schedule a post to all platforms for Friday at 10am: "We just shipped v2.0! Here's what's new..." and attach the screenshot from release-notes.png

Claude: Done! I've created a post scheduled for Friday, March 21 at 10:00 AM UTC across all 4 platforms. The image has been uploaded (2.1 MB). Post group ID: pg_xyz789.

The AI is calling Postpost's MCP tools under the hood — list-connections, create-post, get-upload-url — but the user just speaks naturally. That's the power of MCP: the protocol disappears, and the user gets a conversational interface to complex workflows.

MCP vs. REST APIs vs. Function Calling

If you already have a REST API, why bother with MCP? The short answer: MCP is not a replacement for REST APIs. It's a layer that sits on top, optimized for AI consumption.

Feature REST API Function Calling MCP
Designed for Human developers Specific AI model Any AI client
Tool discovery Read docs / OpenAPI Hardcoded in prompt Dynamic at runtime
Client support Any HTTP client One model provider All MCP clients
Auth Varies (API key, OAuth, etc.) Via model API Standardized (Bearer, OAuth)
Streaming SSE / WebSocket Model-dependent Built-in (SSE / Streamable HTTP)
State management Stateless per request Per conversation Session-based with initialization
Ecosystem Universal Fragmented Growing rapidly (open standard)

The best strategy is to offer both: a REST API for traditional integrations and an MCP server for AI-native integrations. This is exactly what services like Postpost do — their REST API serves developers writing code, while their MCP server serves AI agents.

The MCP Ecosystem in 2026

The MCP ecosystem has grown rapidly since the protocol launched. Here's a snapshot of where things stand.

1,000+

MCP servers in public registries

10+

Major AI clients with MCP support

Notable MCP Servers

Server Category Transport What It Does
Filesystem Development stdio Read, write, and search files in allowed directories
GitHub Development stdio Manage repos, issues, PRs, actions
PostgreSQL Database stdio Query and manage Postgres databases
Playwright Web stdio Browser automation, screenshots, testing
Postpost Social Media HTTP Post to 11+ social platforms, schedule, manage content
Stripe Payments HTTP Manage payments, subscriptions, invoices
Brave Search Search stdio Web and local search
Sentry Monitoring HTTP Error tracking and debugging

MCP Security Model

Security is the most common concern developers raise about MCP. Here's how the protocol handles it.

Built-in Security Layers

  • Human-in-the-loop: Clients require user approval before executing tool calls
  • Scoped permissions: Servers declare capabilities upfront; clients can reject unwanted ones
  • Auth required: HTTP servers authenticate via Bearer tokens or OAuth
  • Input validation: JSON Schema validates all tool inputs before execution
  • Transport security: HTTP transport uses TLS (HTTPS) by default

Risks to Watch

  • Prompt injection: Malicious content in server responses could influence the AI
  • Over-permissioning: Don't give MCP servers write access they don't need
  • API key exposure: Store keys in env vars, never commit to git
  • Untrusted servers: Only connect to MCP servers from trusted sources
  • Auto-approve mode: Some clients allow skipping confirmation — use with caution

Best practice: principle of least privilege

When building MCP servers, expose the minimum set of tools needed. A social media MCP server should not have tools to delete user accounts. Separate read-only tools from destructive ones, and consider offering different API key scopes for different levels of access.

Building a Production MCP Server: Best Practices

If you're building an MCP server for your own product or service, here are the patterns that matter most.

1. Write Excellent Tool Descriptions

The AI model's only information about your tools comes from the name, description, and parameter schemas. These are not just documentation — they are the interface.

// Bad — vague, unhelpful
server.tool("do-thing", "Does a thing", { id: z.string() }, handler);

// Good — specific, actionable
server.tool(
  "get-post-analytics",
  "Get engagement analytics (views, likes, shares, comments) for a specific published post. Returns metrics for the last 7 days by default. Only works for posts with status 'published'.",
  {
    postId: z.string().describe("The post group ID (starts with 'pg_')"),
    days: z.number().default(7).describe("Number of days to look back (1-90)"),
  },
  handler
);

2. Handle Errors Gracefully

Return clear, actionable error messages. The AI model will read these and try to help the user.

@mcp.tool()
async def create_post(content: str, platform_id: str) -> str:
    """Create a new social media post."""
    if not content.strip():
        return "Error: Post content cannot be empty. Please provide the text you want to post."

    if not platform_id.startswith(("instagram-", "linkedin-", "x-", "telegram-")):
        return (
            f"Error: Invalid platform ID '{platform_id}'. "
            "Platform IDs look like 'instagram-17841400...' or 'linkedin-urn:li:org:...'. "
            "Use the list-connections tool to find your platform IDs."
        )

    # ... actual implementation
    return f"Post created successfully. Post ID: {post_id}"

3. Implement Rate Limiting and Pagination

AI models will happily call your tools in rapid succession. Protect your backend.

server.tool(
  "list-posts",
  "List scheduled and published posts. Returns up to 20 posts per page.",
  {
    status: z.enum(["draft", "scheduled", "published", "failed"]).optional(),
    page: z.number().default(1).describe("Page number (1-indexed)"),
    limit: z.number().default(20).max(50).describe("Results per page (max 50)"),
  },
  async ({ status, page, limit }) => {
    // Enforce max limit server-side
    const safeLimit = Math.min(limit, 50);
    const offset = (page - 1) * safeLimit;

    const posts = await db.query(
      "SELECT * FROM posts WHERE ($1::text IS NULL OR status = $1) ORDER BY created_at DESC LIMIT $2 OFFSET $3",
      [status, safeLimit, offset]
    );

    return {
      content: [{ type: "text", text: JSON.stringify(posts, null, 2) }],
    };
  }
);

The Future of MCP

MCP is evolving quickly. The 2025-03-26 specification revision introduced Streamable HTTP transport (replacing SSE), improved session management, and better error handling. Here's what's on the horizon:

OAuth 2.0 Native Support

The spec is adding first-class OAuth flows, so MCP servers can authenticate users through standard OAuth providers without custom token management.

Server Discovery

Registries and discovery protocols are emerging so AI clients can find MCP servers automatically, similar to how DNS works for websites.

Agent-to-Agent Communication

MCP is being extended to support AI agents calling other AI agents — not just tools. This enables complex multi-agent workflows.

Broader Model Support

While Anthropic created MCP, more model providers are adopting it. Expect OpenAI, Google, and others to offer MCP-compatible endpoints.

Getting Started: Your Next Steps

Whether you want to use MCP servers or build one, here's the fastest path forward:

  1. Try an existing MCP server — Connect Postpost's MCP server to Claude Code in 30 seconds. It's a good way to see MCP in action before building your own.
  2. Read the MCP specification — The official docs at modelcontextprotocol.io cover every protocol detail.
  3. Build a minimal server — Use the TypeScript or Python examples above as a starting point. Start with one tool, get it working, then expand.
  4. Join the community — The MCP GitHub repo and Discord have active discussions about patterns, security, and emerging use cases.

Try MCP in action with Postpost

Connect Postpost's MCP server to Claude Code, Cursor, or Windsurf and start scheduling social media posts with natural language.

Get Started Free

Frequently Asked Questions

What is an MCP server?

An MCP server is a service that implements the Model Context Protocol — an open standard created by Anthropic. It exposes tools, resources, and prompts that AI models can call programmatically. Think of it as a standardized API layer between AI assistants and external services — databases, APIs, file systems, or SaaS platforms like social media managers.

What is the difference between MCP and a regular REST API?

A REST API is designed for human developers writing code. The Model Context Protocol is designed for AI models to discover and call tools automatically. MCP includes built-in tool discovery (the AI can list available tools and their schemas), structured input/output types, and a standardized protocol that works across any AI client. You don't need to write API integration code — the AI handles it.

Which AI clients support MCP?

As of 2026, MCP is supported by Claude Code (Anthropic's CLI), Claude Desktop, Cursor, Windsurf, Cline, Continue, Zed, and many other AI-powered development tools. The ecosystem is growing rapidly — any tool that implements the MCP client specification can connect to any MCP server. See the client setup guide for configuration details.

Is MCP only for Anthropic's Claude models?

No. MCP is an open protocol, not tied to any specific AI model. While Anthropic created it and Claude was the first model to support it, MCP works with any AI model through compatible clients. Cursor uses MCP with multiple model providers, and the protocol specification is fully open source at modelcontextprotocol.io.

How do I build my own MCP server?

Use the official MCP SDK for your language — @modelcontextprotocol/sdk for TypeScript or mcp for Python. Define your tools with names, descriptions, and JSON Schema input parameters. Implement the tool handlers that execute the actual logic. Choose a transport: HTTP for remote servers, stdio for local. Both SDKs provide server classes that handle the MCP protocol details automatically.

What are the three transport types in MCP?

MCP supports three transport types: stdio (standard input/output) for local servers that run as child processes, HTTP for remote servers accessed over the network (the most common for cloud services), and SSE (Server-Sent Events) for streaming connections. HTTP is recommended for production deployments; stdio is common for local development tools like filesystem and database servers.

Can I use MCP to post to social media?

Yes. MCP servers like Postpost let AI agents create, schedule, and publish posts to 11+ social platforms including Instagram, LinkedIn, X/Twitter, Telegram, YouTube, TikTok, and more — all through natural language commands. Connect the MCP server to Claude Code or Cursor and say "schedule a LinkedIn post for tomorrow." See the Postpost MCP documentation for the full list of tools.

Is MCP secure? Can MCP servers access my data without permission?

MCP has built-in security layers. Clients require user approval before executing tool calls (human-in-the-loop). Servers authenticate via API keys or OAuth tokens. The protocol itself does not grant servers access to your local files or data — each tool call is sandboxed and requires user confirmation. Always review tool permissions before approving MCP connections, and only connect to MCP servers from trusted sources.

Further Reading

Related Articles