Harden docs MCP local exposure defaults
This commit is contained in:
@@ -18,6 +18,9 @@ CONTEXT_KIT_SEARXNG_SECRET=change-me-local-only
|
||||
CONTEXT_KIT_DOCS_PORT=8776
|
||||
# Override only if you proxy the service behind another hostname or path.
|
||||
# CONTEXT_KIT_DOCS_HTTP_URL=http://127.0.0.1:8776/mcp
|
||||
# Browser CORS is disabled by default. If a browser-based local client needs
|
||||
# access, set one or more exact origins separated by spaces. Avoid `*`.
|
||||
# CONTEXT_KIT_DOCS_ALLOW_ORIGIN=http://127.0.0.1:3000
|
||||
|
||||
# Docs indexing defaults.
|
||||
CONTEXT_KIT_DOCS_TTL=24h
|
||||
|
||||
@@ -60,6 +60,8 @@ config that will not be committed.
|
||||
HTTP MCP) so every client shares one indexer and one Chroma writer. The
|
||||
`bin/context-kit docs` stdio command is kept as a compatibility shim for
|
||||
clients that cannot speak HTTP MCP.
|
||||
- `context-docs` browser CORS is disabled by default; set exact local origins
|
||||
only when a browser-based client needs direct access.
|
||||
- Docs and model caches live in `$HOME/.local/share/context-kit`.
|
||||
- Docs refresh TTL defaults to `24h`.
|
||||
- MCP containers are labeled `dev.context-kit=true` for safe inspection and cleanup.
|
||||
|
||||
@@ -343,21 +343,24 @@ cmd_docs() {
|
||||
# Prefer the `type: remote` MCP config pointing at ${DOCS_HTTP_URL}.
|
||||
# This stdio entrypoint is kept for clients that cannot speak HTTP MCP:
|
||||
# it spawns a thin mcp-proxy bridge per call but all calls multiplex onto
|
||||
# the single long-lived docs-mcp container (no Chroma write contention).
|
||||
# the single long-lived docs-mcp container over the Context Kit Docker
|
||||
# network (no Chroma write contention, no host networking).
|
||||
require_docker
|
||||
require_network
|
||||
require_image "${DOCS_IMAGE}" "context-kit build"
|
||||
|
||||
if ! docker ps --filter "name=^${DOCS_CONTAINER_NAME}$" --filter "status=running" --format '{{.Names}}' | grep -qx "${DOCS_CONTAINER_NAME}"; then
|
||||
fail "long-lived docs-mcp not running; start it with: context-kit start"
|
||||
fi
|
||||
|
||||
local bridge_url="http://${DOCS_CONTAINER_NAME}:8000/mcp"
|
||||
exec docker run --rm -i \
|
||||
--label dev.context-kit=true \
|
||||
--network host \
|
||||
--network "${NETWORK}" \
|
||||
--entrypoint mcp-proxy \
|
||||
"${DOCS_IMAGE}" \
|
||||
--transport streamablehttp \
|
||||
"${DOCS_HTTP_URL}"
|
||||
"${bridge_url}"
|
||||
}
|
||||
|
||||
cmd_repomix() {
|
||||
|
||||
@@ -52,6 +52,7 @@ services:
|
||||
DOCS_MCP_TTL: "${CONTEXT_KIT_DOCS_TTL:-24h}"
|
||||
DOCS_MCP_MAX_GET_BYTES: "${CONTEXT_KIT_DOCS_MAX_GET_BYTES:-75000}"
|
||||
DOCS_MCP_EMBED_MODEL: "${CONTEXT_KIT_DOCS_EMBED_MODEL:-BAAI/bge-small-en-v1.5}"
|
||||
DOCS_MCP_ALLOW_ORIGIN: "${CONTEXT_KIT_DOCS_ALLOW_ORIGIN:-}"
|
||||
# Preindex on startup is off by default; use the docs_refresh tool to
|
||||
# refresh on demand. Set CONTEXT_KIT_DOCS_PREINDEX=1 to restore eager.
|
||||
DOCS_MCP_PREINDEX: "${CONTEXT_KIT_DOCS_PREINDEX:-0}"
|
||||
|
||||
@@ -37,12 +37,17 @@ if [ "${DOCS_MCP_PREINDEX:-0}" = "1" ]; then
|
||||
preindex_flag=""
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2086 # intentional word-splitting on $sources / $preindex_flag
|
||||
allow_origin_args=""
|
||||
if [ -n "${DOCS_MCP_ALLOW_ORIGIN:-}" ]; then
|
||||
allow_origin_args="--allow-origin ${DOCS_MCP_ALLOW_ORIGIN}"
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2086 # intentional word-splitting on $sources / $preindex_flag / $allow_origin_args
|
||||
exec mcp-proxy \
|
||||
--host "${DOCS_MCP_HTTP_HOST:-0.0.0.0}" \
|
||||
--port "${DOCS_MCP_HTTP_PORT:-8000}" \
|
||||
--pass-environment \
|
||||
--allow-origin "${DOCS_MCP_ALLOW_ORIGIN:-*}" \
|
||||
$allow_origin_args \
|
||||
-- \
|
||||
llms-txt-mcp \
|
||||
--store-path /data \
|
||||
|
||||
@@ -15,7 +15,8 @@ shell code.
|
||||
| `CONTEXT_KIT_COMPOSE_PROJECT` | `context-kit` | Docker Compose project and network prefix |
|
||||
| `CONTEXT_KIT_SEARXNG_PORT` | `8099` | Localhost SearXNG port |
|
||||
| `CONTEXT_KIT_DOCS_PORT` | `8776` | Localhost port for the long-lived docs-mcp HTTP service |
|
||||
| `CONTEXT_KIT_DOCS_HTTP_URL` | `http://127.0.0.1:${CONTEXT_KIT_DOCS_PORT}/mcp` | URL emitted into install snippets and used by the stdio bridge |
|
||||
| `CONTEXT_KIT_DOCS_HTTP_URL` | `http://127.0.0.1:${CONTEXT_KIT_DOCS_PORT}/mcp` | URL emitted into HTTP MCP install snippets |
|
||||
| `CONTEXT_KIT_DOCS_ALLOW_ORIGIN` | unset | Optional exact browser CORS origin(s) for docs-mcp, separated by spaces |
|
||||
| `CONTEXT_KIT_DOCS_TTL` | `24h` | Docs re-fetch cadence |
|
||||
| `CONTEXT_KIT_DOCS_SOURCES` | `config/sources.default.txt` | Space-separated source profile files |
|
||||
| `CONTEXT_KIT_DOCS_MAX_GET_BYTES` | `75000` | Max bytes returned by docs retrieval |
|
||||
@@ -43,6 +44,19 @@ The docs-mcp container reads `CONTEXT_KIT_DOCS_TTL` at startup, so changes
|
||||
require `bin/context-kit restart`. When freshness matters for one task, prefer
|
||||
calling the `docs_refresh` MCP tool instead of lowering the global TTL.
|
||||
|
||||
## Browser CORS
|
||||
|
||||
`context-docs` disables browser CORS by default. CLI assistants and server-side
|
||||
HTTP clients do not need CORS. If a browser-based local client must call the MCP
|
||||
endpoint directly, allow only the exact local origin(s) it uses:
|
||||
|
||||
```sh
|
||||
CONTEXT_KIT_DOCS_ALLOW_ORIGIN="http://127.0.0.1:3000 http://localhost:3000" \
|
||||
bin/context-kit restart
|
||||
```
|
||||
|
||||
Avoid `*`; the docs MCP is a local unauthenticated endpoint.
|
||||
|
||||
## Source Profiles
|
||||
|
||||
The docs MCP accepts one or more source files:
|
||||
|
||||
@@ -33,3 +33,12 @@ their mount paths and permissions separately.
|
||||
|
||||
Do not expose SearXNG or MCP servers to the public internet without a separate
|
||||
review. The default setup is for localhost development.
|
||||
|
||||
The containers may bind to `0.0.0.0` internally, but the Compose file publishes
|
||||
SearXNG and docs-mcp only on `127.0.0.1`. If you run the images outside the
|
||||
provided Compose file, review port publishing, SearXNG's limiter/secret, and MCP
|
||||
authentication separately.
|
||||
|
||||
Browser CORS for `context-docs` is disabled by default. Only set
|
||||
`CONTEXT_KIT_DOCS_ALLOW_ORIGIN` for exact local origins that need direct browser
|
||||
access; avoid wildcard origins for unauthenticated local MCP endpoints.
|
||||
|
||||
Reference in New Issue
Block a user