Bygg din egen MCP-server med Python och FastMCP 3.0

Lär dig bygga en MCP-server i Python med FastMCP 3.0. Steg-för-steg-guide med kodexempel som täcker verktyg, resurser, promptmallar och integration med Claude Desktop.

Vad är Model Context Protocol (MCP)?

Om du har jobbat med AI-modeller ett tag vet du hur frustrerande det kan vara att koppla ihop dem med externa system. Varje ny datakälla kräver sin egen integration, och det hela blir snabbt rörigt. Det är precis det problemet som Model Context Protocol (MCP) löser.

MCP är en öppen standard skapad av Anthropic. Den enklaste liknelsen? Tänk USB-C för AI-applikationer – ett standardiserat gränssnitt som fungerar överallt, istället för skräddarsydda kopplingar till varje verktyg och datakälla.

Utan MCP sitter du med ett klassiskt N×M-problem: varje ny datakälla kräver unik integrationskod för varje AI-klient. Med MCP blir det istället N+M – varje verktyg behöver bara en MCP-server, och varje klient behöver bara en MCP-klient. Betydligt smidigare.

Protokollet har dessutom fått ordentlig dragkraft sedan lanseringen. Både OpenAI och Google DeepMind har antagit det, FastMCP driver ungefär 70 % av alla MCP-servrar, och ekosystemet har vuxit till över 200 tillgängliga servrar. Så det här är inte bara ett Anthropic-projekt längre – det är en riktig branschstandard.

Hur MCP-arkitekturen fungerar

Innan vi börjar koda, låt oss snabbt gå igenom hur arkitekturen ser ut. MCP bygger på en klient-server-modell med tre huvudkomponenter:

  • Värdar (Hosts) – AI-applikationer som Claude Desktop, Cursor eller dina egna system där LLM-logiken körs.
  • Klienter (Clients) – Lever inne i värden och upprätthåller 1:1-sessioner med MCP-servrar via JSON-RPC 2.0.
  • Servrar (Servers) – Det du bygger. De exponerar funktionalitet från externa system (databaser, API:er, filsystem) genom tre grundläggande primitiver.

De tre primitiverna

Varje MCP-server exponerar sin funktionalitet genom tre typer av komponenter:

  1. Verktyg (Tools) – Funktioner som AI-modellen kan anropa för att utföra åtgärder. Tänk: skicka e-post, söka i databaser, bearbeta filer.
  2. Resurser (Resources) – Skrivskyddad data som modellen kan läsa, exempelvis konfigurationsfiler eller användarprofiler.
  3. Promptmallar (Prompts) – Fördefinierade mallar som styr hur modellen närmar sig specifika uppgifter.

Den uppdelningen gör det ganska intuitivt att strukturera vad din server ska göra. Men nog med teori – dags att bygga.

Förutsättningar

Innan du sätter igång behöver du ha följande på plats:

  • Python 3.10 eller senare – FastMCP 3.0 stöder 3.10, 3.11, 3.12 och 3.13.
  • uv – En snabb Python-projekthanterare som sköter beroenden och virtuella miljöer. Installera med curl -LsSf https://astral.sh/uv/install.sh | sh.
  • En texteditor – VS Code, Cursor eller vad du föredrar.
  • Claude Desktop (valfritt) – Om du vill testa din server med en riktig AI-klient.

Steg 1: Skapa projektet och installera beroenden

Okej, vi kör. Börja med att skapa ett nytt Python-projekt med uv:

uv init mcp-demo
cd mcp-demo
uv venv
source .venv/bin/activate
uv add "fastmcp"
uv add "mcp[cli]"

uv add "fastmcp" installerar FastMCP 3.0 – den stabila versionen som släpptes 18 februari 2026. Paketet mcp[cli] ger dig tillgång till MCP Inspector, ett felsökningsverktyg vi kommer använda senare.

Skapa sedan din serverfil:

touch server.py

Steg 2: Skapa MCP-serverinstansen

Varje FastMCP-app börjar med en instans av klassen FastMCP. Öppna server.py och lägg till:

from fastmcp import FastMCP

# Skapa serverinstansen med ett beskrivande namn
mcp = FastMCP(name="Min första MCP-server")

Två rader kod och du har en giltig MCP-server. Den gör ingenting ännu, men servernamnet visas i MCP-klienter så att användare kan identifiera den.

Steg 3: Lägg till verktyg (Tools)

Nu till den roliga delen. Verktyg är funktioner som en LLM kan anropa, och FastMCP gör det nästan löjligt enkelt att registrera dem. Dekoratorn @mcp.tool tar hand om allt – funktionens namn blir verktygets namn och docstringen blir beskrivningen som AI-modellen ser.

Ett enkelt beräkningsverktyg

@mcp.tool
def addera(a: int, b: int) -> int:
    """Adderar två heltal och returnerar summan."""
    return a + b

@mcp.tool
def multiplicera(a: float, b: float) -> float:
    """Multiplicerar två tal och returnerar produkten."""
    return a * b

Ett verktyg som hämtar data från ett API

Verktyg kan vara asynkrona och anropa externa tjänster. Här är ett väderverktyg som använder Open-Meteo (gratis, inget API-nyckel krävs):

import httpx

@mcp.tool
async def hamta_vader(stad: str) -> dict:
    """Hämtar aktuell väderdata för en given stad via Open-Meteo API."""
    geocode_url = f"https://geocoding-api.open-meteo.com/v1/search?name={stad}&count=1"
    async with httpx.AsyncClient() as client:
        geo = await client.get(geocode_url)
        geo_data = geo.json()

        if not geo_data.get("results"):
            return {"error": f"Kunde inte hitta staden {stad}"}

        lat = geo_data["results"][0]["latitude"]
        lon = geo_data["results"][0]["longitude"]

        weather_url = (
            f"https://api.open-meteo.com/v1/forecast?"
            f"latitude={lat}&longitude={lon}&current_weather=true"
        )
        weather = await client.get(weather_url)
        return weather.json()["current_weather"]

FastMCP upptäcker automatiskt att funktionen är asynkron. Typannotationerna (str, dict) konverteras till JSON Schema åt dig, så AI-modellen vet exakt vilken indata som förväntas. Ganska smidigt.

Steg 4: Lägg till resurser (Resources)

Resurser ger skrivskyddad åtkomst till data – tänk konfiguration, hjälptexter eller annat som modellen kan behöva läsa men inte ändra. De definieras med @mcp.resource och en unik URI:

@mcp.resource("resource://config")
def hamta_konfiguration() -> dict:
    """Returnerar applikationens konfiguration."""
    return {
        "version": "1.0.0",
        "server_namn": "Min MCP-server",
        "funktioner": ["beräkningar", "väderdata"],
        "max_forfragan_per_minut": 60
    }

@mcp.resource("resource://hjalp")
def hamta_hjalp() -> str:
    """Returnerar en hjälptext som beskriver serverns funktionalitet."""
    return (
        "Denna MCP-server erbjuder beräkningsverktyg (addera, multiplicera) "
        "och väderdata (hamta_vader). Använd verktygen genom att ange "
        "rätt parametrar."
    )

Resurser anropas bara när de begärs, vilket möjliggör lat laddning. URI-schemat resource:// är en konvention, men du kan egentligen använda valfria URI:er som passar din domän.

Steg 5: Lägg till promptmallar (Prompts)

Promptmallar styr hur AI-modellen närmar sig specifika uppgifter – något som är väldigt användbart om du vill ha konsekvent beteende:

@mcp.prompt
def analysera_data(data_beskrivning: str) -> str:
    """Skapar en prompt som ber AI:n analysera given data."""
    return (
        f"Analysera följande data noggrant: {data_beskrivning}\n\n"
        "Ge en sammanfattning som inkluderar:\n"
        "1. Huvudsakliga trender\n"
        "2. Avvikelser eller anomalier\n"
        "3. Rekommenderade åtgärder"
    )

Steg 6: Starta och testa servern

Lägg till startpunkten längst ner i server.py:

if __name__ == "__main__":
    mcp.run()

Den kompletta serverfilen

Så här ser hela server.py ut när allt är på plats:

from fastmcp import FastMCP
import httpx

mcp = FastMCP(name="Min första MCP-server")

# --- Verktyg ---

@mcp.tool
def addera(a: int, b: int) -> int:
    """Adderar två heltal och returnerar summan."""
    return a + b

