Introduction to Agentic AI

Model Context Protocol (MCP)

Model Context Protocol why MCP

Model Context Protocol MCP

  • 2024.11 Anthropic 發佈之開放標準
  • 讓LLM可以整合external tools, systems, and data sources

Model Context Protocol component

  • MCP Client 
    AI 助理。當判斷需要外部協助時,它會作為 MCP 用戶端運行。
  • MCP Server
    可自行建置,或使用現有的軟體。
    託管特定的工具或資源(如搜尋文件、存取 API、讀取文件、執行自訂提示的功能)。
  • MCP Protocol
    MCP 定義Client端如何向伺服器要求資訊或操作,以及伺服器如何回應。可確保相容性和安全性。

Model Context Protocol mcp server

from fastmcp import FastMCP
# Initialize the server with a name
mcp = FastMCP("my-first-server")
# Define a tool using the @mcp.tool decorator
@mcp.tool
def get_weather(city: str) -> dict:
    """Get the current weather for a city."""
    # In production, you'd call a real weather API
    # For now, we'll return mock data
    weather_data = {
        "new york": {"temp": 72, "condition": "sunny"},
        "london": {"temp": 59, "condition": "cloudy"},
        "tokyo": {"temp": 68, "condition": "rainy"},
    }
    
    city_lower = city.lower()
    if city_lower in weather_data:
        return {"city": city, **weather_data[city_lower]}
    else:
        return {"city": city, "temp": 70, "condition": "unknown"}
# Run the server
if __name__ == "__main__":
    mcp.run(transport="stdio")
pip install fastmcp

my_server.py

Model Context Protocol mcp server

  • FastMCP("my-first-server") creates your server with a name

  • @mcp.tool is the decorator that turns any function into an MCP tool

  • The docstring becomes the tool’s description (LLMs use this to understand when to call it)

  • Type hints (city: str, -> dict) tell MCP the expected inputs and outputs

  • transport="stdio" means the server communicates via standard input/output (perfect for local testing)

Model Context Protocol mcp client

import asyncio
from fastmcp import Client

async def main():
    # Point the client at your server file
    client = Client("my_server.py")
    
    # Connect to the server
    async with client:
        # List available tools
        tools = await client.list_tools()
        print("Available tools:")
        for tool in tools:
            print(f"  - {tool.name}: {tool.description}")
        
        print("\n" + "="*50 + "\n")
        
        # Call the weather tool
        result = await client.call_tool(
            "get_weather", 
            {"city": "Tokyo"}
        )
        print(f"Weather result: {result}")

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

test_client.py

Model Context Protocol mcp server

  • Client("my_server.py") tells the client which server to connect to

  • async with client: handles the connection lifecycle automatically

  • list_tools() discovers what tools are available (this is MCP's dynamic discovery)

  • call_tool("get_weather", {"city": "Tokyo"}) invokes the tool with parameters

Model Context Protocol more tools

from fastmcp import FastMCP
from datetime import datetime

mcp = FastMCP("my-first-server")

@mcp.tool
def get_weather(city: str) -> dict:
    """Get the current weather for a city."""
    weather_data = {
        "new york": {"temp": 72, "condition": "sunny"},
        "london": {"temp": 59, "condition": "cloudy"},
        "tokyo": {"temp": 68, "condition": "rainy"},
    }
    city_lower = city.lower()
    if city_lower in weather_data:
        return {"city": city, **weather_data[city_lower]}
    return {"city": city, "temp": 70, "condition": "unknown"}

@mcp.tool
def get_time(timezone: str = "UTC") -> str:
    """Get the current time in a specified timezone."""
    # Simplified - in production use pytz or zoneinfo
    return f"Current time ({timezone}): {datetime.now().strftime('%H:%M:%S')}"

@mcp.tool
def calculate(expression: str) -> dict:
    """Safely evaluate a mathematical expression."""
    try:
        # Only allow safe math operations
        allowed_chars = set("0123456789+-*/.() ")
        if not all(c in allowed_chars for c in expression):
            return {"error": "Invalid characters in expression"}
        
        result = eval(expression)  # Safe because we validated input
        return {"expression": expression, "result": result}
    except Exception as e:
        return {"error": str(e)}
if __name__ == "__main__":
    mcp.run(transport="stdio")

my_server.py

Model Context Protocol production

# Run the server
if __name__ == "__main__":
    mcp.run(transport="http", host="0.0.0.0", port=8000)
# Run the server
if __name__ == "__main__":
    mcp.run(transport="stdio")

my_server.py

my_server.py

測試環境

正式環境

Lesson: MCP

By Leuo-Hong Wang

Lesson: MCP

  • 24