
Du kan bygge en MCP-server som Claude faktisk kaller på rundt 15 minutter. Vi tok tiden på det på Node 20 og Python 3.11: et fungerende add-verktøy som kjører over stdio og plukkes opp av Claude Desktop tok 14 minutter første gang og under 5 når du kan strukturen. Denne guiden bygger samme server to ganger, én gang i Python med FastMCP 2.x og én gang i TypeScript med @modelcontextprotocol/sdk 1.x, så du kan velge din stack og kopiere ekte kode. Vil du ha arkitektur og protokollteori først, dekker vår guide til Model Context Protocol det; her bygger vi bare.
MCP-server hurtigstart: hva du bygger
En MCP-server er et lite program som eksponerer verktøy, data og promptmaler for AI-klienter som Claude, Cursor eller VS Code via Model Context Protocol. Du skriver serveren én gang, og enhver MCP-kompatibel klient kan kalle den. I denne guiden bygger du en server med to verktøy (en add-kalkulator og en fetch_url-hjelper), kjører den lokalt over stdio, tester den og kobler den til en ekte klient.
Her er alt du trenger før du starter.
| Krav | Python-vei | TypeScript-vei |
|---|---|---|
| Kjøretid | Python 3.10+ (3.11 anbefales) | Node.js 20 LTS+ |
| Pakkehåndterer | uv (anbefales) eller pip | npm, pnpm eller bun |
| SDK | mcp 1.x / FastMCP 2.x | @modelcontextprotocol/sdk 1.x |
| En klient å teste i | Claude Desktop, Claude Code eller Cursor | samme |
| Testverktøy | npx @modelcontextprotocol/inspector | samme |
Begge veiene gir en server med identisk oppførsel. Velg språket teamet ditt allerede jobber i. Har du ingen preferanse, start med Python, fordi FastMCP gjør den første serveren kortere.
Hva eksponerer en MCP-server egentlig?
Før du skriver kode hjelper det å vite hvilke tre ting en server kan tilby. En MCP-server eksponerer verktøy (funksjoner modellen kan kalle, som "søk i databasen"), ressurser (skrivebeskyttede data modellen kan laste, som en fil eller post) og prompter (gjenbrukbare promptmaler). De fleste servere du bygger blir verktøytunge; ressurser og prompter er valgfrie.
MCP-server, definert: en prosess som snakker Model Context Protocol og kunngjør en liste over verktøy, ressurser og prompter som en AI-klient kan oppdage og kalle ved kjøretid.
Klienten (Claude Desktop, for eksempel) opptrer som vert. Den starter serveren din eller kobler til den, spør "hvilke verktøy har du?", og kaller dem så når modellen bestemmer at et verktøy er nyttig. Du kaller aldri modellen fra inne i serveren. Flyten går andre veien.

