Files
context-kit/docs/troubleshooting.md
Ajay Krishnan 51dceee224 Overhaul docs retrieval and web search quality
Replace the abandoned llms-txt-mcp/Chroma docs backend with an in-repo
MCP service: SQLite WAL + FTS5 + sentence-transformer embeddings,
transactional source replacement, persisted state across restarts,
singleflight refresh with conditional requests, hybrid lexical/semantic
ranking with exact-duplicate collapse, source/host filters, and
explicit-by-default content retrieval. Add docs_rebuild and a
docs-rebuild CLI command.

Add deterministic llms-full.txt snapshot generation for machine-local
menus with hash-validated provenance manifests; lifecycle commands
promote a local menu to its snapshot only when the manifest validates.
Switch public source profiles to content-bearing llms-full.txt feeds.

Improve web search: bounded provider fallback with per-attempt
diagnostics and cancellation, an optional Brave Search API provider,
strict SearXNG engine selection, capped link/media extraction, and a
real engine=browser renderer that routes every request through the
existing SSRF vetting while blocking WebSockets, non-GET traffic, and
private destinations.

Extend release checks with offline unit suites and isolated candidate
container tests for both images.
2026-07-25 08:49:26 -07:00

185 lines
6.2 KiB
Markdown

# Troubleshooting
## Run Doctor
```sh
bin/context-kit doctor
```
This checks Docker, Compose, images, the Docker network, SearXNG health, a real
web-search MCP initialize/tools-list exchange, docs HTTP readiness, and docs
source configuration.
For release-grade MCP protocol checks, run:
```sh
scripts/release-check
```
Live provider checks are opt-in because search engines, remote docs, and model
downloads can fail independently of this repo:
```sh
CONTEXT_KIT_LIVE_CHECKS=1 scripts/release-check
```
## SearXNG Is Not Responding
Start it:
```sh
bin/context-kit start
```
Then check:
```sh
curl 'http://127.0.0.1:8099/search?q=test&format=json'
```
If you changed `CONTEXT_KIT_SEARXNG_PORT`, use that port instead.
## MCP Image Missing
Build default images:
```sh
bin/context-kit build
```
## Repeated Per-Project Containers
Current OpenCode and Claude snippets connect web search and docs directly to the
shared HTTP services. If every project still starts a web-search container,
regenerate the snippet, update the assistant configuration, and restart the
assistant:
```sh
bin/context-kit install opencode
bin/context-kit install claude
```
For the upgrade from `origin/main`, build and start once. `start` creates only
the missing web-search service and refuses to recreate existing services:
```sh
bin/context-kit build
bin/context-kit start
```
Context Kit never performs a global Docker prune. Inspect labeled resources and
their owners explicitly:
```sh
docker ps -a --filter label=dev.context-kit=true \
--format 'table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Label "dev.context-kit.lifecycle"}}\t{{.Label "dev.context-kit.owner"}}\t{{.Label "com.docker.compose.service"}}'
```
Containers from the old per-call web-search launcher have an empty Compose
service and no lifecycle/owner labels. After all old assistant processes are
stopped, remove only the exact legacy container IDs you verified; do not use a
name-pattern or global prune.
Lifecycle commands for one Compose project use a canonical, uid-owned lock and
reject cross-user control. Failed startup removes only newly-created service
containers, restores existing container states by ID, and never removes the
network or cache volume. `start` uses Compose `--no-recreate`, leaving an
existing container unchanged when its image or environment differs from the
current Compose model; it never silently replaces that container. Inspect the
shared services without deleting them:
```sh
bin/context-kit status
docker compose -p "${CONTEXT_KIT_COMPOSE_PROJECT:-context-kit}" -f compose.yml logs web-search-mcp docs-mcp searxng
```
Use the protocol-level doctor check. `/healthz` also performs initialize and
tools/list rather than trusting the proxy's static `/status` metadata:
```sh
bin/context-kit doctor
curl http://127.0.0.1:8777/healthz
```
`bin/context-kit status` lists legacy labeled containers that have neither a
Compose service nor lifecycle label. This is diagnostic only; Context Kit never
auto-removes them. Stop their old assistant owners before removing individually
verified container IDs.
## Fetch URL Says Max Download Bytes Is Too Big
If `fetch_url` fails before making a network request with an MCP validation error
like `Number must be less than or equal to 26214400`, rebuild the web-search MCP
image:
```sh
bin/context-kit build
```
Context Kit patches the upstream `mcp-web-search` schema so the accepted
`max_download_bytes` value matches `CONTEXT_KIT_WEB_SEARCH_MAX_BYTES`, which
defaults to `52428800`.
## Search Fallback and Chromium
`search_web` defaults to SearXNG. If SearXNG fails or returns no results, the
upstream fallback order is DuckDuckGo, then Bing. Bing uses Chromium through
Puppeteer, so `bin/context-kit doctor` checks that the configured Chromium path
exists inside the web-search image.
Context Kit carries a source-controlled Bing provider override in
`docker/web-search/overrides/bing.js` because the upstream 1.3.0 provider can
race result rendering and return no items even when Chromium sees Bing result
cards. The override waits for result cards and decodes current Bing redirect
URLs before handing results back to the upstream fallback registry.
`search_web` now returns bounded `diagnostics.attempts` entries. Check each
provider's `status`, `duration_ms`, `result_count`, and categorized error before
changing provider order. An optional Brave API fallback is enabled only when
`CONTEXT_KIT_BRAVE_SEARCH_API_KEY` is set.
`fetch_url engine=browser` invokes Chromium for JavaScript-rendered pages. Every
HTTP(S) GET is intercepted and fetched through vetted DNS addresses; non-GET
requests, private/localhost destinations, more than 100 requests, and more than
20 MiB total browser traffic are blocked. Use `engine=http` for ordinary pages.
## Docs Indexing Is Slow
The first `docs_query` or `docs_refresh` downloads an embedding model and
embeds the requested docs sections lazily. Keep default sources small, and add
profiles only when you need them.
Cloudflare and other large docs sets can take significantly longer than the
default source profile. Set `CONTEXT_KIT_DOCS_PREINDEX=1` only if you want
startup to eagerly embed every configured source.
## Docs Sources Report Refresh Errors
If `docs_sources` reports `last_error`, the service keeps the previous generation
searchable and records the failed check. Check the container logs:
```sh
docker compose -p "${CONTEXT_KIT_COMPOSE_PROJECT:-context-kit}" -f compose.yml logs docs-mcp
```
A common cause is Docker creating the bind-mounted cache directories as `root`
before Context Kit created them as the host user. Look for errors like:
```text
Permission denied: '/models/models--BAAI--bge-small-en-v1.5'
unable to open database file
```
Fix ownership and restart:
```sh
DATA_DIR="${CONTEXT_KIT_DATA_DIR:-${HOME:?Set HOME or CONTEXT_KIT_DATA_DIR}/.local/share/context-kit}"
sudo chown -R "$(id -u):$(id -g)" "$DATA_DIR/docs" "$DATA_DIR/models"
bin/context-kit restart
```
`bin/context-kit start` pre-creates these directories and `doctor` reports
existing directories that are not writable by the current user. The docs MCP
uses stateless HTTP sessions, so clients do not retain a session ID across calls.
Use `bin/context-kit docs-rebuild` after fixing the underlying error.