Skip to main content

📋 Table of Contents

Chapter 1: Model Context Protocol (MCP) Introduction

As LLM applications scale, developers face a major integration problem: every database, API, and tool requires a custom, bespoke integration wrapper. The Model Context Protocol (MCP), created by Anthropic, is an open standard that acts like a universal “USB port” connecting AI agents to external data sources and tools.

1. What Problem Does MCP Solve?

Before MCP, integration was fragmented:
  • The Custom Wrapper Mess: If you had 5 developer IDEs and 5 databases, you had to write 25 separate integration adapters.
  • Lack of Standardization: There was no standard format defining how a database should advertise its tables, or how a web search API should register its parameters with an LLM.
MCP standardizes this interface. By defining a common protocol, any MCP-compatible Host can connect to any MCP Server instantly:

2. Architecture & Core Components

The Model Context Protocol divides responsibility among three distinct layers:

2.1 The Host

The orchestration application that communicates with the LLM and manages security permissions (e.g., Claude Desktop, Antigravity IDE, or your custom Python agent). The Host instantiates the clients.

2.2 The Client

A protocol component running inside the Host. It initiates connection sessions to MCP servers and translates tool schemas for the LLM.

2.3 The Server

A lightweight background process that exposes resources, prompts, and tools to the client.
  • Resources: Read-only data sources (like local files, database records, or API responses).
  • Prompts: Reusable prompt templates (like code review formats).
  • Tools: Executable actions (like creating a GitHub issue, writing a file, or running a SQL query).

3. Connecting to an Existing MCP Server

MCP servers communicate with clients using transports. The most common transport is Stdio, where the host launches the server as a subprocess and communicates via standard input (stdin) and standard output (stdout).

Step 1: Install Python MCP SDK

To build MCP clients and servers, install the official SDK:

Step 2: Configure Client Connection

To query an existing server (like the official GitHub MCP server), we initialize a stdio_client connection by launching the server process:

Step 3: Retrieve and Execute Tools

Once connected, the client session queries the server to list its available tools and requests execution:

4. Combined Client Code Project

Below is a complete, runnable script illustrating how to connect to the GitHub MCP server to fetch repository details:

5. Practice Exercises

Practice 1: Tool Parameters Audit

Explain why the client passes arguments as a dictionary (e.g. {"username": "octocat"}) during session.call_tool(), and how the server knows what parameters to expect.
  • Schema Validation: During the handshake, session.list_tools() returns a list of tool objects, each containing an inputSchema (defined in JSON Schema format).
  • API Contract: The server advertises exactly what keys and data types it expects (e.g., username must be a string). The client uses a standard dictionary to structure these arguments, allowing the server to validate them before executing the API request.
Back to Top

Chapter 2: Creating a Custom MCP Server

While prebuilt servers (like GitHub or PostgreSQL) are highly useful, production systems often require exposing internal company databases or custom computation engines. In this page, we build a custom FastMCP Math Server in Python and consume its tools in a separate agentic client application.

1. Defining the Custom Server using FastMCP

To build MCP servers easily, the SDK provides a high-level framework called FastMCP. FastMCP handles the JSON-RPC message serialization and transport setup automatically under the hood.

Step 1: Install FastMCP Dependency

Run in your terminal:

Step 2: Write the Server Script (mcp_server.py)

We initialize a FastMCP instance and register tools using the @mcp.tool() decorator:

2. Consuming Custom Server Tools in an Agentic Client

Now, we build a client application that:
  1. Spawns our mcp_server.py script as a subprocess stdio transport connection.
  2. Queries the server’s available tools.
  3. Binds those tools to a Chat Model so the LLM can invoke them.

Step 1: Initialize the Stdio Subprocess Param

We configure parameters to launch our server script:

Step 2: Bind MCP Tools to ChatModel

We fetch the tool definitions from the server, format them for LangChain, and bind them:

3. Client Implementation Script (mcp_client.py)

Here is the complete, self-contained client script that connects to our server subprocess, binds the exposed math tools to Gemini, and executes a calculation query:

4. Practice Exercises

Practice 1: Adding a Division Tool

Modify the custom server script mcp_server.py to add a new division tool called divide_numbers(a: float, b: float) -> float. Define its docstring indicating that it divides a by b, and returns the result.
Add the following decorator and function to the server script mcp_server.py: