AI Agent Workshop
Mastering MCP
Bygg, utvid og deploy intelligente agenter med Model Context Protocol
// Arkitektur
MCP gir agenter tilgang til den virkelige verden gjennom standardisert verktøyoppdagelse
$ Hurtigstart
Sett opp utviklingsmiljøet ditt på under 5 minutter
Installer uv
uv er en rask Python-pakkehåndterer som gir deg Python og avhengigheter i ett verktøy.
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" Opprett prosjekt
Lag et nytt Python-prosjekt og installer FastMCP med avhengigheter:
mkdir weather-mcp && cd weather-mcp
uv init
uv add fastmcp httpx python-dotenv Konfigurer API-nøkkel
Opprett en .env fil i prosjektmappen:
OPENWEATHER_API_KEY=din-api-nøkkel-her Hvor får du API-nøkkel?
Registrer en gratis konto på openweathermap.org/api og generer en API-nøkkel under "Current Weather Data" (gratis tier).
Klar til å kode!
Miljøet er klart. Neste steg: bygg din første MCP-server med FastMCP.
# Værtjeneste med FastMCP
En komplett MCP-server for vær — klar på under 50 linjer Python
Opprett
weather_server.py
import os
import httpx
from dotenv import load_dotenv
from fastmcp import FastMCP
load_dotenv()
mcp = FastMCP("Værtjeneste")
API_KEY = os.environ["OPENWEATHER_API_KEY"]
BASE_URL = "https://api.openweathermap.org/data/2.5"
@mcp.tool()
async def get_weather(city: str) -> str:
"""Hent gjeldende vær for en by.
Args:
city: Navnet på byen, f.eks. 'Oslo', 'Bergen', 'Tromsø'
"""
async with httpx.AsyncClient() as client:
resp = await client.get(
f"{BASE_URL}/weather",
params={
"q": city,
"appid": API_KEY,
"units": "metric",
"lang": "no",
},
)
resp.raise_for_status()
data = resp.json()
return (
f"Vær i {data['name']}:\n"
f" Temperatur: {data['main']['temp']}°C "
f"(føles som {data['main']['feels_like']}°C)\n"
f" Beskrivelse: {data['weather'][0]['description']}\n"
f" Fuktighet: {data['main']['humidity']}%\n"
f" Vind: {data['wind']['speed']} m/s"
)
@mcp.tool()
async def get_forecast(city: str, hours: int = 24) -> str:
"""Hent værvarsel for en by.
Args:
city: Navnet på byen
hours: Timer fremover (3-120, steg på 3)
"""
async with httpx.AsyncClient() as client:
resp = await client.get(
f"{BASE_URL}/forecast",
params={
"q": city,
"appid": API_KEY,
"units": "metric",
"lang": "no",
},
)
resp.raise_for_status()
data = resp.json()
entries = data["list"][: max(1, hours // 3)]
lines = [f"Værvarsel for {data['city']['name']}:\n"]
for e in entries:
lines.append(
f" {e['dt_txt']} {e['main']['temp']:+.0f}°C "
f"{e['weather'][0]['description']}"
)
return "\n".join(lines) Kjør og test
# Start MCP Inspector (åpner nettleser med testgrensesnitt)
uv run fastmcp dev weather_server.py
# Eller installer direkte i Claude Desktop
uv run fastmcp install weather_server.py // MCP Inspector
- 1. Kjør
fastmcp dev - 2. Åpne nettleseren på adressen som vises
- 3. Klikk "List Tools" for å se verktøyene
- 4. Test
get_weathermed en by
// Claude Desktop
- 1. Kjør
fastmcp install - 2. Start Claude Desktop på nytt
- 3. Se etter hammer-ikonet i chat
- 4. Spør: "Hva er været i Oslo?"
Hva er FastMCP?
FastMCP er et Python-rammeverk
som gjør det enkelt å bygge MCP-servere. Med dekoratorer som
@mcp.tool(),
@mcp.resource() og
@mcp.prompt()
kan du eksponere Python-funksjoner som MCP-verktøy med minimal kode.
Når MCP Inspector viser verktøyene og du kan hente værdata, er du klar for oppgavene!
> Oppgaver
To hands-on oppgaver som bygger videre på værserveren (~30 min hver)
Utvid weather_server.py
med smarte verktøy som bruker værdata til noe nyttig. Du lærer å bruke
@mcp.tool(),
@mcp.resource() og
@mcp.prompt().
A Legg til klesanbefaling
Lag et verktøy suggest_clothing
som henter været for en by og anbefaler klær basert på temperatur, vind og nedbør.
@mcp.tool()
async def suggest_clothing(city: str) -> str:
"""Anbefal klær basert på gjeldende vær i en by.
Args:
city: Navnet på byen
"""
# 1. Hent værdata (gjenbruk logikk fra get_weather)
async with httpx.AsyncClient() as client:
resp = await client.get(
f"{BASE_URL}/weather",
params={
"q": city,
"appid": API_KEY,
"units": "metric",
"lang": "no",
},
)
resp.raise_for_status()
data = resp.json()
temp = data["main"]["temp"]
wind = data["wind"]["speed"]
description = data["weather"][0]["description"]
# 2. Bygg anbefalinger basert på forholdene
clothes = []
if temp < 0:
clothes.extend(["Vinterjakke", "Lue", "Hansker", "Skjerf"])
elif temp < 10:
clothes.extend(["Varm jakke", "Genser", "Lange bukser"])
elif temp < 20:
clothes.extend(["Lett jakke", "Langermet skjorte"])
else:
clothes.extend(["T-skjorte", "Shorts eller lett bukse"])
if wind > 10:
clothes.append("Vindtett ytterlag")
if "regn" in description or "rain" in description:
clothes.extend(["Regntett jakke", "Vanntette sko"])
return (
f"Klesanbefaling for {data['name']} "
f"({temp:.0f}°C, {description}):\n\n"
+ "\n".join(f" - {item}" for item in clothes)
) B Legg til bysammenligning
Lag et verktøy compare_weather
som sammenligner været i to byer side om side.
@mcp.tool()
async def compare_weather(city_a: str, city_b: str) -> str:
"""Sammenlign været mellom to byer.
Args:
city_a: Første by
city_b: Andre by
"""
# Din implementasjon her!
# Tips:
# - Hent værdata for begge byer (bruk httpx)
# - Sammenlign temperatur, vind, fuktighet
# - Returner en formatert sammenligning
... C Legg til en ressurs
MCP-ressurser gir AI-modellen tilgang til data den kan referere til. Legg til en liste over populære norske byer:
@mcp.resource("weather://cities")
def get_cities() -> str:
"""Liste over støttede norske byer."""
cities = [
"Oslo", "Bergen", "Trondheim", "Stavanger",
"Tromsø", "Kristiansand", "Drammen", "Bodø",
"Fredrikstad", "Ålesund",
]
return "\n".join(cities) D Legg til en prompt-mal
MCP-prompts er maler som AI-klienten kan bruke. Lag en "daglig oppdatering"-prompt:
@mcp.prompt()
def daily_briefing(city: str) -> str:
"""Generer en morgenrapport for været."""
return (
f"Gi meg en kort og hyggelig morgenrapport for {city}. "
f"Bruk get_weather og get_forecast for å hente data. "
f"Inkluder: gjeldende vær, varsel for resten av dagen, "
f"og et forslag til klær (bruk suggest_clothing). "
f"Skriv på norsk og hold det kort."
) Test alt
# Start MCP Inspector
uv run fastmcp dev weather_server.py
# Sjekk at alle 4 verktøy vises under "Tools"
# Sjekk at ressursen vises under "Resources"
# Sjekk at prompten vises under "Prompts"
# Test hvert verktøy med ulike byer Når alle verktøy, ressursen og prompten fungerer i Inspector, er oppgave 1 fullført!
Bonus: Installer i Claude Desktop og spør "Bruk daily_briefing for Oslo"
Bygg en ny MCP-server fra bunnen av! Turplanleggeren skal hjelpe brukere med å planlegge turer ved å kombinere stedsinformasjon med værdata.
Tips
Bruk gjerne Claude, Copilot eller lignende verktøy til å hjelpe deg med implementasjonen. Del opp i små steg og test underveis!
A Opprett ny server
Lag en ny fil trip_planner.py
i samme prosjekt:
import os
import httpx
from dotenv import load_dotenv
from fastmcp import FastMCP
load_dotenv()
mcp = FastMCP("Turplanlegger")
API_KEY = os.environ["OPENWEATHER_API_KEY"]
# Enkel database over norske reisemål
DESTINATIONS = {
"Oslo": {
"type": "storby",
"highlights": ["Operaen", "Vigelandsparken", "Munchmuseet"],
"activities": ["museum", "shopping", "mat", "arkitektur"],
},
"Bergen": {
"type": "kystby",
"highlights": ["Bryggen", "Fløibanen", "Fisketorget"],
"activities": ["fjordcruise", "vandring", "mat", "historie"],
},
"Lofoten": {
"type": "natur",
"highlights": ["Reine", "Haukland strand", "Trollfjorden"],
"activities": ["vandring", "fiske", "kajakk", "nordlys"],
},
"Tromsø": {
"type": "nordnorsk",
"highlights": ["Ishavskatedralen", "Fjellheisen", "Polaria"],
"activities": ["nordlys", "hundekjøring", "hvalsafari", "vandring"],
},
"Trondheim": {
"type": "historisk",
"highlights": ["Nidarosdomen", "Bakklandet", "Festung Kristiansten"],
"activities": ["historie", "sykkel", "mat", "kultur"],
},
} B Implementer reisemål-anbefaling
Lag et verktøy som anbefaler reisemål basert på brukerens interesser:
@mcp.tool()
async def suggest_destination(interests: list[str]) -> str:
"""Anbefal et norsk reisemål basert på interesser.
Args:
interests: Liste med interesser, f.eks. ['vandring', 'mat', 'historie']
"""
# Din implementasjon her!
# Tips:
# - Gå gjennom DESTINATIONS
# - Tell treff på aktiviteter vs. interesser
# - Hent været for de beste forslagene
# - Returner en rangert liste med begrunnelse
... C Lag en pakkeliste-generator
Lag et verktøy som genererer en pakkeliste basert på reisemål, varighet og værvarsel:
@mcp.tool()
async def packing_list(destination: str, days: int = 3) -> str:
"""Generer en pakkeliste basert på reisemål og værvarsel.
Args:
destination: Reisemål (by eller sted)
days: Antall dager (1-14)
"""
# Din implementasjon her!
# Tips:
# - Hent værvarsel for destinasjonen
# - Sjekk temp-spenn, nedbør, vind
# - Baseklær + vær-spesifikke ting + aktivitetsutstyr
# - Returner en ryddig, kategorisert liste
... D Lag en dagsplan
Lag et verktøy som planlegger en dag på et reisemål:
@mcp.tool()
async def day_plan(destination: str, interests: list[str]) -> str:
"""Lag en dagsplan for et reisemål.
Args:
destination: Reisemål
interests: Hva brukeren er interessert i
"""
# Din implementasjon her!
# Tips:
# - Bruk DESTINATIONS for å finne highlights
# - Hent været for å tilpasse planen
# - Lag en tidsplan (morgen, formiddag, lunsj, ettermiddag, kveld)
# - Gi konkrete forslag basert på interesser og vær
... E Legg til ressurs og prompt
Fullfør serveren med en ressurs og en prompt:
@mcp.resource("trips://destinations")
def list_destinations() -> str:
"""Oversikt over tilgjengelige reisemål."""
# Returner en formatert liste over DESTINATIONS
# med type og aktiviteter for hvert sted
...
@mcp.prompt()
def plan_trip(destination: str, days: int) -> str:
"""Planlegg en komplett tur."""
return (
f"Hjelp meg å planlegge en {days}-dagers tur til {destination}. "
f"Bruk suggest_destination for å bekrefte valget, "
f"packing_list for pakkeliste, og day_plan for "
f"hver dag. Presenter alt ryddig på norsk."
) Test serveren
# Test turplanleggeren
uv run fastmcp dev trip_planner.py
# Test i Inspector:
# - suggest_destination med interests=["vandring", "natur"]
# - packing_list med destination="Bergen", days=3
# - day_plan med destination="Oslo", interests=["mat", "kultur"] Når alle verktøy fungerer og gir fornuftige svar, er oppgave 2 fullført!
Bonus: Installer begge servere i Claude Desktop!
uv run fastmcp install weather_server.py
uv run fastmcp install trip_planner.py
# Spør Claude: "Planlegg en 3-dagers tur til Bergen.
# Sjekk været og lag en pakkeliste." {} Teknisk Referanse
FastMCP-dekoratorer, MCP-konsepter og nyttige kommandoer
// FastMCP Dekoratorer
| Dekorator | Beskrivelse |
|---|---|
@mcp.tool() | Eksponer en funksjon som MCP-verktøy |
@mcp.resource(uri) | Eksponer data som en lesbar ressurs |
@mcp.prompt() | Definer en gjenbrukbar prompt-mal |
// MCP Konsepter
| Konsept | Forklaring |
|---|---|
| Tools | Funksjoner AI-en kan kalle (handlinger) |
| Resources | Data AI-en kan lese (kontekst) |
| Prompts | Maler for vanlige oppgaver (arbeidsflyter) |
// Nyttige kommandoer
Utvikling og testing
# Start MCP Inspector
uv run fastmcp dev server.py
# Kjør server direkte
uv run python server.py
# Installer i Claude Desktop
uv run fastmcp install server.py
# Installer med navn
uv run fastmcp install server.py \
--name "Min Server" Prosjektoppsett
# Nytt prosjekt med uv
uv init && uv add fastmcp httpx
# Claude Desktop config (macOS)
cat ~/Library/Application\ Support/\
Claude/claude_desktop_config.json
# Claude Desktop config (Windows)
cat %APPDATA%\Claude\
claude_desktop_config.json @ Ta kontakt
Spørsmål om workshopen eller ønsker en gjennomkjøring for teamet ditt? Send oss en melding.
Om workshopen
- Hands-on med MCP, FastMCP og AI-agenter
- Ettermiddag/kveld 2-3 timer
- Hos dere, hos oss eller remote
- Tilpasses nivå og behov
E-post
Lokasjon
Bergen, Norge
Svartid: Vi svarer normalt innen 24 timer på virkedager.