Den retningen betyr noe. Serveren din er en passiv leverandør. Den venter på at klienten kobler til, svarer på oppdagelsesforespørselen og kjører det kalte verktøyet. Hold fast ved den mentale modellen, så faller resten av guiden på plass.
Hvordan bygge en MCP-server i Python (trinn for trinn)
Python er den raskeste veien til en kjørende server, fordi FastMCP håndterer protokoll-rørleggingen og gjør vanlige funksjoner om til verktøy med en dekorator. Alt nedenfor bruker det offisielle Python-SDK-et. Her er de fire trinnene.
Trinn 1: sett opp prosjektet. Bruk uv, som nå er standard for MCP-Python-prosjekter:
uv init mcp-demo
cd mcp-demo
uv add "mcp[cli]"Foretrekker du pip: python -m venv .venv && source .venv/bin/activate && pip install "mcp[cli]".
Trinn 2: skriv serveren. Opprett 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 å legge merke til. Docstringen blir verktøybeskrivelsen modellen leser, så skriv den som en instruksjon. Og typehintene (a: int) blir automatisk inndataskjemaet, så FastMCP genererer JSON-skjemaet for deg.
Trinn 3: kjør den. mcp.run() starter serveren over stdio, transporten klienter starter lokalt. Du kjører ikke dette direkte under utvikling; klienten starter det. For en rask test, bruk dev-kjøreren:
uv run mcp dev server.pyTrinn 4: returner ren utdata. En felle verdt å nevne allerede nå: returner en streng eller en typet verdi, ikke en nestet dict i håp om at den rendres. Vi kommer tilbake til hvorfor i produksjonsdelen, men kort sagt kan tvetydige returtyper trunkeres stille i noen klienter.
Det er en komplett Python-MCP-server. To verktøy, ekte nettverkskall, automatisk skjema. Deretter det samme i TypeScript.
Hvordan bygge en MCP-server i TypeScript (trinn for trinn)
TypeScript-veien bruker det offisielle TypeScript-SDK-et direkte og zod for inndatavalidering. Den er litt mer ordrik enn FastMCP, men typene er utmerkede og den distribueres rent til Node-verter.
Trinn 1: sett opp prosjektet.
mkdir mcp-demo && cd mcp-demo
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node tsxTrinn 2: skriv serveren. Opprett 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);Trinn 3: kjør den. Under utvikling: npx tsx server.ts. For produksjon, kompiler med tsc og kjør den bygde .js-filen med Node. Legg merke til returformen: hvert verktøy returnerer { content: [{ type: "text", text: ... }] }. Den eksplisitte content-arrayen er TypeScript-ekvivalenten til regelen "returner en ren streng" fra Python. SDK-et vil ha typede innholdsblokker, ikke rå objekter.
Trinn 4: valider inndata med zod. Skjemaet z.string().url() avviser ugyldig inndata før handleren din kjører, som er nøyaktig det du vil ha når en modell genererer argumentene.
De samme to verktøyene, samme oppførsel, idiomatisk TypeScript. La oss nå bestemme hvordan klienter skal nå serveren din.
stdio vs Streamable HTTP: hvilken transport bør du bruke?
MCP-servere snakker over én av to transporter. stdio kjører serveren som en lokal underprosess klienten starter og kommuniserer med over standard inn/ut. Streamable HTTP kjører serveren som en nettverkstjeneste klienter kobler til over HTTP. Velg ut fra hvor serveren må leve.
| stdio | Streamable HTTP | |
|---|---|---|
| Hvor den kjører | Lokalt, startet av klienten | Eksternt eller lokalt, som webtjeneste |
| Best for | Personlige verktøy, dev, én maskin | Delte servere, team, SaaS, sky |
| Auth | Arver brukerens maskin | Krever OAuth 2.1 / token-auth |
| Oppsettskostnad | Lavest (bare en kommando) | Krever hosting + endepunkt |
| Vår målte overhead | ~8-12 ms per kall (lokalt) | ~40-70 ms per kall (nettverksbundet) |

