Local Memory Stack (Qdrant + Nomic Embed)

August 20, 2026 · View on GitHub

This guide documents a lightweight local setup for mcp-probe-kit memory tools (search_memory, memorize_asset, read_memory_asset, update_memory_asset, delete_memory_asset, scan_and_extract_patterns):

  • Qdrant — vector database (port 50008)
  • Infinity (nomic-embed) — embedding API (port 50012), replaces Ollama for users who want a smaller footprint

Both services are typically deployed with Docker Compose under a shared docker-start layout. Ports use the 500xx convention to avoid conflicts.

ServiceHost portContainer portPurpose
Qdrant HTTP500086333REST API, dashboard
Qdrant gRPC500096334gRPC API
Nomic Embed (Infinity)500127997OpenAI-compatible embeddings

1. Qdrant

Service info

ItemValue
Imageqdrant/qdrant:latest
Container nameqdrant
HTTPhttp://127.0.0.1:50008
gRPC127.0.0.1:50009
Data./data/qdrant/storage
Snapshots./snapshots/qdrant/snapshots
AuthQDRANT_API_KEY in .env (header api-key)

docker-compose.yml

services:
  qdrant:
    image: qdrant/qdrant:latest
    container_name: qdrant
    restart: always
    env_file:
      - .env
    ports:
      - "50008:6333"
      - "50009:6334"
    volumes:
      - ./data:/qdrant/storage
      - ./snapshots:/qdrant/snapshots
    environment:
      - QDRANT__SERVICE__HTTP_PORT=6333
      - QDRANT__SERVICE__GRPC_PORT=6334
      - QDRANT__LOG_LEVEL=INFO
      - QDRANT__SERVICE__API_KEY=${QDRANT_API_KEY}
    healthcheck:
      test:
        - "CMD"
        - "bash"
        - "-c"
        - "exec 3<>/dev/tcp/127.0.0.1/6333 && printf 'GET /collections HTTP/1.1\r\nHost: localhost\r\napi-key: ${QDRANT_API_KEY}\r\nConnection: close\r\n\r\n' >&3 && IFS= read -r line <&3 && [[ \"$$line\" == *\"200\"* ]]"
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 30s

.env.example

# copy: cp .env.example .env
# generate key: python -c "import secrets; print(secrets.token_urlsafe(32))"

QDRANT_API_KEY=change-me-to-a-long-random-string
QDRANT_URL=http://127.0.0.1:50008

First deploy

cd qdrant
copy .env.example .env
# Edit .env — set a long random QDRANT_API_KEY
docker compose up -d

Verify

# Health / collections (requires api-key when API_KEY is enabled)
curl http://127.0.0.1:50008/collections \
  -H "api-key: YOUR_QDRANT_API_KEY"

# Web UI (enter the same key in the dashboard)
# http://127.0.0.1:50008/dashboard

Common commands

docker compose up -d          # start
docker compose down           # stop
docker compose logs -f qdrant # logs
docker compose restart qdrant # restart

Notes

  • After enabling QDRANT__SERVICE__API_KEY, all REST/gRPC requests must include header api-key.
  • mcp-probe-kit sends this via MEMORY_QDRANT_API_KEY.
  • Collection mcp_probe_memory is created automatically on first memorize_asset write (Cosine distance; vector size inferred from the first embedding).

2. Nomic Embed (Infinity)

Lightweight embedding server based on Infinity. Model: nomic-ai/nomic-embed-text-v1.5 (768 dimensions). No Ollama required.

Service info

ItemValue
Imagemichaelf34/infinity:0.0.70
Container namenomic-embed
Host port50012 → container 7997
Modelnomic-ai/nomic-embed-text-v1.5
Vector dim768
Enginetorch (CPU if no GPU)
AuthINFINITY_API_KEYAuthorization: Bearer <key>
Model cacheDocker volume hf_cache/app/.cache

docker-compose.yml

services:
  nomic-embed:
    image: michaelf34/infinity:0.0.70
    container_name: nomic-embed
    restart: unless-stopped
    ports:
      - "50012:7997"
    volumes:
      - hf_cache:/app/.cache
    environment:
      INFINITY_API_KEY: ${INFINITY_API_KEY}
    command:
      - v2
      - --model-id
      - nomic-ai/nomic-embed-text-v1.5
      - --revision
      - main
      - --dtype
      - float32
      - --batch-size
      - "8"
      - --engine
      - torch
      - --port
      - "7997"
      - --no-bettertransformer
    healthcheck:
      test:
        - "CMD"
        - "curl"
        - "-f"
        - "http://127.0.0.1:7997/health"
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 120s

volumes:
  hf_cache:

.env.example

INFINITY_API_KEY=change-me-to-a-long-random-string

First deploy

cd nomic-embed
copy .env.example .env
# Edit .env — set INFINITY_API_KEY (long random string)
docker compose up -d
docker logs -f nomic-embed   # wait for "ready to batch requests"

First start downloads the HuggingFace model (~2–5 minutes cold start).

Verify

curl http://127.0.0.1:50012/health

curl http://127.0.0.1:50012/models \
  -H "Authorization: Bearer YOUR_INFINITY_API_KEY"

# Important: path is /embeddings — NOT /v1/embeddings
curl http://127.0.0.1:50012/embeddings \
  -H "Authorization: Bearer YOUR_INFINITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"nomic-ai/nomic-embed-text-v1.5","input":"hello world"}'

