Skip to main content

Command Palette

Search for a command to run...

Model Context Protocol

Published
3 min read
Model Context Protocol

What Exactly Is MCP?

Think of Model Context Protocol (MCP) as the “rules + tools” layer that helps you make an LLM behave the way you want — not the other way around.

LLMs are smart, but they don’t know your business logic.
They don’t know your APIs.
They don’t know when to call what.
Left alone, they’ll guess — and sometimes hallucinate.

MCP fixes that.

With MCP, you define:

  • the tools the model is allowed to use

  • the exact inputs/outputs

  • when and how those tools should be used

  • the structure the model must follow

So instead of the LLM wandering around, it becomes a well-behaved agent that follows your workflow.

In simple terms:

MCP is how you “shape” an LLM into doing your tasks predictably — using your APIs, your rules, and your logic.

It turns a general-purpose model into something that works like part of your backend.


FastMCP Example (Weather Agent)

from fastmcp import FastMCP

mcp = FastMCP(
    name="Weather MCP Agent",
    instructions=(
        "Provides a structured multi-day weather forecast when called."
    ),
    stateless_http=True
)
  • instructions guide the LLM

  • stateless_http=True exposes the MCP over HTTP (no session handshake)


🧰 Defining a Tool

@mcp.tool(
    name="get_weather_forecast",
    description="Returns a structured daily weather forecast."
)
async def get_weather_forecast(
    trip_details: TripDocument
) -> WeatherForecastOutput:
    return await fetch_weather_forecast(trip_details)

A good MCP tool has:

  • clear purpose

  • strict input schema

  • strict output schema


🔗 Mounting MCP into FastAPI

mcp_app = mcp.http_app(path="/weather")
app = FastAPI(lifespan=mcp_app.lifespan)
app.mount("/mcp", mcp_app)

Here “mcp” is a FastMCP instance. To make it accessible over HTTP, you create a FastAPI “app” and mount the MCP on a route. This exposes your MCP tools as API endpoints that any client (LLM, service, or frontend) can call.

This gives you:

  • /mcp/weather → MCP tools

Your MCP becomes a production-ready API.


🧪 Testing Your MCP (cURL Command)

Here’s the exact command I used to test the tool:

curl -X POST https://localhost:8080/mcp/weather \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "get_weather_forecast",
      "arguments": {
        "trip_details": {
          "tripId": "test-trip-123",
          "destination": "Paris, France"
        }
      }
    }
  }'

This simulates exactly how an LLM calls your MCP tool.


MCP in a Nutshell

  • MCP = Tools + Rules + Schema → guides the LLM on what it can do and ensures structured outputs.

  • LLM uses MCP tools → gets structured data (JSON) from MCP, then can convert it into natural language for the user.

  • FastAPI mount → Mounting the MCP on FastAPI exposes its tools over HTTP, so any client — frontend, microservice, or even curl — can call it and get structured JSON

  • Think LEGO blocks → modular, reusable, predictable AI behavior.

In Driftaway, combining FastMCP + Pydantic + FastAPI has given me highly reliable agents — far more predictable than relying on prompts alone.