Fix docs-mcp cache directory ownership checks

This commit is contained in:
2026-06-08 15:33:44 -07:00
parent 6629a9b284
commit 6a4d8673d1
2 changed files with 67 additions and 1 deletions

View File

@@ -41,6 +41,8 @@ DOCS_PORT="${CONTEXT_KIT_DOCS_PORT:-8776}"
DOCS_HTTP_URL="${CONTEXT_KIT_DOCS_HTTP_URL:-http://127.0.0.1:${DOCS_PORT}/mcp}" DOCS_HTTP_URL="${CONTEXT_KIT_DOCS_HTTP_URL:-http://127.0.0.1:${DOCS_PORT}/mcp}"
DOCS_CONTAINER_NAME="context-kit-docs-mcp" DOCS_CONTAINER_NAME="context-kit-docs-mcp"
DOCS_SOURCES_FILE="${DATA_DIR}/docs-sources.txt" DOCS_SOURCES_FILE="${DATA_DIR}/docs-sources.txt"
DOCS_DATA_DIR="${DATA_DIR}/docs"
MODELS_DATA_DIR="${DATA_DIR}/models"
WEB_SEARCH_IMAGE="${CONTEXT_KIT_WEB_SEARCH_IMAGE:-context-kit/web-search-mcp:latest}" WEB_SEARCH_IMAGE="${CONTEXT_KIT_WEB_SEARCH_IMAGE:-context-kit/web-search-mcp:latest}"
DOCS_IMAGE="${CONTEXT_KIT_DOCS_IMAGE:-context-kit/docs-mcp:latest}" DOCS_IMAGE="${CONTEXT_KIT_DOCS_IMAGE:-context-kit/docs-mcp:latest}"
@@ -98,6 +100,35 @@ write_docs_sources_file() {
mv "${tmp}" "${DOCS_SOURCES_FILE}" mv "${tmp}" "${DOCS_SOURCES_FILE}"
} }
ensure_writable_dir() {
local dir="$1"
mkdir -p "${dir}"
if [[ ! -w "${dir}" || ! -x "${dir}" ]]; then
fail "data directory is not writable by uid $(id -u): ${dir}; fix ownership or set CONTEXT_KIT_DATA_DIR"
fi
}
prepare_data_dirs() {
ensure_writable_dir "${DATA_DIR}"
ensure_writable_dir "${DOCS_DATA_DIR}"
ensure_writable_dir "${MODELS_DATA_DIR}"
}
check_data_dirs() {
local ok=0 dir
for dir in "${DATA_DIR}" "${DOCS_DATA_DIR}" "${MODELS_DATA_DIR}"; do
if [[ ! -d "${dir}" ]]; then
printf 'warn data directory missing: %s (run context-kit start)\n' "${dir}"
elif [[ -w "${dir}" && -x "${dir}" ]]; then
printf 'pass data directory writable: %s\n' "${dir}"
else
printf 'fail data directory not writable by uid %s: %s\n' "$(id -u)" "${dir}"
ok=1
fi
done
return "${ok}"
}
warn() { warn() {
printf 'warn: %s\n' "$*" >&2 printf 'warn: %s\n' "$*" >&2
} }
@@ -204,7 +235,7 @@ cmd_build() {
cmd_start() { cmd_start() {
require_docker require_docker
mkdir -p "${DATA_DIR}" prepare_data_dirs
if ! docker image inspect "${WEB_SEARCH_IMAGE}" >/dev/null 2>&1 || ! docker image inspect "${DOCS_IMAGE}" >/dev/null 2>&1; then if ! docker image inspect "${WEB_SEARCH_IMAGE}" >/dev/null 2>&1 || ! docker image inspect "${DOCS_IMAGE}" >/dev/null 2>&1; then
cmd_build cmd_build
fi fi
@@ -254,6 +285,10 @@ cmd_doctor() {
printf 'fail docker compose unavailable\n'; ok=1 printf 'fail docker compose unavailable\n'; ok=1
fi fi
if ! check_data_dirs; then
ok=1
fi
if docker network inspect "${NETWORK}" >/dev/null 2>&1; then if docker network inspect "${NETWORK}" >/dev/null 2>&1; then
printf 'pass docker network exists: %s\n' "${NETWORK}" printf 'pass docker network exists: %s\n' "${NETWORK}"
else else

View File

@@ -40,3 +40,34 @@ section. Keep default sources small, and add profiles only when you need them.
Cloudflare and other large docs sets can take significantly longer than the Cloudflare and other large docs sets can take significantly longer than the
default source profile. default source profile.
## Docs Tools Say Index Manager Not Initialized
If `docs_query` or `docs_refresh` returns `Index manager not initialized` while
`/status` still responds, the HTTP wrapper is up but `llms-txt-mcp` failed to
initialize its embedding model or Chroma database. Check the container logs:
```sh
docker logs context-kit-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/.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` now pre-creates these directories and `doctor` reports
existing directories that are not writable by the current user. If an assistant
client reports `Session not found` after restarting `docs-mcp`, restart the
assistant so it opens a fresh Streamable HTTP MCP session.