Response: data[0].embedding is a 768-float array.

Swagger: http://127.0.0.1:50012/docs

Performance (CPU, indicative)

Scenario~Latency
Single short text (warm)30–50 ms
First request~150 ms
Batch 8~150 ms
Resident memory~1 GB

Suitable for MCP memory and occasional writes; not for high-concurrency bulk indexing.


3. mcp-probe-kit MCP configuration

Recommended: Qdrant on 50008 + Infinity on 50012 with openai-compatible provider.

{
  "mcpServers": {
    "mcp-probe-kit": {
      "command": "npx",
      "args": ["-y", "mcp-probe-kit@latest"],
      "env": {
        "MEMORY_QDRANT_URL": "http://127.0.0.1:50008",
        "MEMORY_QDRANT_API_KEY": "YOUR_QDRANT_API_KEY",
        "MEMORY_QDRANT_COLLECTION": "mcp_probe_memory",
        "MEMORY_EMBEDDING_PROVIDER": "openai-compatible",
        "MEMORY_EMBEDDING_URL": "http://127.0.0.1:50012/embeddings",
        "MEMORY_EMBEDDING_MODEL": "nomic-ai/nomic-embed-text-v1.5",
        "MEMORY_EMBEDDING_API_KEY": "YOUR_INFINITY_API_KEY",
        "MEMORY_SEARCH_LIMIT": "3",
        "MEMORY_SUMMARY_MAX_CHARS": "280"
      }
    }
  }
}

Claude Code: put the same keys under mcpServers.mcp-probe-kit.env in .mcp.json.

After changing env, fully restart your MCP client (e.g. quit and reopen Cursor).

CLI fallback (local.env)

If your host Agent cannot see the MCP tools and you use the project wrapper CLI fallback (./.mcp-probe-kit/bin/probe* exec ...), then the CLI process will not inherit IDE mcp.json env vars.

In that case, configure Memory via .mcp-probe-kit/local.env (created by install-agent): put the same MEMORY_* keys there.

Environment variable reference

VariableRequiredDescription
MEMORY_QDRANT_URLYes (read/write)Qdrant base URL, e.g. http://127.0.0.1:50008
MEMORY_QDRANT_API_KEYIf Qdrant auth enabledSent as api-key header
MEMORY_QDRANT_COLLECTIONNoDefault mcp_probe_memory
MEMORY_EMBEDDING_URLYes (write/search)e.g. http://127.0.0.1:50012/embeddings
MEMORY_EMBEDDING_MODELYes (write/search)nomic-ai/nomic-embed-text-v1.5
MEMORY_EMBEDDING_PROVIDERNoMust be openai-compatible for Infinity
MEMORY_EMBEDDING_API_KEYYes for InfinityBearer token = INFINITY_API_KEY
MEMORY_SEARCH_LIMITNoDefault 3
MEMORY_SEARCH_CONTENT_MAX_CHARSNoMax content chars in search_memory text; default 1500, 0 = summary only
MEMORY_SUMMARY_MAX_CHARSNoDefault 280

Tool vs environment

ToolMinimum env
read_memory_assetMEMORY_QDRANT_URL
delete_memory_assetMEMORY_QDRANT_URL
search_memoryQdrant + embedding (MEMORY_QDRANT_URL, MEMORY_EMBEDDING_URL, MEMORY_EMBEDDING_MODEL)
memorize_assetQdrant + embedding
update_memory_assetQdrant + embedding (content changes re-embed the point)
scan_and_extract_patternsNone (local scan; persist with memorize_asset)

4. End-to-end smoke test

# 1) Qdrant
curl -s http://127.0.0.1:50008/collections -H "api-key: YOUR_QDRANT_API_KEY"

# 2) Embedding
curl -s -X POST http://127.0.0.1:50012/embeddings \
  -H "Authorization: Bearer YOUR_INFINITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"nomic-ai/nomic-embed-text-v1.5","input":"mcp-probe-kit test"}' \
  | jq '.data[0].embedding | length'
# Expected: 768

Then in the IDE, call memorize_asset once, then read_memory_asset / update_memory_asset / delete_memory_asset or semantic search via orchestration tools.


5. Troubleshooting

SymptomFix
Qdrant 401Set MEMORY_QDRANT_API_KEY to match qdrant/.env
Embedding 401Use Authorization: Bearer + correct INFINITY_API_KEY
Embedding 404URL must be http://127.0.0.1:50012/embeddings, not /v1/embeddings
nomic-embed health stuck on startingFirst model download; check docker logs nomic-embed
Log No CUDA runtimeNormal on CPU
Dimension mismatch in QdrantCollection was created with another model; delete collection or use a new MEMORY_QDRANT_COLLECTION name
Memory write disabledEnsure all three are set: MEMORY_QDRANT_URL, MEMORY_EMBEDDING_URL, MEMORY_EMBEDDING_MODEL

6. Alternatives

StackWhen to use
Qdrant + Infinity (this guide)Default for local dev; lighter than Ollama
Qdrant + OllamaIf you already run Ollama for chat models
Qdrant + hosted OpenAI-compatible APINo local embedding container

See also README — Optional Memory System Setup.


中文说明: 同内容中文版见 memory-local-setup.zh-CN.md.