@mcp.tool
def multiplicera(a: float, b: float) -> float:
    """Multiplicerar två tal och returnerar produkten."""
    return a * b

@mcp.tool
async def hamta_vader(stad: str) -> dict:
    """Hämtar aktuell väderdata för en given stad via Open-Meteo API."""
    geocode_url = f"https://geocoding-api.open-meteo.com/v1/search?name={stad}&count=1"
    async with httpx.AsyncClient() as client:
        geo = await client.get(geocode_url)
        geo_data = geo.json()

        if not geo_data.get("results"):
            return {"error": f"Kunde inte hitta staden {stad}"}

        lat = geo_data["results"][0]["latitude"]
        lon = geo_data["results"][0]["longitude"]

        weather_url = (
            f"https://api.open-meteo.com/v1/forecast?"
            f"latitude={lat}&longitude={lon}&current_weather=true"
        )
        weather = await client.get(weather_url)
        return weather.json()["current_weather"]

# --- Resurser ---

@mcp.resource("resource://config")
def hamta_konfiguration() -> dict:
    """Returnerar applikationens konfiguration."""
    return {
        "version": "1.0.0",
        "server_namn": "Min MCP-server",
        "funktioner": ["beräkningar", "väderdata"],
        "max_forfragan_per_minut": 60
    }

@mcp.resource("resource://hjalp")
def hamta_hjalp() -> str:
    """Returnerar en hjälptext som beskriver serverns funktionalitet."""
    return (
        "Denna MCP-server erbjuder beräkningsverktyg (addera, multiplicera) "
        "och väderdata (hamta_vader). Använd verktygen genom att ange "
        "rätt parametrar."
    )

# --- Promptmallar ---

@mcp.prompt
def analysera_data(data_beskrivning: str) -> str:
    """Skapar en prompt som ber AI:n analysera given data."""
    return (
        f"Analysera följande data noggrant: {data_beskrivning}\n\n"
        "Ge en sammanfattning som inkluderar:\n"
        "1. Huvudsakliga trender\n"
        "2. Avvikelser eller anomalier\n"
        "3. Rekommenderade åtgärder"
    )

if __name__ == "__main__":
    mcp.run()

Testa med MCP Inspector

MCP Inspector är ett interaktivt felsökningsverktyg – och ärligt talat, det är ganska ovärderligt under utveckling. Starta det med:

fastmcp dev server.py

Inspector öppnas i din webbläsare och visar alla registrerade verktyg, resurser och promptmallar. Du kan anropa verktyg med testdata och se resultaten direkt. Jag rekommenderar att du kör igenom varje verktyg manuellt här innan du kopplar in en riktig AI-klient.

Testa via kommandoraden

FastMCP 3.0 introducerade CLI-kommandon som gör testning ännu smidigare:

# Lista alla verktyg på servern
fastmcp list server.py

# Anropa ett specifikt verktyg
fastmcp call server.py addera --a 5 --b 3

Steg 7: Integrera med Claude Desktop

Dags för den riktigt tillfredsställande delen – att se din server fungera med en riktig AI-klient. För att koppla ihop din MCP-server med Claude Desktop behöver du redigera konfigurationsfilen. På macOS hittar du den här:

~/Library/Application Support/Claude/claude_desktop_config.json

Lägg till din server i mcpServers-objektet:

{
  "mcpServers": {
    "min-server": {
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "/absolut/sökväg/till/mcp-demo",
        "server.py"
      ]
    }
  }
}

Starta om Claude Desktop efter att du sparat. Din server bör nu dyka upp som en tillgänglig integration, och Claude kan använda dina verktyg direkt i konversationen.

Snabbinstallation med CLI

Vill du slippa redigera JSON-filer manuellt? FastMCP 3.0 har ett enklare alternativ:

# Registrera servern automatiskt med Claude Desktop
fastmcp install server.py --name "min-server"

Kommandot uppdaterar konfigurationsfilen automatiskt. Klart.

Nyheter i FastMCP 3.0

FastMCP 3.0 (stabil sedan 18 februari 2026) innebär en rejäl arkitekturell förändring jämfört med version 2. Här är det viktigaste du behöver veta.

Providers – flexibel komponentladdning

