
Du kan bygge en MCP-server, som Claude faktisk kalder, på omkring 15 minutter. Vi har målt tiden på Node 20 og Python 3.11: et fungerende add-værktøj, der kører over stdio og bliver opsamlet af Claude Desktop, tog 14 minutter første gang og under 5 minutter, når man først kender strukturen. Denne guide bygger den samme server to gange: én gang i Python med FastMCP 2.x og én gang i TypeScript med @modelcontextprotocol/sdk 1.x – så du kan vælge din stack og kopiere rigtig kode. Hvis du først vil have arkitekturen og protokolteorien på plads, har vores guide til Model Context Protocol-koncepter svarene; her fokuserer vi udelukkende på kodningen.
Hurtig start på MCP-server: Hvad bygger du?
En MCP-server er et lille program, der eksponerer værktøjer, data og prompt-skabeloner til AI-klienter som Claude, Cursor eller VS Code over Model Context Protocol. Du skriver serveren én gang, og enhver MCP-kompatibel klient kan kalde den. I denne guide vil du bygge en server med to værktøjer (en add-lommeregner og en fetch_url-hjælper), køre den lokalt over stdio, teste den og forbinde den til en rigtig klient.
Her er alt, hvad du skal bruge, før du starter.
| Krav | Python-sti | TypeScript-sti |
|---|---|---|
| Runtime | Python 3.10+ (3.11 anbefales) | Node.js 20 LTS+ |
| Pakkehåndtering | uv (anbefales) eller pip | npm, pnpm eller bun |
| SDK | mcp 1.x / FastMCP 2.x | @modelcontextprotocol/sdk 1.x |
| Klient til test | Claude Desktop, Claude Code eller Cursor | samme |
| Testværktøj | npx @modelcontextprotocol/inspector | samme |
Begge stier producerer en server, der opfører sig identisk. Vælg det sprog, dit team allerede bruger. Hvis du ikke har nogen præference, så start med Python, da FastMCP gør den første server kortere.
Hvad eksponerer en MCP-server egentlig?
Før du skriver kode, hjælper det at kende de tre ting, en server kan tilbyde. En MCP-server eksponerer værktøjer (funktioner modellen kan kalde, f.eks. "søg i databasen"), ressourcer (skrivebeskyttede data, modellen kan indlæse, f.eks. en fil eller en post) og prompts (genanvendelige prompt-skabeloner). De fleste servere, du bygger, vil være tungt fokuseret på værktøjer; ressourcer og prompts er valgfrie.
MCP-server, defineret: En proces, der taler Model Context Protocol og annoncerer en liste over værktøjer, ressourcer og prompts, som en AI-klient kan opdage og invoke ved runtime.
Klienten (f.eks. Claude Desktop) fungerer som vært. Den starter eller forbinder til din server, spørger "hvilke værktøjer har du?", og kalder dem derefter, når modellen beslutter, at et værktøj er nyttigt. Du kalder aldrig modellen inde fra serveren. Flowet går den anden vej.

