IntermediateClaude CodeCLIMCP

Claude Code: guide for danske udviklere

Claude Code er ikke autocomplete i en sidebar. Det er en agent der læser filer, kører kommandoer og retter kode i din terminal — og derfor er permissions og konfiguration det første du skal forstå.

1. september 202614 min læsetid

TL;DR

Installér, kør i projektroden, og bed om en ændring i almindeligt sprog. Alt andet i denne guide handler om at gøre den løkke sikker og gentagelig.

terminalbash
1npm install -g @anthropic-ai/claude-code
2
3cd ~/projekter/mit-repo
4claude
5
6# Eller uden interaktiv session — svaret kommer på stdout
7claude -p "Hvilke filer håndterer authentication?"

Prerequisites

  • • Node.js 18+
  • • Et Claude-abonnement eller en API-nøgle fra Anthropic
  • • Et git-repo — Claude Code kan køre uden, men du mister din fortrydelsesknap

Hvad Claude Code faktisk er

De fleste AI-kodeværktøjer sidder i editoren og foreslår den næste linje. Claude Code sidder i terminalen og har et andet mandat: den må søge i repoet, læse filer, redigere dem, køre tests og kalde eksterne værktøjer. Modellen bestemmer selv hvilke skridt der skal til — du beskriver målet, ikke fremgangsmåden.

Det er den samme agent-løkke som i guiden om at bygge en AI-agent fra bunden: modellen kalder et værktøj, får et resultat tilbage, tænker videre, kalder det næste. Forskellen er at værktøjerne allerede findes (læs fil, skriv fil, kør bash, søg med grep), og at løkken kører mod din faktiske arbejdsmappe.

Den forskel er hele pointen — og hele risikoen. En autocomplete kan foreslå noget forkert. En agent kan slette noget forkert.

Step 1: Den første session

Start altid i projektroden. Claude Code bruger arbejdsmappen som sin grænse: den læser og skriver derinde, og skal spørge om lov før den går udenfor.

terminalbash
1cd ~/projekter/mit-repo
2claude
3
4> Find hvor vi validerer JWT-tokens, og tilføj en test der dækker
5> udløbne tokens.

Første gang en ny type handling optræder, beder Claude Code om godkendelse: må den redigere denne fil, må den køre denne kommando. Du kan godkende én gang eller for hele sessionen. Det er irriterende i tre minutter og redningen den dag modellen misforstår en instruktion.

Headless mode

Med -p kører Claude Code én opgave og afslutter. Det er formen du bruger i scripts, i CI og i pipelines:

terminalbash
1# Almindeligt svar på stdout
2claude -p "Opsummer ændringerne i den seneste commit"
3
4# Struktureret output, så du kan parse det
5claude -p "List alle TODO-kommentarer som JSON" --output-format json
6
7# Pipe ind fra andre værktøjer
8git diff | claude -p "Skriv en commit-besked ud fra denne diff"

Vær opmærksom på exit-koden. Et kald der ikke nåede at udføre noget som helst kan stadig returnere 0. Hvis du bygger et script der kører opgaver i kø, skal du tjekke selve outputtet — ikke kun exit-koden — før du markerer opgaven som løst.

Step 2: CLAUDE.md — projektets hukommelse

En CLAUDE.md i projektroden bliver læst automatisk ved hver session. Det er stedet til det modellen umuligt kan gætte: hvilke kommandoer der bygger projektet, hvilke mapper der er genereret, hvilke regler der ikke må brydes.

CLAUDE.mdmarkdown
1# Projektkonventioner
2
3## Kommandoer
4- Build: `npm run build`
5- Test: `npm test -- --run` (vitest, watch er slået fra i CI)
6- Lint: `npm run lint`
7
8## Arkitektur
9- `src/db/schema.ts` er source of truth. Migrationer i `drizzle/`
10 er genereret — redigér dem aldrig i hånden.
11- Al netværkskald går gennem `src/lib/http.ts`, aldrig fetch direkte.
12
13## Regler
14- Ingen nye afhængigheder uden at spørge først.
15- Skriv tests i samme PR som ændringen.

