Building Your Own MCP Server: A Complete Developer's Guide

🔌 MCP (Model Context Protocol): A Deep-Dive Developer's Guide

Anthropic's open standard — how to build the 'USB-C' that connects AI agents to external resources

Key Takeaway — MCP solves the 'N×M integration explosion' that arose when each AI model required a custom adapter for every external service. By standardizing on a common protocol, it collapses the problem to N+M: implement MCP once on each side and interoperability is handled by the standard. An MCP server you build once can be shared across Claude, Cursor, Cline, Zed, and any future MCP-compatible client — making it a reusable capability asset rather than a one-off integration. This guide is for engineers ready to move from consuming MCP to building it.

🧭 1. What MCP Is — and Why It Exists

MCP (Model Context Protocol) is an open standard protocol published by Anthropic in late 2024. It standardizes how AI model clients communicate with external data sources, tools, and services — giving every party a single well-defined contract instead of a custom handshake for each pair. The USB-C analogy is apt: just as USB-C unified a fragmented device connector landscape, MCP provides a universal interface between AI agents and the external world.

📜 Why a Standard Was Needed

Before MCP, each model-to-service pair required its own bespoke adapter — OpenAI Function Calling, ChatGPT Plugins, custom REST wrappers, and so on. With N models and M services, that means N×M integration efforts, each duplicating the same plumbing: auth handling, schema negotiation, and error normalization.

MCP collapses this to an N+M structure. A model implements the MCP client interface once; a service implements the MCP server interface once. The protocol specification handles everything in between.

🧱 The Three Core Primitives

Everything an MCP server can expose is abstracted into exactly three primitive types. This classification is central to the design philosophy — and understanding it is the first decision you make when building a server: which primitive does each capability belong to?

Primitive Nature Examples
📚 Resources Read-only context File contents, DB rows, API responses
🛠️ Tools Functions with side effects File writes, email delivery, DB updates
📝 Prompts Reusable workflow templates Repeatable tasks invoked via slash commands

Tools dominate most MCP server designs, while Resources are frequently underused. A common mistake is wrapping every data lookup in a Tool — but read-only access belongs in Resources. This matters: the model can fetch a Resource without triggering the tool-confirmation UX, and Resources signal to the model that no mutation is occurring, which improves both accuracy and cost efficiency.

🧬 2. Technical Specification: Wire Format and Transport

2.1 Message Format: JSON-RPC 2.0

Every MCP message follows the JSON-RPC 2.0 specification. JSON-RPC was chosen because it is (1) a lightweight text format with minimal parsing overhead, (2) language-agnostic — any runtime that can serialize JSON can speak it, and (3) ships with a standardized error code system, so clients never have to guess what went wrong.

📤 Request — Client → server; expects a response. Carries a unique id for correlation.

📥 Response — Server → client; contains either a result or an error object, never both.

📢 Notification — One-way message; no response expected or sent.

2.2 Capability Schema: JSON Schema

When a server advertises the tools, resources, and prompts it provides, it uses JSON Schema to describe each one in a machine-readable form. The schema captures the tool's name, its description, and the type, shape, and required status of every input parameter. The model reads these schemas at runtime and uses them to decide which tool to call and how to construct valid arguments.

💡 Practical insight — The quality of the description field is the single largest lever on tool-call accuracy. "Sends an email" invites misuse. "Sends a single SMTP email to a verified recipient address. Supports plain text and HTML body. Attachments up to 10 MB. Rate-limited to 10 calls per minute." gives the model everything it needs to decide whether, when, and how to invoke the tool. Always document conditions, constraints, and side effects — not just what the tool does.

2.3 Transport Layer Comparison

Transport Use Case Characteristics
STDIO Local (same machine as Claude Desktop) Simplest setup; ideal for local file and database access. No network stack required.
HTTP + SSE Remote server Bidirectional via HTTP POST (client→server) + Server-Sent Events (server→client). Works over standard HTTP infrastructure.
Streamable HTTP 2025 spec — recommended remote standard Improved bidirectional efficiency over HTTP+SSE; next-generation recommendation for new remote deployments.

2.4 Data Flow

AI Model (Client) JSON-RPC 2.0 (STDIO / HTTP) MCP Server Tools / Resources External DB / API / FS

2.5 Authentication: OAuth 2.0 Integration (2025 Spec)

As of the 2025 specification update, remote MCP servers integrate OAuth 2.0 as the standard authentication flow. The goal is secure delegation of per-user resource access — think a user's personal Google Drive or a company's internal Slack workspace. The spec covers two patterns: the client retaining and refreshing tokens on behalf of the user, and the server performing the OAuth flow directly. Choosing the right pattern depends on whether your server acts as a first-party or third-party to the protected resource.

🛠️ 3. Building an MCP Server: Stack, Workflow, and Ecosystem

3.1 Tech Stack

Runtime: Node.js 18+ or Python 3.10+

Official SDK: TypeScript @modelcontextprotocol/sdk / Python mcp

Test client: Claude Desktop — register the server in claude_desktop_config.json and invoke tools interactively

Supporting tools: npx for zero-install execution, Git, and dotenv for .env secret management

3.2 Development Workflow: Six Steps

STEP 1
Initialize
STEP 2
Create Server
STEP 3
Register Capabilities
STEP 4
Implement Handlers
STEP 5
Attach Transport
STEP 6
Register Client