Den retning er vigtig. Din server er en passiv udbyder. Den venter på, at klienten forbinder, besvarer opdagelsesanmodningen og kører det værktøj, der bliver kaldt. Hold fast i den mentale model, så falder resten af guiden på plads.
Sådan bygger du en MCP-server i Python (trin for trin)
Python er den hurtigste vej til en kørende server, fordi FastMCP håndterer protokollens infrastruktur og omdanner almindelige funktioner til værktøjer med en decorator. Alt nedenfor bruger det officielle Python SDK. Her er de fire trin.
Trin 1: Opsæt projektet. Brug uv, som nu er standarden for MCP Python-projekter:
uv init mcp-demo
cd mcp-demo
uv add "mcp[cli]"Hvis du foretrækker pip: python -m venv .venv && source .venv/bin/activate && pip install "mcp[cli]".
Trin 2: Skriv serveren. Opret server.py:
from mcp.server.fastmcp import FastMCP
import httpx
# Name shows up in the client's tool list
mcp = FastMCP("demo-server")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers and return the sum."""
return a + b
@mcp.tool()
async def fetch_url(url: str) -> str:
"""Fetch a URL and return the first 2000 characters of the body."""
async with httpx.AsyncClient(timeout=10) as client:
resp = await client.get(url)
return resp.text[:2000]
if __name__ == "__main__":
mcp.run() # defaults to stdio transportTo ting er værd at bemærke. Docstring'en bliver til værktøjsbeskrivelsen, som modellen læser, så skriv den som en instruktion. Og typehintsene (a: int) bliver automatisk til input-skemaet, så FastMCP genererer JSON Schema for dig.
Trin 3: Kør det. mcp.run() starter serveren på stdio, hvilket er den transport, klienter starter lokalt. Du kører ikke dette direkte under udvikling; klienten starter det. Til en hurtig røgtest kan du bruge dev-runneren:
uv run mcp dev server.pyTrin 4: Returner rent output. En fælde, det er værd at flagge nu: returnér en streng eller en typet værdi, ikke en rå nested dict, som du håber bliver renderet korrekt. Vi vender tilbage til hvorfor i produktionsafsnittet, men kort fortalt kan tvetydige returtyper blive stille afskåret i nogle klienter.
Det er en komplet Python MCP-server. To værktøjer, rigtige netværkskald, automatisk skema. Dernæst det samme i TypeScript.
Sådan bygger du en MCP-server i TypeScript (trin for trin)
TypeScript-stien bruger det officielle TypeScript SDK direkte og zod til inputvalidering. Det er lidt mere verbost end FastMCP, men typerne er fremragende, og det deployer rent til Node-værter.
Trin 1: Opsæt projektet.
mkdir mcp-demo && cd mcp-demo
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node tsxTrin 2: Skriv serveren. Opret server.ts:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({ name: "demo-server", version: "1.0.0" });
server.tool(
"add",
"Add two numbers and return the sum.",
{ a: z.number(), b: z.number() },
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }],
}),
);
server.tool(
"fetch_url",
"Fetch a URL and return the first 2000 characters.",
{ url: z.string().url() },
async ({ url }) => {
const resp = await fetch(url);
const body = await resp.text();
return { content: [{ type: "text", text: body.slice(0, 2000) }] };
},
);
const transport = new StdioServerTransport();
await server.connect(transport);Trin 3: Kør det. Under udvikling: npx tsx server.ts. Til produktion skal du kompilere med tsc og køre den buildede .js med Node. Bemærk returstrukturen: hvert værktøj returnerer { content: [{ type: "text", text: ... }] }. Den eksplicitte content-array er TypeScript-ækvivalenten til reglen om at "returnere en ren streng" fra Python. SDK'et ønsker typede content-blokke, ikke rå objekter.
Trin 4: Valider inputs med zod. Skemaet z.string().url() afviser dårligt input, før din handler kører, hvilket er præcis, hvad du ønsker, når en model genererer argumenterne.
Samme to værktøjer, samme adfærd, idiomatisk TypeScript. Lad os nu beslutte, hvordan klienter skal nå din server.
stdio vs. Streamable HTTP: Hvilken transport skal du bruge?
MCP-servere kommunikerer over en af to transporter. stdio kører serveren som en lokal underproces, som klienten starter og kommunikerer med via standard input/output. Streamable HTTP kører serveren som en netværkstjeneste, som klienter forbinder til over HTTP. Vælg baseret på, hvor serveren skal leve.
| stdio | Streamable HTTP | |
|---|---|---|
| Hvor det kører | Lokalt, startet af klienten | Fjern eller lokalt, som en webtjeneste |
| Bedst til | Personlige værktøjer, dev, enkeltmaskine | Delte servere, teams, SaaS, cloud |
| Auth | Arver brugerens maskine | Kræver OAuth 2.1 / token-auth |
| Opsætningsomkostninger | Lavest (bare en kommando) | Kræver hosting + et endpoint |
| Vores målte overhead | ~8-12 ms per kald (lokal) | ~40-70 ms per kald (netværksbundet) |

Tommelfingerregelen: byg og test på stdio, og skift derefter til Streamable HTTP kun, når mere end én person eller maskine har brug for serveren. De fleste servere behøver aldrig at forlade stdio. Kaldene mcp.run() og StdioServerTransport() ovenfor er allerede stdio, så du er klar til udvikling.
Sådan tester du din MCP-server med Inspector
Før du kobler din server til Claude, skal du teste den isoleret med MCP Inspector. Det er en browser-UI, der forbinder til din server, lister dens værktøjer og lader dig kalde dem manuelt. Kør det mod din server:
# Python
npx @modelcontextprotocol/inspector uv run server.py
# TypeScript
npx @modelcontextprotocol/inspector npx tsx server.tsInspector åbner en lokal side, hvor du kan se dine add- og fetch_url-værktøjer, affyre et testkald og læse det rå svar. Dette er den bedste vane inden for MCP-udvikling. Hvis et værktøjs skema er malformed, eller en returværdi er forkert, vil du se det her på sekunder i stedet for at stirre på en stilfejl inde i Claude. Vi fangede et dårligt input-skema på denne måde, som ellers ville have kostet en fuld debugging-runde gennem klienten. Test i Inspector først, hver gang.
Sådan forbinder du din MCP-server til Claude Desktop, Claude Code og Cursor
Når Inspector er tilfreds, skal du pege en rigtig klient mod din server. Hver klient læser en konfigurationsfil, der fortæller den, hvordan den skal starte din server over stdio.
Claude Desktop. Rediger claude_desktop_config.json (på macOS: ~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"demo-server": {
"command": "uv",
"args": ["--directory", "/absolute/path/to/mcp-demo", "run", "server.py"]
}
}
}Genstart Claude Desktop, og dine værktøjer vises under connector-ikonet.
Claude Code. Tilføj serveren med én kommando fra dit projekt: claude mcp add demo-server -- uv run server.py. Claude Code gemmer det i din projektkonfiguration og indlæser det ved opstart. Hvis du også bruger hooks til at scripte Claude Code, passer vores guide til Claude Code hooks godt sammen med custom MCP-værktøjer.
Cursor. Tilføj den samme mcpServers-blok til .cursor/mcp.json i din projektrod. Strukturen matcher Claude Desktops. For et eksempel fra virkeligheden på en MCP-server, der kører inde i Claude Code, se hvordan vi integrerede Higgsfield i Claude Code.
Brug absolutte stier i alle konfigurationer. Relative stier er den mest almindelige årsag til, at en server ikke starter.
Deploying af en MCP-server til produktion (Auth og Hosting)
Når din server skal deles, skal du flytte den fra stdio til Streamable HTTP og tilføje tre ting: autentificering, fejlhåndtering og en vært.
- Autentificering. Fjerne MCP-servere skal bruge OAuth 2.1 i henhold til MCP-autoriseringsspecifikationen. Til interne værktøjer er et bearer-token-tjek på HTTP-endpointet det pragmatiske minimum. Ship aldrig en offentlig, uautentificeret værktøjsserver, fordi et værktøj, der kører SQL eller rammer interne API'er, er en levende angrebsflade.
- Fejlhåndtering. Wrap værktøjskroppen i try/except (eller try/catch) og returnér en typet fejlmeddelelse i stedet for at throw'e. Modellen håndterer "forespørgslen fejlede, her er hvorfor" langt bedre end en afbrudt forbindelse.
- Hosting. Enhver platform, der kører en langlivet Node- eller Python-proces, virker: en lille VPS, Fly.io, Railway eller en container på din egen infrastruktur. Hold processen varm, da cold starts tilføjer latency til det første værktøjskald.
- Konkurrence og omkostninger. Hvis dine værktøjer kalder en LLM eller betalt API downstream, skal du placere en gateway foran dem. Vores oversigt over LLM-gatewayværktøjer dækker rate limiting og fallback, og context engineering-værktøjer hjælper med at holde værktøjsoutputs fra at oppuste modellens context-vindue.
For Python skal du ændre run-kaldet til mcp.run(transport="streamable-http"); for TypeScript skal du udskifte StdioServerTransport med SDK'ets StreamableHTTPServerTransport. Værktøjsdefinitionerne ændrer sig slet ikke – det er pointen med transportabstraktionen.
Hvad vi lærte ved at shippe MCP-servere i produktion
Vi har bygget MCP-servere til internt brug hos Techsy, og nogle lektioner viser sig først, når rigtig trafik rammer dem. Her er hvad vi målte, og hvor vi blev bidt.
Den første server, vi shippede, var et read-only Postgres-forespørgselsværktøj bygget med FastMCP 2.x på Python mcp 1.x SDK, senere omskrevet i @modelcontextprotocol/sdk 1.x for at sammenligne. På en 2026-stack (Node 20, Python 3.11) tilføjede lokale stdio-værktøjskald cirka 8 til 12 ms transport-overhead per kald. Da vi flyttede den samme server til Streamable HTTP på en VPS, steg omkostningen per kald til 40 til 70 ms, næsten udelukkende netværks round-trip snarere end protokolomkostning. FastMCP cold-start var omkring 300 ms for processen, hvilket er grunden til, at vi holder produktionsprocessen varm.
Fælden, der kostede os omkring to timer: et værktøj, der returnerede en rå Python-dict, blev renderet fint i Inspector, men kom tilbage trunkeret inde i Claude Desktop. At wrappe returværdien som en typet tekststreng løste det øjeblikkeligt. Det er derfor, denne guide returnerer strenge og content-tekstblokke overalt i stedet for nestede objekter. Den anden vane, der betalte sig med det samme, var at køre hver server gennem npx @modelcontextprotocol/inspector, før vi rørte en klientkonfiguration, hvilket afslørede et malformed input-skema på TypeScript-omskrivningen, som ellers ville have fejlet stille i Cursor.
| Hvad vi brugte | Version |
|---|---|
Python mcp SDK | 1.x |
| FastMCP | 2.x |
@modelcontextprotocol/sdk (TS) | 1.x |
| Node.js | 20 LTS |
| Inspector | @modelcontextprotocol/inspector (seneste) |
Hvis du vælger, hvilke værktøjer du skal bygge ind i servere i første omgang, er vores liste over de bedste MCP-servere i 2026 en god idébank.
Hvordan Techsy tilgår MCP-udvikling
Hos Techsy bygger vi MCP-servere som en del af de AI-agent-systemer, vi shipper til kunder, og forbinder agenter til interne databaser, CRM'er og API'er gennem et typet værktøjslag. Vores tilgang er at starte smalt (ét veltestet værktøj over stdio), validere det i Inspector og derefter promovere det til en autentificeret HTTP-tjeneste kun, når mere end én agent har brug for det. Vi parer custom-servere med Claude Agent SDK, når agentlogikken bliver kompleks.
Det er den ærlige version: de fleste teams overbygger deres første server. Du har sjældent brug for HTTP, OAuth og et dusin værktøjer på dag ét. Hvis du vil have et ekstra sæt øjne på en MCP-integration, kan du få en gratis konsultation, og vi vil fortælle dig, om det er et én-værktøj stdio-job eller noget, der genuint har brug for infrastruktur.
Ofte stillede spørgsmål
Skal jeg bygge min MCP-server i Python eller TypeScript?
Brug det sprog, dit team allerede shipper. Python med FastMCP er den korteste vej til en første kørende server, fordi en decorator omdanner en funktion til et værktøj. TypeScript med det officielle SDK er lidt mere verbost, men giver dig fremragende typer og deployer rent til Node-værter. Begge producerer servere, der opfører sig identisk over for klienten.
Har jeg brug for et framework som FastMCP for at bygge en MCP-server?
Nej, men det hjælper. FastMCP leveres med det officielle Python mcp SDK og fjerner det meste af protokol-boilerplaten. Du kan bruge den lavere niveau Server API for finjusteret kontrol, men til næsten enhver server er FastMCP (Python) eller McpServer (TypeScript) det rigtige værktøj og kræver langt mindre kode.
Hvordan debugger jeg en MCP-server, der ikke virker?
Kør den gennem MCP Inspector først: npx @modelcontextprotocol/inspector efterfulgt af din run-kommando. Inspector lister dine værktøjer og lader dig kalde dem direkte, så du kan bekræfte, at serveren virker, før du bebrejder klienten. Hvis Inspector er fin, men klienten ikke er, skal du tjekke, at din konfiguration bruger absolutte stier, og at du har genstartet klienten.
Er FastMCP en officiel del af MCP?
Ja. FastMCP er bundtet med det officielle Model Context Protocol Python SDK som high-level server-interface. Decoratoren @mcp.tool(), du bruger, er den anbefalede måde at bygge Python-servere på, ikke et tredjeparts-add-on.
Hvad er forskellen mellem en lokal og en fjern MCP-server?
En lokal server kører på din maskine over stdio, startet af klienten som en underproces, bedst til personlige værktøjer og udvikling. En fjern server kører som en webtjeneste over Streamable HTTP og er tilgængelig for flere klienter, hvilket kræver OAuth 2.1-autentificering. Byg lokalt først, gå remote kun ved deling.
Hvilke sprog kan jeg bygge en MCP-server i?
Model Context Protocol har officielle SDK'er til Python, TypeScript, Java, Kotlin og C#, med community-SDK'er på andre sprog. Da MCP er en wire-protokol, kan ethvert sprog, der kan læse og skrive JSON-RPC over stdio eller HTTP, implementere en server, men de officielle SDK'er sparer dig for det arbejde.
Virker en MCP-server med ChatGPT og Gemini, eller kun Claude?
MCP er en åben standard adopteret på tværs af det agentiske AI-økosystem, inklusive ChatGPT, Gemini, Cursor og VS Code Copilot. En enkelt server, du bygger, virker med enhver kompatibel klient. Du skriver ikke en separat integration per model, hvilket er hele pointen med protokollen.
Hvor lang tid tager det at bygge en fungerende MCP-server?
En første server med et eller to værktøjer, der kører over stdio, tager omkring 15 minutter, når din runtime er installeret. Vi målte 14 minutter for en nybegynder på Node 20 og under 5 minutter for et gentaget build. Det er tilføjelsen af autentificering, HTTP-transport og produktionshosting, der tager rigtig tid, ikke selve serveren.
Om forfatteren
Mert Batur Gurbuz er medstifter af Techsy.io, hvor teamet shipper AI-agenter, automatiseringssystemer og voice/SDR-pipelines til B2B-kunder. Han studerer på University of Birmingham og skriver om den LLM-tooling-stack, som Techsy-teamet faktisk bruger i produktion. Connect på LinkedIn.
Mert Batur Gurbuz, Medstifter, Techsy.io, University of Birmingham