Skip to content
Back to blog

MCP (Model Context Protocol) Explained: The Future of AI Tool Use

Understand what the Model Context Protocol (MCP) is, how it standardizes AI-tool communication, and learn to build an MCP server with practical use cases.

MH
Mahmoud Hashem
· November 20, 2024 · 6 min read
Protocol and connection concept with networked devices

Introduction

The Model Context Protocol (MCP) is an open standard that defines how AI models communicate with external tools and data sources. Introduced by Anthropic in late 2024, MCP aims to solve a fundamental problem in AI development: every integration between an LLM and an external system requires custom, bespoke work. MCP standardizes this communication, making it possible to build a tool once and use it with any MCP-compatible AI client.

This article explains what MCP is, why it matters, and how to build your own MCP server.

The Problem MCP Solves

Before MCP, connecting an AI model to external tools followed a fragmented pattern:

  • OpenAI function calling used one format
  • Anthropic tool use used another
  • LangChain tools had their own interface
  • Custom integrations were built from scratch each time

This meant that if you built a tool for OpenAI’s API, you couldn’t use it with Claude without rewriting the integration layer. Every new model required new adapters.

MCP addresses this by defining a standard protocol for tool communication. Build an MCP server once, and any MCP-compatible client can use it.

How MCP Works

MCP follows a client-server architecture:

MCP Server

An MCP server exposes capabilities to AI clients. A server can provide three types of capabilities:

  1. Tools: Functions the AI can call (e.g., search a database, send an email)
  2. Resources: Data the AI can read (e.g., file contents, database records)
  3. Prompts: Pre-defined prompt templates the AI can use

MCP Client

An MCP client (typically an AI application or agent framework) connects to MCP servers and makes their capabilities available to the AI model. The client handles the protocol communication, presenting tools to the model in the format it expects.

Protocol

MCP uses JSON-RPC 2.0 as its message format, communicating over stdio or HTTP with Server-Sent Events (SSE). This makes it language-agnostic and transport-flexible.

Building an MCP Server

Let’s build a practical MCP server that provides file system tools. We’ll use the official MCP Python SDK.

Installation

pip install mcp

A File System MCP Server

from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
import os
import json

server = Server("filesystem-server")

@server.list_tools()
async def list_tools() -> list[Tool]:
    return [
        Tool(
            name="read_file",
            description="Read the contents of a file",
            inputSchema={
                "type": "object",
                "properties": {
                    "path": {
                        "type": "string",
                        "description": "Path to the file to read"
                    }
                },
                "required": ["path"]
            }
        ),
        Tool(
            name="list_directory",
            description="List files in a directory",
            inputSchema={
                "type": "object",
                "properties": {
                    "path": {
                        "type": "string",
                        "description": "Path to the directory to list"
                    }
                },
                "required": ["path"]
            }
        ),
        Tool(
            name="write_file",
            description="Write content to a file",
            inputSchema={
                "type": "object",
                "properties": {
                    "path": {
                        "type": "string",
                        "description": "Path to the file to write"
                    },
                    "content": {
                        "type": "string",
                        "description": "Content to write"
                    }
                },
                "required": ["path", "content"]
            }
        )
    ]

@server.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
    if name == "read_file":
        path = arguments["path"]
        with open(path, "r") as f:
            content = f.read()
        return [TextContent(type="text", text=content)]
    
    elif name == "list_directory":
        path = arguments["path"]
        entries = os.listdir(path)
        result = "\n".join(entries)
        return [TextContent(type="text", text=result)]
    
    elif name == "write_file":
        path = arguments["path"]
        content = arguments["content"]
        with open(path, "w") as f:
            f.write(content)
        return [TextContent(type="text", text=f"Written to {path}")]
    
    raise ValueError(f"Unknown tool: {name}")

async def main():
    async with stdio_server() as (read_stream, write_stream):
        await server.run(read_stream, write_stream)

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

Connecting from a Client

Once your server is running, MCP-compatible clients can connect to it. For example, in Claude Desktop, you configure MCP servers in the settings:

{
  "mcpServers": {
    "filesystem": {
      "command": "python",
      "args": ["/path/to/your/server.py"]
    }
  }
}

The AI model can then use your tools directly, with the MCP client handling all the communication.

Practical Use Cases

Database Query Tool

An MCP server that lets AI models query your database:

@server.list_tools()
async def list_tools() -> list[Tool]:
    return [
        Tool(
            name="query_database",
            description="Execute a read-only SQL query",
            inputSchema={
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "SQL SELECT query"
                    }
                },
                "required": ["query"]
            }
        )
    ]

@server.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
    if name == "query_database":
        import sqlite3
        conn = sqlite3.connect("app.db")
        cursor = conn.execute(arguments["query"])
        columns = [desc[0] for desc in cursor.description]
        rows = cursor.fetchall()
        conn.close()
        
        results = [dict(zip(columns, row)) for row in rows]
        return [TextContent(type="text", text=json.dumps(results, indent=2))]

API Integration Server

Expose your internal APIs to AI models through MCP:

@server.list_tools()
async def list_tools() -> list[Tool]:
    return [
        Tool(
            name="get_customer",
            description="Get customer details by ID",
            inputSchema={
                "type": "object",
                "properties": {
                    "customer_id": {"type": "string"}
                },
                "required": ["customer_id"]
            }
        ),
        Tool(
            name="create_ticket",
            description="Create a support ticket",
            inputSchema={
                "type": "object",
                "properties": {
                    "customer_id": {"type": "string"},
                    "subject": {"type": "string"},
                    "description": {"type": "string"}
                },
                "required": ["customer_id", "subject", "description"]
            }
        )
    ]

Why MCP Matters

For Developers

  • Build once, use everywhere: An MCP server works with any MCP-compatible client
  • Standardized interface: No more writing custom adapters for each AI provider
  • Composability: Multiple MCP servers can run simultaneously, each providing different capabilities

For Organizations

  • Security: MCP servers run locally or on your infrastructure, keeping data in your control
  • Reusability: Build internal tool servers once and share them across teams
  • Ecosystem: As more tools are built as MCP servers, the value of the ecosystem grows

Current Ecosystem

MCP is still early, but adoption is growing:

  • Claude Desktop supports MCP servers natively
  • Open-source MCP servers exist for popular services like GitHub, Slack, and Google Drive
  • Community servers are being published for databases, file systems, and APIs
  • Agent frameworks are adding MCP client support

Conclusion

The Model Context Protocol represents a meaningful step toward standardizing how AI models interact with the external world. By providing a common protocol for tool communication, MCP reduces the integration burden and makes AI tools more portable and composable.

Building an MCP server is straightforward, and the payoff is significant: any MCP-compatible AI client can use your tools without custom integration work. As the ecosystem grows, MCP servers will become the standard way to expose capabilities to AI models, much as REST APIs became the standard for web services.

#MCP #AI Agents #LLM

Related articles

Let's build something great together

Ready to automate your business processes and save hundreds of hours every month? Let's talk about your project.