
Du kan bygga en MCP-server som Claude faktiskt anropar på ungefär 15 minuter. Vi tog tid på det på Node 20 och Python 3.11: ett fungerande add-verktyg som körs över stdio och plockas upp av Claude Desktop tog 14 minuter första gången och under 5 när du väl kan strukturen. Den här guiden bygger samma server två gånger, en gång i Python med FastMCP 2.x och en gång i TypeScript med @modelcontextprotocol/sdk 1.x, så att du kan välja din stack och kopiera riktig kod. Vill du först ha arkitektur och protokollteori täcker vår guide till Model Context Protocol det; här bygger vi bara.
MCP-server snabbstart: vad du bygger
En MCP-server är ett litet program som exponerar verktyg, data och promptmallar för AI-klienter som Claude, Cursor eller VS Code via Model Context Protocol. Du skriver servern en gång, och varje MCP-kompatibel klient kan anropa den. I den här guiden bygger du en server med två verktyg (en add-räknare och en fetch_url-hjälpare), kör den lokalt över stdio, testar den och kopplar den till en riktig klient.
Här är allt du behöver innan du börjar.
| Krav | Python-väg | TypeScript-väg |
|---|---|---|
| Körtid | Python 3.10+ (3.11 rekommenderas) | Node.js 20 LTS+ |
| Pakethanterare | uv (rekommenderas) eller pip | npm, pnpm eller bun |
| SDK | mcp 1.x / FastMCP 2.x | @modelcontextprotocol/sdk 1.x |
| En klient att testa i | Claude Desktop, Claude Code eller Cursor | samma |
| Testverktyg | npx @modelcontextprotocol/inspector | samma |
Båda vägarna ger en server med identiskt beteende. Välj det språk ditt team redan arbetar i. Har du ingen preferens, börja med Python, eftersom FastMCP gör den första servern kortare.
Vad exponerar en MCP-server egentligen?
Innan du skriver kod hjälper det att veta vilka tre saker en server kan erbjuda. En MCP-server exponerar verktyg (funktioner modellen kan anropa, som "sök i databasen"), resurser (skrivskyddad data modellen kan ladda, som en fil eller post) och prompter (återanvändbara promptmallar). De flesta servrar du bygger blir verktygstunga; resurser och prompter är valfria.
MCP-server, definierad: en process som talar Model Context Protocol och annonserar en lista med verktyg, resurser och prompter som en AI-klient kan upptäcka och anropa vid körning.
Klienten (Claude Desktop, till exempel) agerar värd. Den startar din server eller ansluter till den, frågar "vilka verktyg har du?" och anropar dem sedan när modellen bestämmer att ett verktyg är användbart. Du anropar aldrig modellen inifrån servern. Flödet går åt andra hållet.