Hold filen kort. Den koster tokens ved hver eneste forespørgsel, og en CLAUDE.md på 400 linjer bliver til støj, ikke til kontekst. Skriv det der er specifikt for dit projekt, og lad være med at forklare hvad TypeScript er.

Step 3: Permissions du kan stole på

Godkendelser kan gøres permanente i settings.json. Filen lever i .claude/ i projektet (delt med teamet) eller i ~/.claude/ (kun dig).

.claude/settings.jsonjson
1{
2 "permissions": {
3 "allow": [
4 "Read",
5 "Grep",
6 "Glob",
7 "Bash(npm test:*)",
8 "Bash(npm run lint)",
9 "Bash(git status)",
10 "Bash(git diff:*)"
11 ],
12 "deny": [
13 "Bash(rm -rf:*)",
14 "Bash(git push:*)",
15 "Read(./.env)",
16 "Read(./secrets/**)"
17 ]
18 }
19}

Mønsteret er værd at lægge mærke til: læsning og tests er frit, alt destruktivt kræver et menneske, og hemmeligheder er helt spærret. deny vinder altid over allow.

Der findes et flag der springer alle spørgsmål over. Brug det kun i en container eller en engangsmaskine, hvor det værste udfald er at du bygger miljøet op igen. På din arbejdsmaskine, med adgang til produktionsnøgler, er det ikke en tidsbesparelse — det er en hændelse der venter på at ske.

Step 4: MCP-servere

Model Context Protocol er den åbne standard for at give en model adgang til værktøjer og data. Claude Code er en MCP-klient, så enhver MCP-server bliver til værktøjer agenten kan kalde — din database, dit issue-tracker, din analytics-platform.

terminalbash
1# Tilføj en server til dette projekt
2claude mcp add postgres -- npx -y @modelcontextprotocol/server-postgres \
3 postgresql://localhost/mindb
4
5# Se hvad der er tilsluttet
6claude mcp list

Konfigurationen kan også committes, så hele teamet får de samme værktøjer. Læg en .mcp.json i projektroden:

.mcp.jsonjson
1{
2 "mcpServers": {
3 "postgres": {
4 "command": "npx",
5 "args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mindb"]
6 },
7 "sentry": {
8 "type": "http",
9 "url": "https://mcp.sentry.dev/mcp"
10 }
11 }
12}

To praktiske erfaringer med MCP-servere. Den første: skriv aldrig hemmeligheder direkte i filen hvis den skal i git — brug environment-variabler. Den anden: foretræk type: "http" når serveren tilbyder det. Wrapper-løsninger der kører en lokal proces for at nå en fjern server har det med at miste deres OAuth-tokens ved hvert versionsspring, og fejlen viser sig som en browserfane der åbner sig midt i en session.

Vil du bygge din egen server frem for at bruge andres, er protokollen beskrevet trin for trin i MCP-guiden.

Step 5: Subagents

En subagent er en separat instans med sit eget context window, sit eget systemprompt og sin egen værktøjsliste. Den bruges til arbejde der ellers ville fylde hovedsessionen med støj — at læse tredive filer for at finde ét svar, for eksempel.

.claude/agents/test-runner.mdmarkdown
1---
2name: test-runner
3description: Kører testsuiten og rapporterer kun de fejlende tests med årsag.
4tools: Read, Grep, Glob, Bash
5---
6
7Du kører projektets tests og rapporterer resultatet.
8
9Kør `npm test -- --run`. Hvis alt består: svar med én linje.
10Hvis noget fejler: for hver fejlende test angiv filnavn, testnavn,
11den faktiske fejlbesked og den mest sandsynlige årsag.
12
13Ret ikke koden. Din opgave er diagnosen, ikke behandlingen.

