AI agents are revolutionising industries by automating complex tasks and enabling efficient workflows. However, the effectiveness of these agents more dependent on data, systems and other agents.
The Model Context Protocol (MCP) is a standardised protocol designed to integrate smooth communication between large language models (LLMs) and services, external systems and tools.
MCP promotes a modular and scalable architecture, enabling the development of sophisticated reusable AI systems capable of performing complex tasks efficiently.
Understanding AI Agents
Before diving into MCP, it's essential to grasp the foundational concepts of AI Agents:
AI Agents: Systems that coordinate one or multiple LLMs alongside various tools to execute a series of tasks cohesively while retaining context in memory.
Workflow: AI agents follow a structured workflow comprising:
- Perception: Data collection.
- Planning: Deciding on a plan based on goals.
- Execution: Taking actions using tools and external systems.
- Monitoring: Handling outcomes and errors.
- Learning: Incorporating feedback for improvement.
A significant challenge with AI agents is the necessity to individually create, integrate, and grant access to each tool and functionality. This often results in bespoke solutions tailored to specific use cases, limiting scalability and flexibility.
Current Challenges in AI Agents
Effective communication between AI agents and external systems faces several challenges,
Inconsistent Message Formats: Different agents may use unique communication protocols, making integration difficult.
Scalability Issues: Tight coupling between agents and tools can lead to bottlenecks, reducing scalability in complex tasks.
Collaboration Barriers: The lack of standardised protocols and the duplication of services lead to inefficiencies and monolithic behaviours.
Why MCP is Crucial in AI
The Model Context Protocol addresses the challenges by introducing standardised communication, modularity, scalability, and enhanced collaboration capabilities.
1. Standardised Communication
MCP is an open protocol that standardises how applications provide context to AI models, particularly large language models (LLMs). Its compared to USB-C serves as a universal standard for connecting devices, MCP offers a unified method to connect AI agents and systems to a different services and tools.
2. Modularity and Scalability
Inspired by microservices architecture, MCP enables AI agents to be modular, scalable, and reusable across different systems. Developers can build specialised agents that perform specific tasks independently, ensuring these agents can operate autonomously and integrate seamlessly into broader workflows.
3. Enhanced Collaboration
MCP defines clear ownership and responsibilities for agents, fostering cross-functional teamwork. This clarity is essential for developing complex AI systems where multiple teams work on different project aspects. MCP ensures consistency and integration across the entire system, allowing each team to focus on their specialized modules or services.
How MCP Works
Its a traditional client-server architecture with added host application as user facing. Here's a basic structure:
|- MCP Host[Chat System or Web application]
|- MCP Client[Remote Client using SSE]
|- MCP Server A[Database]
|- MCP Server B[Filesystem]
|- MCP Server C[External System]
|-MCP Client[Stdio Client in local]
|-MCP Server D[API system]
MCP Architecture
The MCP architecture has the following
MCP Hosts: The user application like Chat system, Agents or web application and Programs like Claude Desktop or integrated development environments (IDEs) that access data through MCP.
MCP Clients: Protocol clients maintaining one-to-one connections with servers.
MCP Servers: Dedicated servers that expose specific capabilities / existing systems / files via MCP.
Core Components of MCP
Resources: Resources represent data that MCP servers make available to clients (AI agents). These can include file contents, database records, API responses, live system data, images, and log files. Each resource is identified by a unique URI and can contain either text or binary data.
Tools: Tools are functions that MCP servers expose, allowing clients to invoke them for performing actions. Ranging from simple computations to complex API interactions, MCP supports the discovery, invocation, and management of these tools.
Prompts: Prompts are predefined templates in MCP that accept dynamic arguments, include context from resources, chain multiple interactions, and guide specific workflows. Servers can define reusable prompt templates and workflows that clients use to interact with LLMs efficiently.
Typical Workflow with MCP
Initialisation: Establishing connections and negotiating protocols and capabilities.
Message Exchange: Facilitating tools, resources, and prompt interactions through standardised MCP messages.
Termination: Graceful shutdown and resource cleanup upon completion.
Example Implementation: Maths MCP (Python)
Let's build an MCP system that provides resource, tools and prompt information in the below 10 steps
Setting Up the Environment
uv init maths-mcp
cd maths-mcp
uv venv
source .venv/bin/activate
uv add "mcp[cli]" httpx
Implementing the Server with Stdio
from mcp.server.fastmcp import FastMCP
from pathlib import Path
mcp = FastMCP("Maths MCP Server")
@mcp.resource(
uri="dir://ubuntu/url/docs",
name="maths_docs",
description="List of available documents"
)
def maths_docs() -> list[str]:
"""List the files in the user's desktop"""
docs = Path.home() / "url/docs"
return [str(f) for f in docs.iterdir()]
@mcp.tool(
name="addition",
description="Add two numbers"
)
async def addition(a: float, b: float) -> float:
"""
Add two numbers
"""
response = a + b
return response
@mcp.tool(
name="subtraction",
description="Subtract two numbers"
)
async def subtraction(a: float, b: float) -> float:
"""
Subtract two numbers
"""
response = a - b
return response
@mcp.prompt(
name="maths_prompt",
description="Prompt for maths use cases"
)
def maths_prompt(message: str) -> str:
prompt = "Enter two numbers to perform an operation"
return prompt
if __name__ == "__main__":
mcp.run()
Explanation
Two tools:
- addition: Provides addition tool
- subtraction: Provides subtraction tool
One resource:
- maths_docs: Provides maths docs url
One prompt:
- maths_prompt: Provides maths prompt
Example client code
Let's explore how a simple MCP client in Python can interact with the MCP server using stdio
from mcp import ClientSession, StdioServerParameters, types
from mcp.client.stdio import stdio_client
# Create server parameters for stdio connection
server_params = StdioServerParameters(
command="python", # Executable
args=["post/stdio_server.py"], # Command line arguments
env=None, # Optional environment variables
)
async def run():
async with stdio_client(server_params) as (read, write):
async with ClientSession(
read, write) as session:
# Initialize the connection
await session.initialize()
# List available prompts
prompts = await session.list_prompts()
print("\n\n\nAvailable prompts:", prompts)
# List available resources
resources = await session.list_resources()
print("\n\n\nAvailable resources:", resources)
# List available tools
tools = await session.list_tools()
print("\n\n\nAvailable tools:", tools)
if __name__ == "__main__":
import asyncio
asyncio.run(run())
Output
>python post/studio_client.py
Available prompts: meta=None nextCursor=None prompts=[Prompt(name='maths_prompt', description='Prompt for maths use cases', arguments=[PromptArgument(name='message', description=None, required=True)])]
Available resources: meta=None nextCursor=None resources=[Resource(uri=AnyUrl('dir://ubuntu/url/docs'), name='maths_docs', description='List of available documents', mimeType='text/plain', size=None, annotations=None)]
Available tools: meta=None nextCursor=None tools=[Tool(name='addition', description='Add two numbers', inputSchema={'properties': {'a': {'title': 'A', 'type': 'number'}, 'b': {'title': 'B', 'type': 'number'}}, 'required': ['a', 'b'], 'title': 'additionArguments', 'type': 'object'}), Tool(name='subtraction', description='Subtract two numbers', inputSchema={'properties': {'a': {'title': 'A', 'type': 'number'}, 'b': {'title': 'B', 'type': 'number'}}, 'required': ['a', 'b'], 'title': 'subtractionArguments', 'type': 'object'})]
Explanation
In this client example:
- Initialisation: The client initialises the connection with the server by ClientSession.
- Listing Tools: It retrieves a list of available tools that the server exposes.
- Listing Resources: It retrieves a list of available resources that the server exposes.
- Listing Prompts: It retrieves a list of available prompts that the server exposes.
This interaction demonstrates how MCP ensures that clients can dynamically discover and utilise the capabilities provided by servers, making AI agents both flexible and powerful.
SSE Server Code
On the same folder create sse_server.py and import the studio server
from starlette.applications import Starlette
from mcp.server.sse import SseServerTransport
from mcp.server import Server
from starlette.requests import Request
from starlette.routing import Mount, Route
import uvicorn
from stdio_server import mcp
def create_starlette_app(mcp_server: Server, *, debug: bool = False) -> Starlette:
"""Create a Starlette application that can server the provied mcp server with SSE."""
sse = SseServerTransport("/messages/")
async def handle_sse(request: Request) -> None:
async with sse.connect_sse(request.scope, request.receive, request._send,
) as (read_stream, write_stream):
await mcp_server.run(read_stream, write_stream, mcp_server.create_initialization_options(),)
return Starlette(
debug=debug,
routes=[
Route("/sse", endpoint=handle_sse),
Mount("/messages/", app=sse.handle_post_message),
],
)
if __name__ == "__main__":
mcp_server = mcp._mcp_server
starlette_app = create_starlette_app(mcp_server, debug=True)
uvicorn.run(starlette_app, host="0.0.0.0", port=8000)
Explanation
In this sse server example:
The stdio_server is imported and using Starlette the endpoints /sse and /messages are exposed. Now run the server over http
Execution
post/sse_server.py
INFO: Started server process [7553]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
So now the MCP server is exposed in port 8000, this can be proxied by Apache or Nginx but in this example lets consider its in same host.
SSE Client Code
from mcp.client.session import ClientSession
from mcp.client.sse import sse_client
import asyncio
async def client_logic():
async with sse_client(url="http://0.0.0.0:8000/sse") as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
# List available tools
tools = await session.list_tools()
print("\n\n\nAvailable tools:", tools)
resources = await session.list_resources()
print("\n\n\nAvailable resources:", resources)
prompts = await session.list_prompts()
print("\n\n\nAvailable prompts:", prompts)
def main():
asyncio.run(client_logic())
if __name__ == "__main__":
main()
Output
>python post/sse_client.py
Available tools: meta=None nextCursor=None tools=[Tool(name='addition', description='Add two numbers', inputSchema={'properties': {'a': {'title': 'A', 'type': 'number'}, 'b': {'title': 'B', 'type': 'number'}}, 'required': ['a', 'b'], 'title': 'additionArguments', 'type': 'object'}), Tool(name='subtraction', description='Subtract two numbers', inputSchema={'properties': {'a': {'title': 'A', 'type': 'number'}, 'b': {'title': 'B', 'type': 'number'}}, 'required': ['a', 'b'], 'title': 'subtractionArguments', 'type': 'object'})]
Available resources: meta=None nextCursor=None resources=[Resource(uri=AnyUrl('dir://ubuntu/url/docs'), name='maths_docs', description='List of available documents', mimeType='text/plain', size=None, annotations=None)]
Available prompts: meta=None nextCursor=None prompts=[Prompt(name='maths_prompt', description='Prompt for maths use cases', arguments=[PromptArgument(name='message', description=None, required=True)])]
Summary
The Model Context Protocol (MCP) represents a possible solution to improve AI integrations, scaling by providing a standardised framework that ensures seamless connections between AI Agents, tools and systems.
MCP enhancing modularity, scalability, and collaboration, MCP is essential for building reusable and efficient AI systems.
References
- MCP Documentation: Dive into the official MCP documentation
- Experiment with MCP Development: Develop your own MCP servers and clients using the TypeScript SDK and Python SDK.
Top comments (0)