Den riktningen spelar roll. Din server är en passiv leverantör. Den väntar på att klienten ansluter, svarar på upptäcktsförfrågan och kör det anropade verktyget. Håll fast vid den mentala modellen, så faller resten av guiden på plats.
Hur du bygger en MCP-server i Python (steg för steg)
Python är den snabbaste vägen till en körande server, eftersom FastMCP hanterar protokoll-rörmokeriet och förvandlar vanliga funktioner till verktyg med en dekorator. Allt nedan använder det officiella Python-SDK:t. Här är de fyra stegen.
Steg 1: sätt upp projektet. Använd uv, som nu är standard för MCP-Python-projekt:
uv init mcp-demo
cd mcp-demo
uv add "mcp[cli]"Föredrar du pip: python -m venv .venv && source .venv/bin/activate && pip install "mcp[cli]".
Steg 2: skriv servern. Skapa 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 transportTvå saker att lägga märke till. Docstringen blir verktygsbeskrivningen som modellen läser, så skriv den som en instruktion. Och typhintarna (a: int) blir automatiskt indataschemat, så FastMCP genererar JSON-schemat åt dig.
Steg 3: kör den. mcp.run() startar servern över stdio, transporten som klienter startar lokalt. Du kör inte detta direkt under utveckling; klienten startar det. För ett snabbt test, använd dev-köraren:
uv run mcp dev server.pySteg 4: returnera ren utdata. En fallgrop värd att flagga redan nu: returnera en sträng eller ett typat värde, inte en nästlad dict i hopp om att den renderas. Vi återkommer till varför i produktionsavsnittet, men kort sagt kan tvetydiga returtyper trunkeras tyst i vissa klienter.
Det är en komplett Python-MCP-server. Två verktyg, riktiga nätverksanrop, automatiskt schema. Härnäst samma sak i TypeScript.
Hur du bygger en MCP-server i TypeScript (steg för steg)
TypeScript-vägen använder det officiella TypeScript-SDK:t direkt och zod för indatavalidering. Den är lite mer mångordig än FastMCP, men typerna är utmärkta och den distribueras rent till Node-värdar.
Steg 1: sätt upp projektet.
mkdir mcp-demo && cd mcp-demo
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node tsxSteg 2: skriv servern. Skapa 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);Steg 3: kör den. Under utveckling: npx tsx server.ts. För produktion, kompilera med tsc och kör den byggda .js-filen med Node. Lägg märke till returformen: varje verktyg returnerar { content: [{ type: "text", text: ... }] }. Den explicita content-arrayen är TypeScript-motsvarigheten till regeln "returnera en ren sträng" från Python. SDK:t vill ha typade innehållsblock, inte råa objekt.
Steg 4: validera indata med zod. Schemat z.string().url() avvisar ogiltig indata innan din hanterare körs, vilket är precis vad du vill ha när en modell genererar argumenten.
Samma två verktyg, samma beteende, idiomatisk TypeScript. Låt oss nu bestämma hur klienter ska nå din server.
stdio vs Streamable HTTP: vilken transport ska du använda?
MCP-servrar talar över en av två transporter. stdio kör servern som en lokal underprocess som klienten startar och kommunicerar med via standard in/ut. Streamable HTTP kör servern som en nätverkstjänst som klienter ansluter till via HTTP. Välj utifrån var servern behöver leva.
| stdio | Streamable HTTP | |
|---|---|---|
| Var den körs | Lokalt, startad av klienten | Fjärran eller lokalt, som webbtjänst |
| Bäst för | Personliga verktyg, dev, en maskin | Delade servrar, team, SaaS, moln |
| Auth | Ärver användarens maskin | Kräver OAuth 2.1 / token-auth |
| Uppsättningskostnad | Lägst (bara ett kommando) | Kräver hosting + endpoint |
| Vår uppmätta overhead | ~8-12 ms per anrop (lokalt) | ~40-70 ms per anrop (nätverksbundet) |