Værdien er isolationen. Subagenten læser hundredvis af linjer testoutput; hovedsessionen får tre linjer konklusion tilbage. Kontekstvinduet er en begrænset ressource, og subagents er den billigste måde at bruge det på.

Step 6: Hooks

Hooks er shell-kommandoer der kører deterministisk ved bestemte hændelser. Hvor en instruktion i CLAUDE.md er noget modellen bør følge, er en hook noget der sker. Det er forskellen mellem at bede om formateret kode og at få det.

.claude/settings.jsonjson
1{
2 "hooks": {
3 "PostToolUse": [
4 {
5 "matcher": "Edit|Write",
6 "hooks": [
7 {
8 "type": "command",
9 "command": "npx prettier --write \"$CLAUDE_FILE_PATHS\""
10 }
11 ]
12 }
13 ]
14 }
15}

Typiske anvendelser: formatér efter hver redigering, kør typecheck før sessionen afsluttes, log alle bash-kommandoer til en revisionsfil, eller blokér redigering af bestemte filer helt.

Step 7: Claude Code i CI

Headless mode gør værktøjet brugbart i en pipeline. Her er en review-kommentar på hver pull request:

.github/workflows/review.ymlyaml
1name: AI review
2on: pull_request
3
4jobs:
5 review:
6 runs-on: ubuntu-latest
7 permissions:
8 contents: read
9 pull-requests: write
10 steps:
11 - uses: actions/checkout@v4
12 with:
13 fetch-depth: 0
14
15 - name: Installér Claude Code
16 run: npm install -g @anthropic-ai/claude-code
17
18 - name: Gennemgå diff
19 env:
20 ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
21 run: |
22 git diff origin/${{ github.base_ref }}...HEAD > /tmp/diff.txt
23 claude -p "Gennemgå denne diff. Rapportér kun konkrete fejl \
24 med filnavn og linjenummer. Ingen stilistiske noter." \
25 --allowedTools "Read Grep Glob" \
26 < /tmp/diff.txt > /tmp/review.md
27
28 - name: Kommentér
29 env:
30 GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31 run: gh pr comment ${{ github.event.number }} --body-file /tmp/review.md

--allowedTools er vigtig her. En CI-agent skal kunne læse og søge, ikke skrive og pushe. Giv den præcis de værktøjer opgaven kræver.

Når du vil bygge oven på det

Claude Code findes også som bibliotek — Claude Agent SDK — hvis du vil have den samme agent-løkke inde i din egen applikation frem for i en terminal. Det er et andet værktøj end tool runneren i Claude API, som kun kører de værktøjer du selv definerer. Grænsen går ved indbyggede værktøjer: Agent SDK'et har filadgang og bash med fra start, tool runneren har ingenting.

Skal du derimod bare kalde modellen direkte fra Python eller TypeScript, er guiden til Claude API startstedet.

Common pitfalls

  • Ingen git-historik. Agenten redigerer filer direkte. Uden commits har du ingen diff at kigge på, og ingen vej tilbage. Commit før du starter noget stort.
  • For stor CLAUDE.md. Den læses hver gang og koster tokens hver gang. Under 100 linjer er et fornuftigt mål.
  • Vage opgaver. "Ryd op i koden" giver tilfældige refaktoreringer. "Udtræk valideringen i handlers.ts til en ren funktion og skriv tests" giver det du bad om.
  • Blindt godkendte permissions. At sige ja til alt i to uger fjerner hele sikkerhedsnettet. Læg reglerne i settings.json i stedet, så de er eksplicitte og gennemgåede.
  • Én lang session til alt. Kontekstvinduet fyldes op med afsluttet arbejde. Start forfra mellem opgaver, eller læg afgrænsede opgaver ud til subagents.
  • Hemmeligheder i læserækkevidde. Sæt .env og nøglemapper på deny. Agenten læser hvad den kan komme til, og alt hvad den læser, ryger i konteksten.