원클릭으로
add-claude-context
[DEPRECATED] Replaced by scripts/code_search.py (native sqlite-vec + Ollama). Do not use.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
[DEPRECATED] Replaced by scripts/code_search.py (native sqlite-vec + Ollama). Do not use.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Save this session to the vault and update the semantic memory index
Capture a repeatable task procedure from the just-completed work as a durable, queryable memory node, so the steps are recalled automatically next time instead of re-derived. Triggers on "learn this procedure", "remember how to do this", "save this as a procedure", "/learn-procedure".
Add Asana project management MCP integration to Deus. Gives host-side Claude Code sessions read/write access to Asana tasks, projects, sections, and tags via @roychri/mcp-server-asana.
Add OpenAI/Codex as a backend. Guides through API key setup, service backend configuration, optional CLI setup, and verification. Can run alongside Claude (default) or replace it.
Add /compact command for manual context compaction. Solves context rot in long sessions by forwarding the SDK's built-in /compact slash command. Main-group or trusted sender only.
Add Discord bot channel integration to Deus.
| name | add-claude-context |
| description | [DEPRECATED] Replaced by scripts/code_search.py (native sqlite-vec + Ollama). Do not use. |
| disable-model-invocation | true |
This skill is deprecated. claude-context (Milvus-based) was evaluated and found to have never worked due to 5 cascading bugs (wrong config path, corrupt npx cache, wrong protocol, broken network isolation, short timeout). Milvus is also massive overkill for code search at any realistic codebase scale.
Replacement:
scripts/code_search.py-- native semantic code search using sqlite-vec + Ollama embeddings + RRF fusion, following thememory_tree.pypattern. No Docker, no Milvus, no external dependencies beyond Ollama.
The content below is preserved for historical reference only.
This skill adds semantic code search to Claude Code via the claude-context MCP server by Zilliz. Once installed, Claude can index any codebase and search it by meaning — not just keyword matching.
Tools added:
index_codebase — index a directory into the vector databasesearch_code — semantic search across indexed codeget_indexing_status — check indexing progressclear_index — remove an indexPrivacy: All data stays local. Embeddings via Ollama, vectors in a network-isolated Docker Milvus container. No cloud APIs, no telemetry. See Security for the full defense-in-depth breakdown.
grep -q "claude-context" ~/.claude/mcp.json 2>/dev/null && echo "INSTALLED" || echo "NOT_INSTALLED"
If already installed, skip to Phase 5 (Verify).
Docker:
docker info > /dev/null 2>&1 && echo "Docker OK" || echo "Docker not running"
If Docker is not running, tell the user to start Docker Desktop (macOS) or the Docker daemon (Linux).
Ollama:
ollama list > /dev/null 2>&1 && echo "Ollama OK" || echo "Ollama not running"
If Ollama is not installed, direct the user to https://ollama.com/download.
Node.js version:
node --version
Must be >= 20 and < 24. Node 24 is incompatible with claude-context. If the version is wrong, tell the user which versions are supported.
ollama list 2>/dev/null | grep -i embed
If embedding models are found, ask the user which one to use via AskUserQuestion.
If no embedding models are found, suggest pulling one:
No embedding models found in Ollama. You need one for code search. Options:
- nomic-embed-text (768-dim, 274MB) — lightweight, recommended for most use cases
- mxbai-embed-large (1024-dim, 669MB) — higher quality embeddings
- snowflake-arctic-embed2 (1024-dim, 1.2GB) — multilingual support
Pull the chosen model:
ollama pull <model-name>
Get the dimension from a test embedding call — never hardcode this value:
curl -s http://127.0.0.1:11434/api/embed -d '{"model":"<model-name>","input":"test"}' | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d['embeddings'][0]))"
Store the model name and dimension for Phase 4.
docker ps --filter "name=deus-milvus" --format "{{.Status}}" 2>/dev/null
If deus-milvus is already running and healthy, skip to Phase 4:
docker exec deus-milvus curl -sf http://localhost:9091/healthz > /dev/null 2>&1 && echo "HEALTHY" || echo "NOT_HEALTHY"
Create the Milvus config directory:
mkdir -p ~/.config/deus/milvus
Create ~/.config/deus/milvus/embedEtcd.yaml:
cat > ~/.config/deus/milvus/embedEtcd.yaml << 'EOF'
listen-client-urls: http://0.0.0.0:2379
advertise-client-urls: http://0.0.0.0:2379
quota-backend-bytes: 4294967296
auto-compaction-mode: revision
auto-compaction-retention: "1000"
EOF
Create ~/.config/deus/milvus/user.yaml (required mount, no overrides needed):
touch ~/.config/deus/milvus/user.yaml
Create ~/.config/deus/milvus/start-milvus.sh:
cat > ~/.config/deus/milvus/start-milvus.sh << 'SCRIPT'
#!/bin/bash
set -euo pipefail
CONTAINER=deus-milvus
INTERNAL_NET=deus-milvus-net
BRIDGE_NET=deus-milvus-bridge
# Create networks if missing
docker network create --internal "$INTERNAL_NET" 2>/dev/null || true
docker network create "$BRIDGE_NET" 2>/dev/null || true
# If container exists but stopped, remove it (clean restart with correct config)
if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER}$"; then
if docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER}$"; then
echo "deus-milvus already running"
exit 0
fi
docker rm "$CONTAINER"
fi
# Start on bridge network (port publishing requires a non-internal network at creation time)
docker run -d --name "$CONTAINER" \
--network "$BRIDGE_NET" \
--restart no \
--security-opt seccomp:unconfined \
-e ETCD_USE_EMBED=true \
-e ETCD_DATA_DIR=/var/lib/milvus/etcd \
-e ETCD_CONFIG_PATH=/milvus/configs/embedEtcd.yaml \
-e COMMON_STORAGETYPE=local \
-e DEPLOY_MODE=STANDALONE \
--memory=3g --memory-swap=3g --cpus=2 \
-p 127.0.0.1:19530:19530 \
-v deus-milvus-data:/var/lib/milvus \
-v "$HOME/.config/deus/milvus/embedEtcd.yaml:/milvus/configs/embedEtcd.yaml:ro" \
-v "$HOME/.config/deus/milvus/user.yaml:/milvus/configs/user.yaml:ro" \
milvusdb/milvus:latest \
milvus run standalone
# Wait for Milvus to be healthy before switching networks
HEALTHY=false
for i in $(seq 1 60); do
docker exec "$CONTAINER" curl -sf http://localhost:9091/healthz >/dev/null 2>&1 && HEALTHY=true && break
sleep 2
done
if [ "$HEALTHY" != "true" ]; then
echo "ERROR: Milvus did not become healthy after 120s"
echo "Run: docker logs $CONTAINER --tail 50"
exit 1
fi
# Switch to internal network (blocks all outbound internet)
docker network connect "$INTERNAL_NET" "$CONTAINER" || { echo "ERROR: failed to connect internal network"; exit 1; }
docker network disconnect "$BRIDGE_NET" "$CONTAINER" || { echo "ERROR: failed to disconnect bridge network"; exit 1; }
# Verify isolation — hard abort if outbound is reachable
if docker exec "$CONTAINER" curl -sf --connect-timeout 3 http://1.1.1.1 >/dev/null 2>&1; then
echo "ABORT: outbound internet still reachable after network switch"
exit 1
fi
echo "Network isolation confirmed"
SCRIPT
chmod +x ~/.config/deus/milvus/start-milvus.sh
Why the network dance? Docker Desktop for Mac's --internal network blocks port publishing — the Docker proxy can't route traffic to containers on internal-only networks. The startup script creates the container on a regular bridge (port publishing works), waits for health, then switches to the internal network (blocks outbound). This survives restarts because the LaunchAgent/systemd unit replays the full sequence.
Why seccomp:unconfined? Milvus v2.6 uses clone3() and io_uring syscalls that the Docker default seccomp profile blocks. Without this flag, Milvus crashes on startup.
Why --restart no? The service manager (LaunchAgent/systemd) owns the lifecycle, not Docker. This ensures the network dance runs on every start.
Resource limits: --memory=3g --cpus=2 prevents Milvus from consuming all host RAM during indexing. Users with more RAM can increase these values in the script.
bash ~/.config/deus/milvus/start-milvus.sh
macOS — LaunchAgent:
cat > ~/Library/LaunchAgents/com.deus.milvus.plist << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.deus.milvus</string>
<key>ProgramArguments</key>
<array>
<string>bash</string>
<string>$HOME/.config/deus/milvus/start-milvus.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<false/>
<key>StandardOutPath</key>
<string>$HOME/Library/Logs/deus-milvus.log</string>
<key>StandardErrorPath</key>
<string>$HOME/Library/Logs/deus-milvus.error.log</string>
</dict>
</plist>
EOF
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.deus.milvus.plist
Note: The heredoc uses << EOF (not << 'EOF') so $HOME expands to the absolute path. launchd does not expand ~ in plist values.
Linux — systemd user unit:
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/deus-milvus.service << 'EOF'
[Unit]
Description=Deus Milvus (semantic code search)
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=%h/.config/deus/milvus/start-milvus.sh
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=default.target
EOF
systemctl --user enable --now deus-milvus.service
Before writing MCP config, verify these invariants. Abort if any check fails — do not proceed with a warning.
Check 1 — No MILVUS_TOKEN:
[ -n "$MILVUS_TOKEN" ] && echo "ABORT: MILVUS_TOKEN is set. This causes data to be sent to Zilliz Cloud. Run: unset MILVUS_TOKEN" && exit 1 || echo "OK"
If MILVUS_TOKEN is set, tell the user to unset it and stop. Do NOT write the MCP config.
Check 2 — MILVUS_ADDRESS is localhost:
The config being written must set MILVUS_ADDRESS to exactly 127.0.0.1:19530. Never omit this field — without it, the SDK may auto-provision a Zilliz Cloud cluster if MILVUS_TOKEN is set in the future.
Read ~/.claude/mcp.json and merge the new claude-context entry. Never overwrite existing servers.
The final entry should be:
{
"claude-context": {
"command": "npx",
"args": ["-y", "@zilliz/claude-context-mcp@0.1.13"],
"env": {
"EMBEDDING_PROVIDER": "Ollama",
"OLLAMA_HOST": "http://127.0.0.1:11434",
"OLLAMA_MODEL": "<detected-model>",
"EMBEDDING_MODEL": "<detected-model>",
"EMBEDDING_DIMENSION": "<detected-dimension>",
"EMBEDDING_BATCH_SIZE": "5",
"MILVUS_ADDRESS": "127.0.0.1:19530",
"HYBRID_MODE": "false"
}
}
}
Replace <detected-model> and <detected-dimension> with the values from Phase 2.
Configuration notes:
EMBEDDING_BATCH_SIZE=5 is a conservative default to avoid OOM with local models. Users with more RAM can increase this.HYBRID_MODE=false disables sparse vector (BM25) search which has reported instability with Milvus standalone. Dense search with the MCP's own reranking is sufficient. Set to true to experiment.MILVUS_ADDRESS must always be set explicitly — omitting it while a MILVUS_TOKEN is present would trigger calls to Zilliz Cloud.~/.claude/mcp.json), making code search available across all projects.Port 9091 is the Milvus management HTTP API (healthz). Port 19530 is the gRPC data port (used by the MCP server). Both must be working.
docker exec deus-milvus curl -sf http://localhost:9091/healthz && echo "Milvus healthy"
python3 -c "import socket; s=socket.socket(); s.settimeout(3); r=s.connect_ex(('127.0.0.1',19530)); print('Port 19530: OK' if r==0 else 'Port 19530: FAIL'); s.close()"
docker exec deus-milvus curl -sf --connect-timeout 3 http://1.1.1.1 2>&1 && echo "WARNING: outbound internet reachable" || echo "Isolation confirmed — no outbound internet"
This command must fail. If it succeeds, the network switch in start-milvus.sh did not complete — re-run the script.
Tell the user:
Claude Context is now installed. To use it, start a new Claude Code session and try:
- Index a codebase: the agent will use
index_codebasewith a directory path- Search: ask something like "find the function that handles message routing"
- The agent uses
search_codeto find semantically relevant codeFirst-time indexing may take a few minutes depending on codebase size.
To verify no data leaves your machine during indexing, run in a separate terminal:
lsof -i -P | grep nodeYou should only see connections to
127.0.0.1:19530(Milvus) and127.0.0.1:11434(Ollama).
Defense in depth — what prevents data leakage:
| Layer | Mechanism |
|---|---|
| Embeddings | EMBEDDING_PROVIDER=Ollama — computed locally, never sent to cloud |
| Vector DB address | MILVUS_ADDRESS=127.0.0.1:19530 — always set explicitly, prevents Zilliz Cloud auto-provisioning |
| Cloud token | No MILVUS_TOKEN — hard gate enforced by skill (abort, not warn) |
| Storage | COMMON_STORAGETYPE=local — vectors on local filesystem, no S3/MinIO |
| Port binding | 127.0.0.1 only — not accessible from LAN |
| Network isolation | --internal Docker network — blocks all outbound internet from container |
| Resource limits | --memory=3g --cpus=2 — prevents resource exhaustion on shared machines |
MCP trust boundary: The claude-context MCP server runs on the host as the user — it has unrestricted filesystem read access. It is not sandboxed. Only index directories you trust; avoid indexing paths containing secrets (.env, .aws/, .ssh/, ~/.config/). Embeddings of cleartext secrets would persist in the unencrypted Milvus volume.
Supply chain: The top-level npm package is pinned to @0.1.13, but transitive dependencies are resolved at npx time without a lockfile. The --internal Docker network mitigates container-side supply chain risk; the MCP server's npm tree is the remaining surface.
Known limitation: Between container start and the network switch (a few seconds during startup), the container is on the bridge network and theoretically has outbound access. The bridge-first approach is required because Docker Desktop for Mac cannot publish ports on --internal or --network none networks. In practice, Milvus doesn't make outbound calls during this window — it's initializing etcd and internal services. The startup script applies isolation as soon as healthz returns OK.
lsof -i :19530docker infodocker logs deus-milvus --tail 50docker rm -f deus-milvus
bash ~/.config/deus/milvus/start-milvus.sh
DEPLOY_MODE=STANDALONE is missing. The startup script sets this automatically. If running Docker manually, add -e DEPLOY_MODE=STANDALONE to your docker run command.
ETCD_USE_EMBED=true and the config file mounts are missing. The startup script handles this. If running manually, add:
-e ETCD_USE_EMBED=true-e ETCD_DATA_DIR=/var/lib/milvus/etcd-e ETCD_CONFIG_PATH=/milvus/configs/embedEtcd.yaml-v ~/.config/deus/milvus/embedEtcd.yaml:/milvus/configs/embedEtcd.yaml:rodocker ps --filter "name=deus-milvus"docker exec deus-milvus curl -sf http://localhost:9091/healthzpython3 -c "import socket; s=socket.socket(); s.settimeout(3); r=s.connect_ex(('127.0.0.1',19530)); print('open' if r==0 else 'closed'); s.close()"bash ~/.config/deus/milvus/start-milvus.shMILVUS_ADDRESS in ~/.claude/mcp.json is 127.0.0.1:19530The LaunchAgent (macOS) or systemd unit (Linux) should handle restarts automatically. Check logs:
cat ~/Library/Logs/deus-milvus.error.logjournalctl --user -u deus-milvus.serviceIf the service manager isn't running, start manually: bash ~/.config/deus/milvus/start-milvus.sh
If you see errors about dimension mismatch, the EMBEDDING_DIMENSION in ~/.claude/mcp.json doesn't match your model's output. Re-detect:
curl -s http://127.0.0.1:11434/api/embed -d '{"model":"<your-model>","input":"test"}' | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d['embeddings'][0]))"
Update EMBEDDING_DIMENSION in ~/.claude/mcp.json to match. This is a known upstream issue (claude-context #235) — auto-detection fails in the background indexer.
claude-context requires Node 20 or 22. Node 24 is not supported. Check your version with node --version and switch if needed (e.g., via nvm use 22).
If you installed from an earlier version of this skill (before the Docker fix), your container may have --restart unless-stopped and be missing config mounts. Run:
docker stop deus-milvus && docker rm deus-milvus
bash ~/.config/deus/milvus/start-milvus.sh
The named volume deus-milvus-data is preserved — no indexed data is lost.
If you removed the Milvus volume (docker volume rm deus-milvus-data), all indexed data is gone. Re-index by asking Claude to run index_codebase again on your project directories.
To completely remove claude-context:
Remove from MCP config:
# Edit ~/.claude/mcp.json and remove the "claude-context" key from mcpServers
Stop and remove Milvus:
docker stop deus-milvus && docker rm deus-milvus
Remove the Docker volume (warning: destroys all indexed codebase data — re-indexing required after reinstall):
docker volume rm deus-milvus-data
Remove Docker networks:
docker network rm deus-milvus-net deus-milvus-bridge 2>/dev/null
Remove config files:
rm -rf ~/.config/deus/milvus/
Remove service manager:
macOS:
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.deus.milvus.plist
rm ~/Library/LaunchAgents/com.deus.milvus.plist
rm -f ~/Library/Logs/deus-milvus.log ~/Library/Logs/deus-milvus.error.log
Linux:
systemctl --user disable --now deus-milvus.service
rm ~/.config/systemd/user/deus-milvus.service
Audited: 2026-05-23. Milvus 2.6 has no configurable telemetry opt-out - network isolation is sufficient.
Searched the milvus-io/milvus repo for: telemetry, analytics, phoneHome, usageReport, pingHome. All GitHub code search queries returned 0 results.
The repo contains internal/rootcoord/telemetry/ but it is internal cluster telemetry only - client SDK metrics (request counts, error rates, SDK versions) stored in etcd for cluster-internal monitoring. No data is transmitted to external services:
manager.go: stores client metrics in-memory + etcd; pull-based (not push); no external HTTP callscommand_store.go: writes only to etcd (internal); no Zilliz/external endpointsconfigs/milvus.yaml: no telemetry, analytics, or phone-home keys presentbuild/docker/milvus/ubuntu22.04/Dockerfile): no telemetry ENV vars; entrypoint is /tini --MINIO_REGION, ETCD_ENDPOINTS, MINIO_ADDRESSGitHub code search for telemetry in milvus-io/pymilvus: 0 results. No external reporting found.
GitHub code search for telemetry in milvus-io/milvus-sdk-node: 0 results. No external reporting found.
No configurable telemetry opt-out keys exist because Milvus 2.6 does not phone home. The --internal Docker network isolation applied in Phase 3 is the complete mitigation. No user.yaml overrides are needed for telemetry suppression - ~/.config/deus/milvus/user.yaml is mounted empty (as a required mount point) and should remain so.