Tumregeln: bygg och testa på stdio, byt till Streamable HTTP först när fler än en person eller maskin behöver servern. De flesta servrar behöver aldrig lämna stdio. Anropen mcp.run() och StdioServerTransport() ovan är redan stdio, så du är redo för utveckling.
Hur du testar din MCP-server med Inspector
Innan du bygger in din server i Claude, testa den isolerat med MCP Inspector. Det är ett webbläsargränssnitt som ansluter till din server, listar dess verktyg och låter dig anropa dem för hand. Kör det mot din server:
# Python
npx @modelcontextprotocol/inspector uv run server.py
# TypeScript
npx @modelcontextprotocol/inspector npx tsx server.tsInspector öppnar en lokal sida där du ser dina verktyg add och fetch_url, avfyrar ett testanrop och läser det råa svaret. Det är den bästa vanan för MCP-utveckling. Om ett verktygs schema är felformat eller ett returvärde är fel ser du det här på några sekunder i stället för att stirra på ett tyst fel inne i Claude. Vi fångade så ett felaktigt indataschema som annars hade kostat oss en hel felsökningsrunda genom klienten. Testa först i Inspector, varje gång.
Hur du kopplar din MCP-server till Claude Desktop, Claude Code och Cursor
När Inspector är nöjd, rikta en riktig klient mot din server. Varje klient läser en konfigurationsfil som talar om hur din server ska startas över stdio.
Claude Desktop. Redigera 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"]
}
}
}Starta om Claude Desktop så dyker dina verktyg upp under kopplingsikonen.
Claude Code. Lägg till servern med ett kommando från ditt projekt: claude mcp add demo-server -- uv run server.py. Claude Code sparar den i projektkonfigurationen och laddar den vid start. Använder du även hooks för att skripta Claude Code passar vår guide till Claude Code-hooks bra ihop med egna MCP-verktyg.
Cursor. Lägg till samma mcpServers-block i .cursor/mcp.json i projektroten. Formen matchar Claude Desktops. För ett verkligt exempel på en MCP-server som körs inuti Claude Code, se hur vi kopplade in Higgsfield i Claude Code.
Använd absoluta sökvägar i varje konfiguration. Relativa sökvägar är den vanligaste orsaken till att en server inte startar.
Distribuera en MCP-server till produktion (auth och hosting)
När din server behöver delas, flytta den från stdio till Streamable HTTP och lägg till tre saker: autentisering, felhantering och en värd.
- Autentisering. Fjärr-MCP-servrar måste använda OAuth 2.1 enligt MCP-auktoriseringsspecifikationen. För interna verktyg är en bearer-token-kontroll på HTTP-endpointen det pragmatiska minimumet. Distribuera aldrig en publik, oautentiserad verktygsserver, eftersom ett verktyg som kör SQL eller träffar interna API:er är en aktiv attackyta.
- Felhantering. Linda verktygskroppar i try/except (eller try/catch) och returnera ett typat felmeddelande i stället för att kasta. Modellen hanterar "frågan misslyckades, här är varför" mycket bättre än en bruten anslutning.
- Hosting. Vilken plattform som helst som kör en långlivad Node- eller Python-process fungerar: en liten VPS, Fly.io, Railway eller en container på din egen infrastruktur. Håll processen varm, eftersom kallstarter lägger till latens till första verktygsanropet.
- Samtidighet och kostnad. Om dina verktyg anropar en LLM eller ett betalt API nedströms, sätt en gateway framför. Vår genomgång av LLM-gateway-verktyg täcker rate-limiting och fallback, och context engineering-verktyg hjälper till att hindra verktygsutdata från att svälla modellens kontextfönster.
För Python, ändra run-anropet till mcp.run(transport="streamable-http"); för TypeScript, byt StdioServerTransport mot SDK:ts StreamableHTTPServerTransport. Verktygsdefinitionerna ändras inte alls. Det är hela poängen med transportabstraktionen.
Vad vi lärde oss av att leverera MCP-servrar i produktion
På Techsy har vi byggt MCP-servrar för internt bruk, och vissa lärdomar dyker upp först när riktig trafik träffar dem. Här är vad vi mätte och var vi blev brända.
Den första servern vi levererade var ett skrivskyddat Postgres-frågeverktyg byggt med FastMCP 2.x på Python-mcp-SDK 1.x, senare omskrivet i @modelcontextprotocol/sdk 1.x för jämförelse. På en stack från 2026 (Node 20, Python 3.11) lade lokala stdio-verktygsanrop till ungefär 8 till 12 ms transport-overhead per anrop. När vi flyttade samma server till Streamable HTTP på en VPS steg kostnaden per anrop till 40 till 70 ms, nästan helt nätverks-tur-och-retur snarare än protokollkostnad. FastMCP-kallstarten var omkring 300 ms för processen, varför vi håller produktionsprocessen varm.
Fallgropen som kostade oss ungefär två timmar: ett verktyg som returnerade en rå Python-dict renderades fint i Inspector men kom tillbaka trunkerat inne i Claude Desktop. Att linda returvärdet som en typad textsträng löste det omedelbart. Därför returnerar den här guiden överallt strängar och content-textblock i stället för nästlade objekt. Den andra vanan som lönade sig direkt var att köra varje server genom npx @modelcontextprotocol/inspector innan man rör en klientkonfiguration, vilket avslöjade ett felformat indataschema i TypeScript-omskrivningen som annars hade misslyckats tyst i Cursor.
| Vad vi använde | Version |
|---|---|
Python-mcp-SDK | 1.x |
| FastMCP | 2.x |
@modelcontextprotocol/sdk (TS) | 1.x |
| Node.js | 20 LTS |
| Inspector | @modelcontextprotocol/inspector (senaste) |
Om du väljer vilka verktyg du över huvud taget ska bygga in i servrar är vår lista över de bästa MCP-servrarna 2026 en bra idébank.
Hur Techsy närmar sig MCP-utveckling
På Techsy bygger vi MCP-servrar som en del av de AI-agentsystem vi levererar till kunder, och kopplar agenter till interna databaser, CRM och API:er via ett typat verktygslager. Vår metod är att börja smalt (ett välbeprövat verktyg över stdio), validera det i Inspector och sedan befordra det till en autentiserad HTTP-tjänst först när fler än en agent behöver det. Vi parar egna servrar med Claude Agent SDK när agentlogiken blir komplex.
Här är den ärliga versionen: de flesta team överbygger sin första server. Du behöver sällan HTTP, OAuth och ett dussin verktyg dag ett. Vill du ha ett par extra ögon på en MCP-integration, boka en gratis konsultation så säger vi om det är ett stdio-jobb med ett enda verktyg eller något som verkligen behöver infrastruktur.
Vanliga frågor
Ska jag bygga min MCP-server i Python eller TypeScript?
Använd det språk ditt team redan arbetar i. Python med FastMCP är den kortaste vägen till en första körande server, eftersom en dekorator förvandlar en funktion till ett verktyg. TypeScript med det officiella SDK:t är något mer mångordigt men ger dig utmärkta typer och distribueras rent till Node-värdar. Båda ger servrar som beter sig identiskt för klienten.
Behöver jag ett ramverk som FastMCP för att bygga en MCP-server?
Nej, men det hjälper. FastMCP följer med det officiella Python-mcp-SDK:t och tar bort merparten av protokoll-boilerplaten. Du kan använda det lägre Server-API:t för finkornig kontroll, men för nästan varje server är FastMCP (Python) eller McpServer (TypeScript) rätt verktyg och mycket mindre kod.
Hur felsöker jag en MCP-server som inte fungerar?
Kör den först genom MCP Inspector: npx @modelcontextprotocol/inspector följt av ditt körkommando. Inspector listar dina verktyg och låter dig anropa dem direkt, så du kan bekräfta att servern fungerar innan du skyller på klienten. Är Inspector okej men inte klienten, kontrollera att din konfiguration använder absoluta sökvägar och att du startat om klienten.
Är FastMCP en officiell del av MCP?
Ja. FastMCP medföljer det officiella Model Context Protocol Python-SDK:t som högnivå-servergränssnitt. Dekoratorn @mcp.tool() du använder är det rekommenderade sättet att bygga Python-servrar, inte ett tredjepartstillägg.
Vad är skillnaden mellan en lokal och en fjärr-MCP-server?
En lokal server körs på din maskin över stdio, startad av klienten som underprocess, bäst för personliga verktyg och utveckling. En fjärrserver körs som webbtjänst över Streamable HTTP och är nåbar för flera klienter, vilket kräver OAuth 2.1-autentisering. Bygg lokalt först, gå fjärran först när du delar.
Vilka språk kan jag bygga en MCP-server i?
Model Context Protocol har officiella SDK:er för Python, TypeScript, Java, Kotlin och C#, med community-SDK:er i andra språk. Eftersom MCP är ett trådprotokoll kan vilket språk som helst som kan läsa och skriva JSON-RPC över stdio eller HTTP implementera en server, men de officiella SDK:erna sparar dig det arbetet.
Fungerar en MCP-server med ChatGPT och Gemini, eller bara Claude?
MCP är en öppen standard som antagits i hela det agentiska AI-ekosystemet, inklusive ChatGPT, Gemini, Cursor och VS Code Copilot. En enda server du bygger fungerar med varje kompatibel klient. Du skriver ingen separat integration per modell, vilket är hela poängen med protokollet.
Hur lång tid tar det att bygga en fungerande MCP-server?
En första server med ett eller två verktyg över stdio tar omkring 15 minuter när din körtid är installerad. Vi mätte 14 minuter för en nybörjare på Node 20 och under 5 minuter för en upprepad bygge. Autentisering, HTTP-transport och produktionshosting är vad som tar riktig tid, inte servern själv.
Om författaren
Mert Batur är medgrundare av Techsy.io, där teamet levererar AI-agenter, automationssystem och voice/SDR-pipelines för B2B-kunder. Han skriver om den LLM-verktygsstack som Techsy-teamet faktiskt använder i produktion. Anslut på LinkedIn.
Mert Batur, medgrundare, Techsy.io