What Is MCP (Model Context Protocol) and Why It Matters
Before 2025, connecting Large Language Models (LLMs) to external data sources—such as PostgreSQL databases, GitHub repositories, local file systems, or Slack APIs—required writing custom API wrappers for every combination of AI host and tool provider.
This $N \times M$ integration fragmentation created massive engineering friction. Enter **MCP (Model Context Protocol)**: an open, standardized protocol created by Anthropic and rapidly adopted across the AI ecosystem by Cursor, Zed, Sourcegraph, Cloudflare, and major dev-tool vendors.
In this guide, we break down how MCP works, why it is becoming the universal standard for AI tool integrations, and how to build a custom MCP server in TypeScript.
The Architecture of Model Context Protocol
MCP follows a classic Client-Server architectural pattern operating over JSON-RPC 2.0 (via stdio or SSE transport):
- **MCP Host**: The application requesting AI capabilities (e.g. Claude Desktop, Cursor IDE, Zed Editor).
- **MCP Client**: The protocol client embedded within the host that maintains 1:1 connections with MCP Servers.
- **MCP Server**: A lightweight executable service that exposes explicit **Resources** (data/files), **Prompts** (reusable context templates), and **Tools** (executable functions).
---
Why Vendors Are Converging on MCP
- **Universal Interoperability**: Write an MCP server once (e.g., a MongoDB connector), and it works instantly inside Claude Desktop, Cursor, Zed, or any compliant MCP host.
- **Security & Privacy Boundaries**: MCP servers run locally or inside controlled containers. Users explicitly grant permissions for tool invocations and resource reads.
- **Dynamic Context Discovery**: Host applications can inspect server capabilities dynamically at runtime without recompiling prompt templates.
---
Building a Custom MCP Server in TypeScript
Below is a practical example of a custom MCP server using `@modelcontextprotocol/sdk` in TypeScript that exposes a local weather/environment tool to any AI agent:
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,// Initialize MCP Server instance const server = new Server( { name: 'nepal-env-mcp-server', version: '1.0.0', }, { capabilities: { tools: {}, }, } );
// 1. Expose Available Tools server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: 'get_kathmandu_aqi', description: 'Fetches real-time Air Quality Index (AQI) data for Kathmandu Valley stations.', inputSchema: { type: 'object', properties: { station: { type: 'string', description: 'Station name e.g. Ratnapark or Lalitpur' }, }, required: ['station'], }, }, ], }; });
// 2. Handle Tool Execution Calls server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name === 'get_kathmandu_aqi') { const station = String(request.params.arguments?.station || 'Ratnapark');
// Simulated sensor lookup const mockData = { station, pm25: 112, aqi: 154, status: 'Unhealthy for Sensitive Groups', timestamp: new Date().toISOString(), };
return { content: [ { type: 'text', text: JSON.stringify(mockData, null, 2), }, ], }; }
throw new Error(`Tool not found: ${request.params.name}`); });
// 3. Connect via Standard I/O Transport async function main() { const transport = new StdioServerTransport(); await server.connect(transport); console.error('Nepal Env MCP Server running on stdio'); }
main().catch(console.error); ```
---
The Future of AI Infrastructure
Model Context Protocol is doing for AI tool integration what Language Server Protocol (LSP) did for IDE language support a decade ago. By decoupling model capabilities from tool ecosystems, developers can build domain-specific AI integrations that remain portable across all future frontier models.