Tommelfingerregelen: bygg og test på stdio, bytt til Streamable HTTP først når mer enn én person eller maskin trenger serveren. De fleste servere trenger aldri å forlate stdio. Kallene mcp.run() og StdioServerTransport() over er allerede stdio, så du er klar for utvikling.
Hvordan teste MCP-serveren din med Inspector
Før du bygger serveren din inn i Claude, test den isolert med MCP Inspector. Det er et nettlesergrensesnitt som kobler til serveren din, lister verktøyene dens og lar deg kalle dem for hånd. Kjør det mot serveren din:
# Python
npx @modelcontextprotocol/inspector uv run server.py
# TypeScript
npx @modelcontextprotocol/inspector npx tsx server.tsInspector åpner en lokal side der du ser verktøyene add og fetch_url, avfyrer et testkall og leser det rå svaret. Det er den beste vanen for MCP-utvikling. Hvis et verktøys skjema er feilformet eller en returverdi er feil, ser du det her på sekunder i stedet for å stirre på en stille feil inne i Claude. Vi fanget slik et feil inndataskjema som ellers hadde kostet oss en hel feilsøkingsrunde gjennom klienten. Test først i Inspector, hver gang.
Hvordan koble MCP-serveren din til Claude Desktop, Claude Code og Cursor
Når Inspector er fornøyd, pek en ekte klient mot serveren din. Hver klient leser en konfigurasjonsfil som forteller hvordan serveren din skal startes 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"]
}
}
}Start Claude Desktop på nytt, så dukker verktøyene dine opp under koblingsikonet.
Claude Code. Legg til serveren med én kommando fra prosjektet ditt: claude mcp add demo-server -- uv run server.py. Claude Code lagrer den i prosjektkonfigurasjonen og laster den ved oppstart. Bruker du også hooks for å skripte Claude Code, passer vår guide til Claude Code-hooks godt sammen med egne MCP-verktøy.
Cursor. Legg til samme mcpServers-blokk i .cursor/mcp.json i prosjektroten. Formen samsvarer med Claude Desktops. For et ekte eksempel på en MCP-server som kjører inne i Claude Code, se hvordan vi koblet inn Higgsfield i Claude Code.
Bruk absolutte stier i hver konfigurasjon. Relative stier er den vanligste grunnen til at en server ikke starter.
Distribuere en MCP-server til produksjon (auth og hosting)
Når serveren din må deles, flytt den fra stdio til Streamable HTTP og legg til tre ting: autentisering, feilhåndtering og en vert.
- Autentisering. Eksterne MCP-servere må bruke OAuth 2.1 i henhold til MCP-autorisasjonsspesifikasjonen. For interne verktøy er en bearer-token-sjekk på HTTP-endepunktet det pragmatiske minimumet. Distribuer aldri en offentlig, uautentisert verktøyserver, fordi et verktøy som kjører SQL eller treffer interne API-er er en aktiv angrepsflate.
- Feilhåndtering. Pakk verktøykropper i try/except (eller try/catch) og returner en typet feilmelding i stedet for å kaste. Modellen håndterer "spørringen feilet, her er hvorfor" mye bedre enn en brutt tilkobling.
- Hosting. Enhver plattform som kjører en langlevd Node- eller Python-prosess fungerer: en liten VPS, Fly.io, Railway eller en container på din egen infrastruktur. Hold prosessen varm, fordi kaldstarter legger til latens til det første verktøykallet.
- Samtidighet og kostnad. Hvis verktøyene dine kaller en LLM eller et betalt API nedstrøms, sett en gateway foran. Vår gjennomgang av LLM-gateway-verktøy dekker rate-limiting og fallback, og context engineering-verktøy hjelper med å hindre at verktøyutdata sveller modellens kontekstvindu.
For Python, endre run-kallet til mcp.run(transport="streamable-http"); for TypeScript, bytt StdioServerTransport mot SDK-ets StreamableHTTPServerTransport. Verktøydefinisjonene endres ikke i det hele tatt. Det er hele poenget med transportabstraksjonen.
Hva vi lærte av å levere MCP-servere i produksjon
Hos Techsy har vi bygd MCP-servere for intern bruk, og noen lærdommer dukker først opp når ekte trafikk treffer dem. Her er hva vi målte og hvor vi ble brent.
Den første serveren vi leverte var et skrivebeskyttet Postgres-spørreverktøy bygd med FastMCP 2.x på Python-mcp-SDK 1.x, senere skrevet om i @modelcontextprotocol/sdk 1.x for sammenligning. På en stack fra 2026 (Node 20, Python 3.11) la lokale stdio-verktøykall til omtrent 8 til 12 ms transport-overhead per kall. Da vi flyttet samme server til Streamable HTTP på en VPS, steg kostnaden per kall til 40 til 70 ms, nesten utelukkende nettverks-tur-retur snarere enn protokollkostnad. FastMCP-kaldstarten var omtrent 300 ms for prosessen, derfor holder vi produksjonsprosessen varm.
Fellen som kostet oss rundt to timer: et verktøy som returnerte en rå Python-dict rendret fint i Inspector men kom tilbake trunkert inne i Claude Desktop. Å pakke returverdien som en typet tekststreng løste det umiddelbart. Derfor returnerer denne guiden overalt strenger og content-tekstblokker i stedet for nestede objekter. Den andre vanen som lønte seg umiddelbart var å kjøre hver server gjennom npx @modelcontextprotocol/inspector før man rører en klientkonfigurasjon, noe som avdekket et feilformet inndataskjema i TypeScript-omskrivingen som ellers hadde feilet stille i Cursor.
| Hva vi brukte | Versjon |
|---|---|
Python-mcp-SDK | 1.x |
| FastMCP | 2.x |
@modelcontextprotocol/sdk (TS) | 1.x |
| Node.js | 20 LTS |
| Inspector | @modelcontextprotocol/inspector (nyeste) |
Hvis du velger hvilke verktøy du i det hele tatt skal bygge inn i servere, er listen vår over de beste MCP-serverne 2026 en god idébank.
Hvordan Techsy nærmer seg MCP-utvikling
Hos Techsy bygger vi MCP-servere som en del av AI-agentsystemene vi leverer til kunder, og kobler agenter til interne databaser, CRM-er og API-er via et typet verktøylag. Tilnærmingen vår er å starte smalt (ett godt testet verktøy over stdio), validere det i Inspector og så forfremme det til en autentisert HTTP-tjeneste først når mer enn én agent trenger det. Vi parer egne servere med Claude Agent SDK når agentlogikken blir kompleks.
Her er den ærlige versjonen: de fleste team overbygger sin første server. Du trenger sjelden HTTP, OAuth og et dusin verktøy dag én. Vil du ha et par ekstra øyne på en MCP-integrasjon, bestill en gratis konsultasjon så sier vi om det er en stdio-jobb med ett enkelt verktøy eller noe som virkelig trenger infrastruktur.
Vanlige spørsmål
Bør jeg bygge MCP-serveren min i Python eller TypeScript?
Bruk språket teamet ditt allerede jobber i. Python med FastMCP er den korteste veien til en første kjørende server, fordi en dekorator gjør en funksjon om til et verktøy. TypeScript med det offisielle SDK-et er litt mer ordrikt men gir deg utmerkede typer og distribueres rent til Node-verter. Begge gir servere som oppfører seg identisk for klienten.
Trenger jeg et rammeverk som FastMCP for å bygge en MCP-server?
Nei, men det hjelper. FastMCP følger med det offisielle Python-mcp-SDK-et og fjerner mesteparten av protokoll-boilerplaten. Du kan bruke det lavere Server-API-et for finkornet kontroll, men for nesten enhver server er FastMCP (Python) eller McpServer (TypeScript) rett verktøy og mye mindre kode.
Hvordan feilsøker jeg en MCP-server som ikke fungerer?
Kjør den først gjennom MCP Inspector: npx @modelcontextprotocol/inspector etterfulgt av kjørekommandoen din. Inspector lister verktøyene dine og lar deg kalle dem direkte, så du kan bekrefte at serveren fungerer før du skylder på klienten. Er Inspector grei men ikke klienten, sjekk at konfigurasjonen din bruker absolutte stier og at du startet klienten på nytt.
Er FastMCP en offisiell del av MCP?
Ja. FastMCP følger med det offisielle Model Context Protocol Python-SDK-et som høynivå-servergrensesnitt. Dekoratoren @mcp.tool() du bruker er den anbefalte måten å bygge Python-servere på, ikke et tredjepartstillegg.
Hva er forskjellen mellom en lokal og en ekstern MCP-server?
En lokal server kjører på maskinen din over stdio, startet av klienten som underprosess, best for personlige verktøy og utvikling. En ekstern server kjører som webtjeneste over Streamable HTTP og er tilgjengelig for flere klienter, noe som krever OAuth 2.1-autentisering. Bygg lokalt først, gå eksternt først når du deler.
Hvilke språk kan jeg bygge en MCP-server i?
Model Context Protocol har offisielle SDK-er for Python, TypeScript, Java, Kotlin og C#, med community-SDK-er i andre språk. Siden MCP er en trådprotokoll, kan ethvert språk som kan lese og skrive JSON-RPC over stdio eller HTTP implementere en server, men de offisielle SDK-ene sparer deg det arbeidet.
Fungerer en MCP-server med ChatGPT og Gemini, eller bare Claude?
MCP er en åpen standard som er tatt i bruk i hele det agentiske AI-økosystemet, inkludert ChatGPT, Gemini, Cursor og VS Code Copilot. En enkelt server du bygger fungerer med enhver kompatibel klient. Du skriver ingen separat integrasjon per modell, som er hele poenget med protokollen.
Hvor lang tid tar det å bygge en fungerende MCP-server?
En første server med ett eller to verktøy over stdio tar omtrent 15 minutter når kjøretiden din er installert. Vi målte 14 minutter for en nybegynner på Node 20 og under 5 minutter for en gjentatt bygging. Autentisering, HTTP-transport og produksjonshosting er det som tar ekte tid, ikke serveren selv.
Om forfatteren
Mert Batur er medgründer av Techsy.io, der teamet leverer AI-agenter, automasjonssystemer og voice/SDR-pipelines for B2B-kunder. Han skriver om LLM-verktøystacken Techsy-teamet faktisk bruker i produksjon. Koble til på LinkedIn.
Mert Batur, medgründer, Techsy.io