The core pattern is server.tool(name, schema, handler): declare the tool's name, its JSON Schema-described input parameters, and the handler function that receives validated arguments and returns a result. The handler can call any local resource — read files, query a database, hit an external API. For local servers, attach StdioServerTransport; for remote, wire up an HTTP endpoint with SSE support. Once running, register the server entry in claude_desktop_config.json and Claude Desktop discovers it automatically on next launch.

3.3 The MCP Ecosystem

Smithery — Community-driven MCP server registry and hub; simplifies search and installation across published servers

mcp-get — CLI package manager: npx mcp-get install <server>

Awesome MCP — Curated GitHub list covering official and community servers for GitHub, Google Drive, Slack, AWS, and more

🛡️ 4. Security and Operational Best Practices

4.1 Security: Prompt Injection Is the Top Threat

An MCP server can relay external data — web scrape output, email body text, third-party DB content — directly into the model's context. This creates a clear attack surface: malicious instructions embedded in that external data can hijack the model's behavior before it ever reaches the user. Anthropic explicitly identifies this as the primary MCP security threat. Unlike traditional injection attacks that target SQL parsers or shell interpreters, prompt injection targets the model's reasoning layer, making it subtler and harder to filter mechanically.

🔴 Three Defense Strategies

Human-in-the-loop — Tools with significant side effects (file writes, outbound messages, payments) require explicit user confirmation before execution

Content isolation (delimiter fencing) — Wrap tool responses in markers that clearly distinguish external data from system instructions, so the model treats them differently

Source attribution — Tag tool output with metadata indicating it is external data, giving the model the context it needs to apply appropriate skepticism

4.2 Risk-Based Tool Routing

Tool Call Request Has Side Effects? (write / send / pay) NO YES Auto Execute read-only OK User Approval Required human-in-the-loop

4.3 Least Privilege

Scope each server's access to the minimum required surface: a specific directory, table, or endpoint — not the whole system. For example, a filesystem server should accept a root directory as a parameter and reject any path outside it. A database server should use a read-only account for SELECT operations and a separate account — with INSERT/UPDATE/DELETE privileges — only for tools that need to mutate data. This limits the blast radius if something goes wrong.

4.4 Secret Management

API keys and database credentials must never be hardcoded in source. Load them at runtime from a .env file or the OS keychain, and add .env to .gitignore immediately — before the first commit.

4.5 Context Window Efficiency

Dumping all available data into the model's context in a single call wastes tokens and degrades response quality — the model must sift through irrelevant content before arriving at the useful signal. Implement filtering, summarization, and pagination server-side and deliver only what the current request actually needs. This is one of the highest-ROI optimizations in MCP server design.

📦 Full Data Dump
95% usage
📑 Pagination
55% usage
✂️ Filter + Summarization
22% usage

※ Context window occupancy comparison — server-side processing can achieve 4× or better efficiency for the same task

4.6 Structured Error Handling

Return JSON-RPC standard error codes and include actionable, specific messages — not generic strings like "Error". Prefer: "File not found: /path/to/x" or "Permission denied: write access to /etc requires root". The model will surface these messages to the user almost verbatim, so they need to be user-readable. Also keep the error envelope (the error key in the JSON-RPC response) structurally distinct from successful output — the model must not mistake an error payload for a valid tool result.

4.7 Additional Considerations for Remote Servers

Area Action
CORS Required when supporting browser-based clients; restrict allowed origins to known client hosts
Rate limiting Prevents backend overload from the model's rapid, repeated tool calls in agentic loops
OAuth tokens Store in KMS or Secret Manager; use short-lived tokens with automatic refresh — never long-lived static secrets

🎯 5. Where to Start: A Practical Roadmap

MCP is the protocol that elevates an AI model from a conversational tool to a system-integrated agent. The combination of JSON-RPC 2.0 + JSON Schema + STDIO/HTTP+SSE means a server you write once becomes a reusable capability consumable by any MCP-compatible client — today and in the future.

🏁 Five-Step Roadmap for Your First MCP Server

1️⃣ Start small — Expose one or two Tools via a STDIO server using the Python or TypeScript SDK. Wire it into Claude Desktop and verify end-to-end behavior before adding scope.

2️⃣ Invest in schema quality — Write precise, constraint-rich description fields. This is the highest-leverage action for improving tool-call accuracy.

3️⃣ Build security gates in from the start — Attach user-confirmation guards to any Tool with significant side effects. Retrofitting this later is painful.

4️⃣ Scale to remote when the need arises — Introduce HTTP+SSE transport and OAuth only when local deployment is insufficient. Don't over-engineer the first version.

5️⃣ Publish if it has reuse value — A server that solves a problem for you likely solves it for others. Register it on Smithery to contribute to the ecosystem.

💼 Final Thought: Shift from Consumer to Producer

The moment you start thinking about MCP not as something you plug in but as something you ship, your leverage with AI grows substantially. Internal systems, personal workflows, repetitive automation — all of it becomes absorbable as model capability. A minimal STDIO server with a single Tool is a perfectly valid starting point. Build small, iterate deliberately, and you'll find the path into the MCP ecosystem is shorter and safer than it looks.

📚 References

※ This content is provided for general technical information purposes only and does not guarantee behavior in any specific system environment. Always consult the official documentation before implementing.
S
SW Develope
Software Development Notes

Collecting and organizing software development resources firsthand, with a final review before publishing.

This post is based on publicly available data and cited sources. Last updated: June 8, 2026

댓글

이 블로그의 인기 게시물

Cutting Claude Code Token Usage by 75%: What the Caveman Technique Actually Delivers

Claude Code ultracode — What It Is, How to Enable It, and Who Can Use It

Does Open-Source Headroom Cut LLM Costs by 90%? A Fact Check