I FastMCP 2 kom alla komponenter från Python-dekoratorer. Version 3 introducerar Providers – ett abstrakt lager för var komponenter hämtas. Du kan nu ladda verktyg från:

  • FileSystemProvider – Upptäcker dekorerade funktioner från en katalogstruktur, med valfri hot-reload.
  • OpenAPIProvider – Genererar verktyg automatiskt från en OpenAPI-specifikation. (Otroligt praktiskt om du redan har dokumenterade REST-API:er.)
  • ProxyProvider – Vidarebefordrar anrop till en fjärr-MCP-server.

Transforms – middleware för komponenter

Transforms fungerar som middleware i komponentpipelinen. Du kan filtrera, byta namn på eller omstrukturera komponenter utan att röra den underliggande koden:

from fastmcp.transforms import rename_tool

# Byt namn på verktyget "addera" till "sum"
transform = rename_tool("addera", "sum")
mcp.add_transform(transform)

OpenTelemetry-instrumentering

FastMCP 3.0 har inbyggd OpenTelemetry-support. Varje verktygsanrop, resursläsning och promptrendering spåras automatiskt – lägg till din OTEL-konfiguration och du får full insyn i latens och prestanda.

Hot Reload under utveckling

fastmcp dev server.py övervakar nu dina filer och laddar om servern automatiskt vid ändringar. Inga fler manuella omstarter.

Funktioner förblir funktioner

En detalj som gör stor skillnad i praktiken: i FastMCP 2 omvandlade dekoratorer dina funktioner till speciella objekt. I version 3 förblir de vanliga Python-funktioner – du kan importera dem, anropa dem direkt och skriva enhetstester precis som vanligt.

Säkerhet och bästa praxis

Att exponera funktionalitet via MCP kräver en del eftertanke kring säkerhet. Här är de viktigaste punkterna:

  • Hantera hemligheter via miljövariabler – Lagra aldrig API-nycklar direkt i konfigurationsfiler. Använd os.environ i servern och ställ in miljövariabler separat.
  • Begränsa servrars scope – Använd flaggan --scope project vid registrering för att begränsa åtkomst till det aktuella projektet.
  • Validera indata – FastMCP genererar JSON Schema från typannotationer, men validera känslig indata manuellt också. Speciellt vid databasoperationer.
  • Använd HTTPS för fjärrservrar – Om din MCP-server är nåbar via nätverk, se till att den körs bakom HTTPS.

Vanliga frågor

Vilka AI-modeller stöder MCP?

MCP är modell-agnostiskt. Det fungerar med Claude, GPT-4, DeepSeek, Gemini och alla modeller som implementerar MCP-klientprotokollet. Anthropic, OpenAI och Google DeepMind har alla antagit standarden.

Vad är skillnaden mellan MCP och vanlig funktionsanrop?

Funktionsanrop (function calling) är specifikt för varje API-leverantör och kräver att du definierar verktyg i varje API-begäran. MCP standardiserar detta genom en separat server som exponerar verktyg, resurser och promptmallar – samma server fungerar med alla kompatibla AI-klienter utan anpassning.

Behöver jag FastMCP eller kan jag använda SDK:n direkt?

Du kan använda MCP Python SDK direkt, men FastMCP förenklar utvecklingen avsevärt. Det sköter verktygsregistrering, typkonvertering och serverlivscykel automatiskt. Ungefär 70 % av alla MCP-servrar byggs med FastMCP, och det ursprungliga FastMCP 1.0 integrerades faktiskt i den officiella SDK:n.

Hur skiljer sig MCP från RAG?

RAG fokuserar på att berika AI-svar med relevanta dokument via vektorsökning. MCP är bredare – det möjliggör verktygsanvändning, dataåtkomst och prompthantering, inte bara dokumenthämtning. Du kan exponera en RAG-pipeline som ett MCP-verktyg, men MCP täcker fler användningsfall.

Kan jag köra flera MCP-servrar samtidigt?

Absolut. En MCP-värd (som Claude Desktop) kan ansluta till flera servrar parallellt – varje server hanteras av en separat klientinstans. Så du kan ha en server för databaser, en för API:er och en för filsystem, alla tillgängliga i samma AI-session.

Om Författaren Editorial Team

Our team of expert writers and editors.