---
title: "Claude Context offline: Ollama, lokalny Milvus, zero ruchu na zewnątrz"
description: "Konfiguracja Claude Context bez OpenAI i bez Zilliz Cloud. Lokalne embeddingi przez Ollamę, Milvus w Dockerze, pełna prywatność kodu. Krok po kroku."
author: Maciej Olszewski
date: 2026-05-07
tags:
  - claude-code
  - ai
url: "https://inprojects.ai/blog/claude-code-context-offline/"
language: pl
---

# Claude Context offline: Ollama, lokalny Milvus, zero ruchu na zewnątrz

> Konfiguracja Claude Context bez OpenAI i bez Zilliz Cloud. Lokalne embeddingi przez Ollamę, Milvus w Dockerze, pełna prywatność kodu. Krok po kroku.

> Claude Context domyślnie kieruje cię do OpenAI za embeddingi i Zilliz Cloud jako magazyn wektorów. Dla firm z wymaganiami zgodności albo po prostu z awersją do wysyłania kodu na zewnątrz obie decyzje da się cofnąć. Tu opisuję pełną konfigurację offline: Ollama lokalnie, Milvus w Dockerze, żadnych kluczy API.

Wracamy do głównego artykułu: [Claude Code: jak przestać palić tokeny](https://inprojects.ai/blog/claude-code-oszczedzanie-tokenow/).

## Dlaczego offline

Kod, który indeksujesz Claude Contextem, idzie do modelu embeddingów. Domyślnie to OpenAI (`text-embedding-3-small` albo `-large`), który:

- Wysyła fragmenty twojego kodu poza sieć firmową
- Wymaga klucza API, który musi być rotowany
- Kosztuje (niedużo, ale notuje zużycie)
- Podlega polityce retencji OpenAI (30 dni logów domyślnie)

W wielu kontraktach (ochrona zdrowia, finanse, obronność, sektor publiczny) to wyklucza takie użycie. Konfiguracja offline rozwiązuje wszystkie cztery problemy naraz.

## Architektura stosu offline

```mermaid
graph LR
    A[Claude Code] -->|MCP| B[claude-context-mcp]
    B -->|embed request| C[Ollama localhost:11434]
    B -->|vector write/search| D[Milvus localhost:19530]
    C -->|nomic-embed-text| E[model file na dysku]
    D -->|pliki kolekcji| F[Docker volume]
```

Trzy komponenty, wszystkie lokalne. Ruch sieciowy zerowy (po jednorazowym pobraniu obrazu Dockera i modelu Ollama).

## Krok 1: Ollama i model embeddingów

### Instalacja

```bash
# macOS:
brew install ollama
brew services start ollama

# Linux:
curl -fsSL https://ollama.com/install.sh | sh
systemctl --user enable --now ollama

# Weryfikacja:
curl http://localhost:11434/api/tags
# powinno zwrócić {"models": []}
```

### Wybór modelu

Ollama udostępnia kilka modeli embeddingów. Dla Claude Context polecane:

| Model | Wymiar | Rozmiar | Jakość | Komenda pull |
|-------|-------:|--------:|--------|--------------|
| `nomic-embed-text` | 768 | 274 MB | dobra | `ollama pull nomic-embed-text` |
| `mxbai-embed-large` | 1024 | 670 MB | bardzo dobra | `ollama pull mxbai-embed-large` |
| `bge-m3` | 1024 | 1,2 GB | flagowa | `ollama pull bge-m3` |

Domyślnie wybieram `nomic-embed-text`: najlepszy kompromis między jakością a rozmiarem, mieści się w <300 MB. `mxbai-embed-large` bierzesz, gdy masz dużą bazę kodu (>10k plików) i zależy ci na semantyce.

```bash
ollama pull nomic-embed-text

# Weryfikacja że działa:
curl http://localhost:11434/api/embed \
  -d '{"model": "nomic-embed-text", "input": "test embedding"}'
# powinno zwrócić {"embeddings": ...768 liczb...}
```

## Krok 2: Milvus w Dockerze

Milvus to ten sam silnik co w Zilliz Cloud, tylko lokalnie. Najprostsza konfiguracja to tryb standalone przez `docker-compose`.

### Pobranie i uruchomienie

```bash
mkdir -p ~/milvus && cd ~/milvus
curl -L https://github.com/milvus-io/milvus/releases/download/v2.4.15/milvus-standalone-docker-compose.yml -o docker-compose.yml
docker compose up -d
```

Standalone startuje trzy kontenery: `milvus-standalone`, `milvus-etcd`, `milvus-minio`. Razem ~2 GB pamięci w spoczynku, ~500 MB dysku per 100k embeddingów.

### Weryfikacja

```bash
# Health check:
curl http://localhost:9091/healthz
# powinno zwrócić 200 OK

# Port 19530: główne API gRPC
docker compose ps
# wszystkie trzy powinny być (healthy)
```

### Utrwalenie danych

Domyślny `docker-compose.yml` zapisuje dane w wolumenie. Jeśli skasujesz kontenery, dane zostają. Jeśli chcesz reset:

```bash
docker compose down -v    # -v usuwa też volumes
```

## Krok 3: Claude Context z lokalnym backendem

### Instalacja

```bash
claude mcp add claude-context \
  -e EMBEDDING_PROVIDER=ollama \
  -e EMBEDDING_MODEL=nomic-embed-text \
  -e OLLAMA_HOST=http://localhost:11434 \
  -e MILVUS_ADDRESS=localhost:19530 \
  -e MILVUS_TOKEN= \
  -e HYBRID_MODE=true \
  -- npx @zilliz/claude-context-mcp@latest
```

Najważniejsze zmienne:

- `EMBEDDING_PROVIDER=ollama` wyłącza domyślne OpenAI
- `EMBEDDING_MODEL=nomic-embed-text` musi wskazywać model, który ściągnął `ollama pull`
- `OLLAMA_HOST` to domyślnie `http://localhost:11434`, ale lepiej ustawić jawnie
- `MILVUS_ADDRESS=localhost:19530` to lokalny port Milvusa
- `MILVUS_TOKEN=` zostaje **pusty** (lokalny Milvus nie wymaga tokena)
- `HYBRID_MODE=true` włącza BM25 + wyszukiwanie wektorowe zamiast samego wektorowego

### Globalna konfiguracja (alternatywa)

Zmienne można trzymać w `~/.context/.env` zamiast w linii komend:

```bash
EMBEDDING_PROVIDER=ollama
EMBEDDING_MODEL=nomic-embed-text
OLLAMA_HOST=http://localhost:11434
MILVUS_ADDRESS=localhost:19530
MILVUS_TOKEN=
HYBRID_MODE=true
CUSTOM_IGNORE_PATTERNS=node_modules,dist,build,.planning,archives,.next,target
SPLITTER_TYPE=ast
```

`CUSTOM_IGNORE_PATTERNS` jest ważne, bo domyślnie Claude Context indeksuje wszystko. Wyklucz katalogi, które nie mają wartości semantycznej (artefakty builda, cache, archiwa).

## Krok 4: pierwsze indeksowanie

W sesji Claude Code:

> Zaindeksuj tę bazę kodu używając claude-context.

Claude wywoła `index_codebase` przez MCP. W zależności od wielkości repo to od kilku minut do pół godziny. Postęp można śledzić:

```bash
# W drugim terminalu:
docker compose -f ~/milvus/docker-compose.yml logs -f milvus-standalone | grep -i "inserted"
```

Dla porównania: 5000 plików TypeScript indeksuje się u mnie ~8 minut na M2, głównie w oczekiwaniu na Ollamę (wąskim gardłem jest embedding, nie Milvus).

Po zakończeniu weryfikacja:

> Jaki jest status indeksowania?

Albo bezpośredni test:

> Znajdź funkcje, które obsługują uwierzytelnianie użytkownika.

Jeśli semantyka działa, zwróci trafne fragmenty kodu bez czytania plików. To ten moment, kiedy widzisz oszczędność tokenów w akcji.

## Rozwiązywanie problemów

### `DEADLINE_EXCEEDED` na gRPC

Najczęściej w trybie Zilliz Cloud Free tier (mamy opcję offline, więc nie dotyczy). Ale jeśli trafisz na to lokalnie, Milvus nie wstał do końca. Sprawdź:

```bash
docker compose logs milvus-standalone | tail -50
```

Typowa przyczyna: kontener jeszcze się inicjalizuje (pierwszy start trwa do 2 minut). Odczekaj.

### Osierocone pliki merkle

Drzewa Merkle służą do przyrostowego reindeksowania. Jeśli skasujesz kolekcję w Milvusie ręcznie, zostają puste pliki śledzące. Rozwiązanie:

```bash
rm -rf ~/.context/merkle/<nazwa-projektu>/
# w sesji Claude:
# "Zaindeksuj tę bazę kodu od zera"
```

### Przekroczony czas odpowiedzi Ollamy podczas indeksowania

Duże pliki (>100 KB) bywają za ciężkie dla Ollamy w jednym żądaniu. W `~/.context/.env`:

```bash
SPLITTER_MAX_CHUNK_SIZE=2000
SPLITTER_CHUNK_OVERLAP=200
```

To wymusza mniejsze fragmenty (2000 znaków z zakładką 200). Ollama radzi sobie z tym od ręki.

### Niekompatybilny Node.js

Claude Context wymaga **Node.js 20.x lub 22.x**. **Nie 24.0.0+**, bo pakiet `@zilliz/claude-context-mcp` nie kompiluje się na 24. Jeśli masz `nvm`:

```bash
nvm install 22
nvm use 22
claude mcp add ...   # świeża rejestracja
```

## Benchmark jakości: offline a OpenAI

Claude Context oficjalnie benchmarkował konfigurację z OpenAI. Z Ollamą `nomic-embed-text` otrzymasz:

- F1 wyszukiwania niższe o ~5-10% (ale wciąż w użytecznym zakresie)
- Embeddingi szybsze lokalnie (brak dodatkowego opóźnienia sieciowego)
- Dłuższy zimny start (pierwszy embedding ~2 s na Apple Silicon, potem ~50-100 ms)

Dla większości zastosowań różnica jakości jest niezauważalna. Jeśli widzisz, że Claude często nie znajduje funkcji, które powinien, przesiądź się na `mxbai-embed-large`. To wyraźnie lepszy model, kosztem 670 MB dysku.

## Monitorowanie i konserwacja

### Miejsce na dysku

Lokalny Milvus zapisuje dane w `~/milvus/volumes/` (domyślnie). Dla średniego projektu:

- 1000 plików ≈ 50 MB
- 10 000 plików ≈ 500 MB  
- 100 000 plików ≈ 5 GB

Sprawdzenie:

```bash
du -sh ~/milvus/volumes/
```

### Czyszczenie starych kolekcji

Każdy projekt ma osobną kolekcję. Jeśli skończyłeś pracę z jakimś repo:

```bash
docker exec milvus-standalone attu-cli --help
# lub wejście do Python API:
python -c "from pymilvus import connections, utility; connections.connect('default', host='localhost', port='19530'); print(utility.list_collections())"
```

### Aktualizacje Ollamy i modeli

```bash
ollama pull nomic-embed-text    # zaktualizuje jeśli jest nowsza wersja
brew upgrade ollama              # update samej Ollamy
```

Po aktualizacji modelu trzeba reindeksować, bo stare embeddingi nie są zgodne z nową wersją (inna skala, często inny wymiar).

## Kiedy ta konfiguracja się nie opłaca

Offline ma koszt stały:

- ~2 GB RAM dla Milvusa
- ~300 MB-1 GB dla Ollamy (zależnie od modelu)
- Docker Desktop / Docker Engine

Jeśli pracujesz na małym projekcie (<500 plików), hobbystycznie, bez wymagań zgodności, to prostsza konfiguracja z OpenAI + Zilliz Cloud Free tier działa od razu, w 2 minuty, i kosztuje cię ~$0 miesięcznie. Offline to decyzja dla kontekstu firmowego albo mocnego przywiązania do prywatności.

---

Wracając do głównego artykułu: [Claude Code: jak przestać palić tokeny](https://inprojects.ai/blog/claude-code-oszczedzanie-tokenow/). Dla terminala zamiast bazy kodu: [RTK: pełna konfiguracja](https://inprojects.ai/blog/claude-code-rtk-konfiguracja/).
