tool-compass 2.5.4__tar.gz → 2.5.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tool_compass-2.5.4 → tool_compass-2.5.6}/.env.example +31 -6
- {tool_compass-2.5.4 → tool_compass-2.5.6}/.github/workflows/ci.yml +115 -15
- {tool_compass-2.5.4 → tool_compass-2.5.6}/.github/workflows/publish.yml +6 -6
- {tool_compass-2.5.4 → tool_compass-2.5.6}/.github/workflows/release-binaries.yml +2 -2
- tool_compass-2.5.6/.polyglot-pins.json +29 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/CHANGELOG.md +26 -1
- {tool_compass-2.5.4 → tool_compass-2.5.6}/Dockerfile +21 -8
- {tool_compass-2.5.4 → tool_compass-2.5.6}/PKG-INFO +34 -7
- {tool_compass-2.5.4 → tool_compass-2.5.6}/README.md +33 -6
- {tool_compass-2.5.4 → tool_compass-2.5.6}/SECURITY.md +6 -7
- {tool_compass-2.5.4 → tool_compass-2.5.6}/atlas/README.md +16 -9
- {tool_compass-2.5.4 → tool_compass-2.5.6}/atlas/page.json +107 -23
- {tool_compass-2.5.4 → tool_compass-2.5.6}/atlas/statistics.json +237 -242
- {tool_compass-2.5.4 → tool_compass-2.5.6}/atlas/structure.json +327 -256
- {tool_compass-2.5.4 → tool_compass-2.5.6}/cli.py +26 -10
- {tool_compass-2.5.4 → tool_compass-2.5.6}/config.py +27 -7
- {tool_compass-2.5.4 → tool_compass-2.5.6}/docker-compose.yml +11 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/docker-entrypoint.sh +66 -3
- {tool_compass-2.5.4 → tool_compass-2.5.6}/fly.toml +4 -3
- {tool_compass-2.5.4 → tool_compass-2.5.6}/gateway.py +63 -25
- {tool_compass-2.5.4 → tool_compass-2.5.6}/pyproject.toml +2 -2
- {tool_compass-2.5.4 → tool_compass-2.5.6}/requirements-dev.txt +3 -3
- {tool_compass-2.5.4 → tool_compass-2.5.6}/ui.py +89 -29
- {tool_compass-2.5.4 → tool_compass-2.5.6}/.dockerignore +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/.gitattributes +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/.github/dependabot.yml +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/.github/workflows/release.yml +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/.gitignore +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/.pre-commit-config.yaml +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/CODE_OF_CONDUCT.md +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/CONTRIBUTING.md +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/LICENSE +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/Makefile +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/SCORECARD.md +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/SHIP_GATE.md +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/_version.py +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/analytics.py +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/atlas/boundaries.yaml +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/backend_client_mcp.py +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/backend_client_simple.py +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/bootstrap.py +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/chain_indexer.py +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/codecov.yml +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/compass_config.example.json +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/docs/index.md +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/embedder.py +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/indexer.py +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/llms.txt +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/requirements.txt +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/scripts/check-org-urls.sh +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/scripts/regenerate-scorecard.sh +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/scripts/sync-version.mjs +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/scripts/verify-metrics.sh +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/sync_manager.py +0 -0
- {tool_compass-2.5.4 → tool_compass-2.5.6}/tool_manifest.py +0 -0
|
@@ -47,13 +47,18 @@ LOG_LEVEL=INFO
|
|
|
47
47
|
|
|
48
48
|
# Host / port are set on the CLI, not via env vars — `ui.py` passes them
|
|
49
49
|
# explicitly to Gradio's launch(), which overrides GRADIO_SERVER_NAME/PORT:
|
|
50
|
-
# tool-compass ui --host 0.0.0.0 --port 7860
|
|
51
|
-
# (defaults: 127.0.0.1:7860; the Docker image
|
|
52
|
-
|
|
53
|
-
#
|
|
54
|
-
#
|
|
55
|
-
#
|
|
50
|
+
# tool-compass ui --host 0.0.0.0 --port 7860 --auth user:pass
|
|
51
|
+
# (defaults: 127.0.0.1:7860; the Docker UI image binds 0.0.0.0.)
|
|
52
|
+
|
|
53
|
+
# UI login in "user:pass" format (both sides non-empty). Applied on every UI
|
|
54
|
+
# start when set, and REQUIRED when binding a non-loopback host (including the
|
|
55
|
+
# Docker UI container) or passing `--share`.
|
|
56
|
+
# To start the Docker UI container (or any non-loopback bind), either:
|
|
57
|
+
# 1. Set GRADIO_AUTH=user:pass, OR
|
|
58
|
+
# 2. Set TOOL_COMPASS_UI_ALLOW_NO_LOGIN=1 when running behind a proxy that
|
|
59
|
+
# does its own login (prints a startup warning and hides execute controls).
|
|
56
60
|
# GRADIO_AUTH=user:pass
|
|
61
|
+
# TOOL_COMPASS_UI_ALLOW_NO_LOGIN=1
|
|
57
62
|
|
|
58
63
|
# =============================================================================
|
|
59
64
|
# Docker-Specific
|
|
@@ -62,6 +67,26 @@ LOG_LEVEL=INFO
|
|
|
62
67
|
# When running in Docker, use host.docker.internal to reach host services
|
|
63
68
|
# OLLAMA_URL=http://host.docker.internal:11434
|
|
64
69
|
|
|
70
|
+
# =============================================================================
|
|
71
|
+
# HTTP Gateway Settings (when PORT is set or `tool-compass serve --http`)
|
|
72
|
+
# =============================================================================
|
|
73
|
+
|
|
74
|
+
# Port for streamable-http transport (unset = stdio mode)
|
|
75
|
+
# PORT=8080
|
|
76
|
+
|
|
77
|
+
# Bind host for HTTP mode (default: 127.0.0.1). Non-loopback values refuse to
|
|
78
|
+
# start unless TOOL_COMPASS_GATEWAY_AUTH_TOKEN (or gateway_auth_token) is set,
|
|
79
|
+
# or TOOL_COMPASS_GATEWAY_ALLOW_NO_TOKEN=1 is set behind an authenticating proxy.
|
|
80
|
+
# HOST=127.0.0.1
|
|
81
|
+
|
|
82
|
+
# Bearer token for the HTTP gateway (overrides gateway_auth_token in
|
|
83
|
+
# compass_config.json). Required off loopback; optional on loopback.
|
|
84
|
+
# TOOL_COMPASS_GATEWAY_AUTH_TOKEN=
|
|
85
|
+
|
|
86
|
+
# Explicit opt-out allowing non-loopback HTTP startup without a bearer token
|
|
87
|
+
# when an authenticating reverse proxy sits in front (logs a startup warning).
|
|
88
|
+
# TOOL_COMPASS_GATEWAY_ALLOW_NO_TOKEN=1
|
|
89
|
+
|
|
65
90
|
# =============================================================================
|
|
66
91
|
# Analytics (optional)
|
|
67
92
|
# =============================================================================
|
|
@@ -204,7 +204,7 @@ jobs:
|
|
|
204
204
|
|
|
205
205
|
- name: Atlas check
|
|
206
206
|
if: matrix.python-version == '3.12' && matrix.os == 'ubuntu-latest'
|
|
207
|
-
run: npx --yes @dogfood-lab/atlas@1.
|
|
207
|
+
run: npx --yes @dogfood-lab/atlas@1.26.0 check
|
|
208
208
|
|
|
209
209
|
- name: Install dependencies
|
|
210
210
|
run: |
|
|
@@ -219,7 +219,7 @@ jobs:
|
|
|
219
219
|
|
|
220
220
|
- name: Upload JUnit report
|
|
221
221
|
if: always()
|
|
222
|
-
uses: actions/upload-artifact@
|
|
222
|
+
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7
|
|
223
223
|
with:
|
|
224
224
|
name: junit-reports-${{ matrix.python-version }}-${{ matrix.os }}
|
|
225
225
|
path: junit-${{ matrix.python-version }}-${{ matrix.os }}.xml
|
|
@@ -242,7 +242,7 @@ jobs:
|
|
|
242
242
|
# replace the artifact its earlier attempt saved.
|
|
243
243
|
- name: Save coverage for Codecov
|
|
244
244
|
if: ${{ env.COVERAGE_LEG == 'true' }}
|
|
245
|
-
uses: actions/upload-artifact@
|
|
245
|
+
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
246
246
|
with:
|
|
247
247
|
name: codecov-coverage
|
|
248
248
|
path: coverage.xml
|
|
@@ -252,7 +252,7 @@ jobs:
|
|
|
252
252
|
|
|
253
253
|
- name: Save test results for Codecov
|
|
254
254
|
if: ${{ !cancelled() && env.COVERAGE_LEG == 'true' && steps.tests.outcome != 'skipped' }}
|
|
255
|
-
uses: actions/upload-artifact@
|
|
255
|
+
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
256
256
|
with:
|
|
257
257
|
name: codecov-test-results
|
|
258
258
|
path: junit.xml
|
|
@@ -268,7 +268,7 @@ jobs:
|
|
|
268
268
|
|
|
269
269
|
- name: Upload pip-audit report
|
|
270
270
|
if: matrix.python-version == '3.12' && matrix.os == 'ubuntu-latest'
|
|
271
|
-
uses: actions/upload-artifact@
|
|
271
|
+
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7
|
|
272
272
|
with:
|
|
273
273
|
name: pip-audit-report
|
|
274
274
|
path: pip-audit-report.json
|
|
@@ -277,13 +277,65 @@ jobs:
|
|
|
277
277
|
# retention and is plenty of window for incident response.
|
|
278
278
|
retention-days: 14
|
|
279
279
|
|
|
280
|
-
# Now BLOCKING
|
|
281
|
-
#
|
|
280
|
+
# Now BLOCKING, in two parts. The core install (requirements.txt without
|
|
281
|
+
# the Web UI line) is audited strictly, with no ignores. The Web UI extra
|
|
282
|
+
# (gradio) is audited next with the dated Pillow exception (#157). The
|
|
282
283
|
# report-only artifact step above still runs for the full JSON snapshot.
|
|
283
|
-
- name: Audit dependencies for vulnerabilities
|
|
284
|
+
- name: Audit core dependencies for vulnerabilities
|
|
284
285
|
if: matrix.python-version == '3.12' && matrix.os == 'ubuntu-latest'
|
|
285
286
|
run: |
|
|
286
|
-
|
|
287
|
+
grep -vi '^gradio' requirements.txt > "$RUNNER_TEMP/requirements-core.txt"
|
|
288
|
+
pip-audit -r "$RUNNER_TEMP/requirements-core.txt"
|
|
289
|
+
|
|
290
|
+
- name: Audit Web UI extra for vulnerabilities
|
|
291
|
+
if: matrix.python-version == '3.12' && matrix.os == 'ubuntu-latest'
|
|
292
|
+
run: |
|
|
293
|
+
grep -i '^gradio' requirements.txt > "$RUNNER_TEMP/requirements-ui.txt"
|
|
294
|
+
# Dated exception until 2026-12-10 (#157): gradio 6.31.0 requires
|
|
295
|
+
# pillow<13.0, holding pillow at 12.3.0 while the 40 advisories below
|
|
296
|
+
# are fixed in 13.0.0 and unreachable from tool-compass. Remove when
|
|
297
|
+
# a stable gradio allows pillow 13, or re-read on 2026-12-10.
|
|
298
|
+
pip-audit -r "$RUNNER_TEMP/requirements-ui.txt" \
|
|
299
|
+
--ignore-vuln PYSEC-2026-4327 \
|
|
300
|
+
--ignore-vuln PYSEC-2026-4328 \
|
|
301
|
+
--ignore-vuln PYSEC-2026-4326 \
|
|
302
|
+
--ignore-vuln PYSEC-2026-4339 \
|
|
303
|
+
--ignore-vuln PYSEC-2026-4340 \
|
|
304
|
+
--ignore-vuln PYSEC-2026-4343 \
|
|
305
|
+
--ignore-vuln PYSEC-2026-4334 \
|
|
306
|
+
--ignore-vuln PYSEC-2026-4337 \
|
|
307
|
+
--ignore-vuln PYSEC-2026-4341 \
|
|
308
|
+
--ignore-vuln PYSEC-2026-4330 \
|
|
309
|
+
--ignore-vuln PYSEC-2026-4338 \
|
|
310
|
+
--ignore-vuln PYSEC-2026-4335 \
|
|
311
|
+
--ignore-vuln PYSEC-2026-4336 \
|
|
312
|
+
--ignore-vuln PYSEC-2026-4331 \
|
|
313
|
+
--ignore-vuln PYSEC-2026-4332 \
|
|
314
|
+
--ignore-vuln PYSEC-2026-4329 \
|
|
315
|
+
--ignore-vuln PYSEC-2026-4333 \
|
|
316
|
+
--ignore-vuln PYSEC-2026-4342 \
|
|
317
|
+
--ignore-vuln CVE-2026-112895 \
|
|
318
|
+
--ignore-vuln CVE-2026-112400 \
|
|
319
|
+
--ignore-vuln CVE-2026-112897 \
|
|
320
|
+
--ignore-vuln CVE-2026-112395 \
|
|
321
|
+
--ignore-vuln CVE-2026-112404 \
|
|
322
|
+
--ignore-vuln CVE-2026-112899 \
|
|
323
|
+
--ignore-vuln CVE-2026-112900 \
|
|
324
|
+
--ignore-vuln CVE-2026-112893 \
|
|
325
|
+
--ignore-vuln CVE-2026-112891 \
|
|
326
|
+
--ignore-vuln CVE-2026-112390 \
|
|
327
|
+
--ignore-vuln CVE-2026-112401 \
|
|
328
|
+
--ignore-vuln CVE-2026-112391 \
|
|
329
|
+
--ignore-vuln CVE-2026-112894 \
|
|
330
|
+
--ignore-vuln CVE-2026-112406 \
|
|
331
|
+
--ignore-vuln CVE-2026-112399 \
|
|
332
|
+
--ignore-vuln CVE-2026-112892 \
|
|
333
|
+
--ignore-vuln CVE-2026-112393 \
|
|
334
|
+
--ignore-vuln CVE-2026-96638 \
|
|
335
|
+
--ignore-vuln CVE-2026-96640 \
|
|
336
|
+
--ignore-vuln CVE-2026-96778 \
|
|
337
|
+
--ignore-vuln GHSA-78g4-xqwv-q3g8 \
|
|
338
|
+
--ignore-vuln PYSEC-2026-4363
|
|
287
339
|
|
|
288
340
|
codecov:
|
|
289
341
|
# Uploads what the test job saved, from a job of its own, so the OIDC
|
|
@@ -310,13 +362,13 @@ jobs:
|
|
|
310
362
|
# that matches nothing, unlike a name, does not fail: a failing test
|
|
311
363
|
# run saves test results and no coverage.
|
|
312
364
|
- name: Download coverage
|
|
313
|
-
uses: actions/download-artifact@
|
|
365
|
+
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
|
314
366
|
with:
|
|
315
367
|
pattern: codecov-coverage
|
|
316
368
|
path: .
|
|
317
369
|
|
|
318
370
|
- name: Download test results
|
|
319
|
-
uses: actions/download-artifact@
|
|
371
|
+
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
|
320
372
|
with:
|
|
321
373
|
pattern: codecov-test-results
|
|
322
374
|
path: .
|
|
@@ -531,10 +583,10 @@ jobs:
|
|
|
531
583
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
|
532
584
|
|
|
533
585
|
- name: Set up Docker Buildx
|
|
534
|
-
uses: docker/setup-buildx-action@
|
|
586
|
+
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
|
|
535
587
|
|
|
536
588
|
- name: Build Docker image
|
|
537
|
-
uses: docker/build-push-action@
|
|
589
|
+
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
|
|
538
590
|
with:
|
|
539
591
|
context: .
|
|
540
592
|
target: ${{ matrix.target }}
|
|
@@ -547,10 +599,55 @@ jobs:
|
|
|
547
599
|
- name: Smoke run
|
|
548
600
|
run: |
|
|
549
601
|
set -euo pipefail
|
|
550
|
-
|
|
602
|
+
# PYTHONUNBUFFERED + PYTHONFAULTHANDLER: a start that stalls before the
|
|
603
|
+
# app logs anything (seen on hosted runners: the container printed only
|
|
604
|
+
# the entrypoint's volume warning for the whole window) must say where
|
|
605
|
+
# it is stuck. On timeout the step sends SIGABRT, which makes Python
|
|
606
|
+
# write every thread's stack to the container log before it dies.
|
|
607
|
+
if [ "${{ matrix.smoke }}" = "bind" ]; then
|
|
608
|
+
# UI image binds 0.0.0.0 and must refuse a bare start without login.
|
|
609
|
+
rc=0
|
|
610
|
+
docker run --rm ${{ matrix.tag }} >/dev/null 2>&1 || rc=$?
|
|
611
|
+
if [ "$rc" -ne 2 ]; then
|
|
612
|
+
echo "::error::UI container without GRADIO_AUTH exited $rc (expected 2)"
|
|
613
|
+
exit 1
|
|
614
|
+
fi
|
|
615
|
+
docker run -d --name tc-smoke -e PYTHONUNBUFFERED=1 -e PYTHONFAULTHANDLER=1 \
|
|
616
|
+
-e GRADIO_AUTH=u:p -p ${{ matrix.port }}:${{ matrix.port }} ${{ matrix.tag }}
|
|
617
|
+
else
|
|
618
|
+
SMOKE_ENV_ARGS=()
|
|
619
|
+
if [ "${{ matrix.target }}" = "mcp-gateway" ]; then
|
|
620
|
+
# Bare start (HOST=0.0.0.0, no token, no opt-out) must refuse with
|
|
621
|
+
# exit code 2. Bound with timeout so a fail-open start cannot hang.
|
|
622
|
+
set +e
|
|
623
|
+
BARE_OUT="$(timeout 30s docker run --rm --name tc-smoke-bare \
|
|
624
|
+
-e PYTHONUNBUFFERED=1 ${{ matrix.tag }} 2>&1)"
|
|
625
|
+
BARE_RC=$?
|
|
626
|
+
set -e
|
|
627
|
+
docker rm -f tc-smoke-bare >/dev/null 2>&1 || true
|
|
628
|
+
echo "$BARE_OUT"
|
|
629
|
+
if [ "$BARE_RC" -ne 2 ]; then
|
|
630
|
+
echo "::error::bare mcp-gateway start expected exit 2, got ${BARE_RC}"
|
|
631
|
+
exit 1
|
|
632
|
+
fi
|
|
633
|
+
SMOKE_VAL="ci-smoke"
|
|
634
|
+
SMOKE_ENV_ARGS=(-e "TOOL_COMPASS_GATEWAY_AUTH_TOKEN=${SMOKE_VAL}")
|
|
635
|
+
fi
|
|
636
|
+
docker run -d --name tc-smoke -e PYTHONUNBUFFERED=1 -e PYTHONFAULTHANDLER=1 \
|
|
637
|
+
${SMOKE_ENV_ARGS[@]+"${SMOKE_ENV_ARGS[@]}"} \
|
|
638
|
+
-p ${{ matrix.port }}:${{ matrix.port }} ${{ matrix.tag }}
|
|
639
|
+
fi
|
|
551
640
|
cleanup() { docker logs tc-smoke || true; docker rm -f tc-smoke || true; }
|
|
552
641
|
trap cleanup EXIT
|
|
553
|
-
|
|
642
|
+
# 90 x 2s = 3 minutes. 45 x 2s was enough on every run that started
|
|
643
|
+
# normally (the image answers in a few seconds), but a hosted runner
|
|
644
|
+
# that is slow to start the process failed the required check with no
|
|
645
|
+
# code change; a crashed container still fails at once (below).
|
|
646
|
+
for _ in $(seq 1 90); do
|
|
647
|
+
if [ "$(docker inspect -f '{{.State.Running}}' tc-smoke)" != "true" ]; then
|
|
648
|
+
echo "::error::docker smoke (${{ matrix.target }}) container exited before it was ready"
|
|
649
|
+
exit 1
|
|
650
|
+
fi
|
|
554
651
|
if [ "${{ matrix.smoke }}" = "health" ]; then
|
|
555
652
|
if curl -sf "http://127.0.0.1:${{ matrix.port }}/health"; then
|
|
556
653
|
echo "gateway /health ok"
|
|
@@ -569,6 +666,9 @@ jobs:
|
|
|
569
666
|
sleep 2
|
|
570
667
|
done
|
|
571
668
|
echo "::error::docker smoke (${{ matrix.target }}) did not become ready on port ${{ matrix.port }}"
|
|
669
|
+
docker top tc-smoke || true
|
|
670
|
+
docker kill -s ABRT tc-smoke || true
|
|
671
|
+
sleep 2
|
|
572
672
|
exit 1
|
|
573
673
|
|
|
574
674
|
# ===========================================================================
|
|
@@ -77,7 +77,7 @@ jobs:
|
|
|
77
77
|
run: twine check dist/*
|
|
78
78
|
|
|
79
79
|
- name: Upload build artifacts
|
|
80
|
-
uses: actions/upload-artifact@
|
|
80
|
+
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7
|
|
81
81
|
with:
|
|
82
82
|
name: dist
|
|
83
83
|
path: dist/
|
|
@@ -104,13 +104,13 @@ jobs:
|
|
|
104
104
|
|
|
105
105
|
steps:
|
|
106
106
|
- name: Download build artifacts
|
|
107
|
-
uses: actions/download-artifact@
|
|
107
|
+
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8
|
|
108
108
|
with:
|
|
109
109
|
name: dist
|
|
110
110
|
path: dist/
|
|
111
111
|
|
|
112
112
|
- name: Publish to PyPI
|
|
113
|
-
uses: pypa/gh-action-pypi-publish@
|
|
113
|
+
uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
|
|
114
114
|
with:
|
|
115
115
|
# CT-B-009: emit SLSA build provenance attestations for the wheel
|
|
116
116
|
# and sdist. PyPI verifies the attestation against the workflow's
|
|
@@ -207,13 +207,13 @@ jobs:
|
|
|
207
207
|
# SHA-pinned per SLSA L3 supply-chain hygiene (CT-B-002). publish job
|
|
208
208
|
# carries packages:write — a compromised mutable v3 tag would inherit
|
|
209
209
|
# GHCR write capability during a release window. Bump via dependabot.
|
|
210
|
-
uses: docker/setup-qemu-action@
|
|
210
|
+
uses: docker/setup-qemu-action@99012661954931238ded8c8b007157a8430204e1 # v4.4.0
|
|
211
211
|
|
|
212
212
|
- name: Set up Docker Buildx
|
|
213
|
-
uses: docker/setup-buildx-action@
|
|
213
|
+
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
|
|
214
214
|
|
|
215
215
|
- name: Build and push
|
|
216
|
-
uses: docker/build-push-action@
|
|
216
|
+
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
|
|
217
217
|
with:
|
|
218
218
|
context: .
|
|
219
219
|
target: ${{ matrix.target }}
|
|
@@ -137,7 +137,7 @@ jobs:
|
|
|
137
137
|
"$BIN" ui --help
|
|
138
138
|
|
|
139
139
|
- name: Upload binary artifact
|
|
140
|
-
uses: actions/upload-artifact@
|
|
140
|
+
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7
|
|
141
141
|
with:
|
|
142
142
|
name: binary-${{ matrix.target }}
|
|
143
143
|
path: dist/${{ env.TOOL_NAME }}-*
|
|
@@ -154,7 +154,7 @@ jobs:
|
|
|
154
154
|
attestations: write
|
|
155
155
|
steps:
|
|
156
156
|
- name: Download all binaries
|
|
157
|
-
uses: actions/download-artifact@
|
|
157
|
+
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
|
158
158
|
with:
|
|
159
159
|
path: artifacts
|
|
160
160
|
merge-multiple: true
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"pins": {
|
|
4
|
+
"0ec3b638688c0d83:zh": {
|
|
5
|
+
"lang": "zh",
|
|
6
|
+
"source": "Per-category scores are regenerated post-swarm via\n`bash scripts/regenerate-scorecard.sh` (which wraps `npx\n@mcptoolshop/shipcheck audit`). See [SCORECARD.md](SCORECARD.md) for the\ncurrent authoritative breakdown — the table below mirrors it and is\nintentionally not hand-authored. Hand-curated sections (Known Gaps,\nRemediation History) live outside the `<!-- SHIPCHECK-AUTO-START/END -->`\nmarkers in SCORECARD.md and survive regenerations.",
|
|
7
|
+
"translation": "通过 `bash scripts/regenerate-scorecard.sh` 在群集完成后重新生成每个类别的分数(该工具包装了 `npx @mcptoolshop/shipcheck audit`)。有关当前权威的细分,请参阅 [SCORECARD.md](SCORECARD.md)——下表是对其的镜像,并且有意不是手动编写的。手动策划的部分(已知差距、修复历史记录)位于 SCORECARD.md 中的 `<!-- SHIPCHECK-AUTO-START/END -->` 标记之外,并且会在重新生成时保留。",
|
|
8
|
+
"pinnedAt": "2026-11-12T11:38:07.275Z"
|
|
9
|
+
},
|
|
10
|
+
"28f2f2cfe1b673d7:ja": {
|
|
11
|
+
"lang": "ja",
|
|
12
|
+
"source": "Get the full `inputSchema` for a tool (required/enums/defaults)",
|
|
13
|
+
"translation": "ツールの完全な `inputSchema`(必須項目/列挙型/デフォルト値)を取得します。",
|
|
14
|
+
"pinnedAt": "2026-11-12T11:38:07.731Z"
|
|
15
|
+
},
|
|
16
|
+
"bb5538e8cb37670d:ja": {
|
|
17
|
+
"lang": "ja",
|
|
18
|
+
"source": "Set to `1` to allow starting the UI off loopback without `GRADIO_AUTH` behind an authenticating proxy (warns and hides execute controls)",
|
|
19
|
+
"translation": "`1` に設定すると、認証プロキシの背後で `GRADIO_AUTH` なしにループバック以外でUIを起動できます(警告を表示し、実行コントロールを非表示にします)。",
|
|
20
|
+
"pinnedAt": "2026-11-12T11:38:07.733Z"
|
|
21
|
+
},
|
|
22
|
+
"ee7649ad38ebf58b:zh": {
|
|
23
|
+
"lang": "zh",
|
|
24
|
+
"source": "📖 **Full documentation:** See the [Tool Compass Handbook](https://mcp-tool-shop-org.github.io/tool-compass/handbook/) for installation, configuration, and architecture deep-dives.",
|
|
25
|
+
"translation": "📖 **完整文档:** 请参阅 [Tool Compass Handbook](https://mcp-tool-shop-org.github.io/tool-compass/handbook/),其中包含有关安装、配置和架构的详细信息。",
|
|
26
|
+
"pinnedAt": "2026-11-12T11:38:07.271Z"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.5.6] - 2026-11-12
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **The Gradio UI honours `GRADIO_AUTH` / `--auth` on every start, and refuses to start off loopback (including the Docker UI container) without a login.** Loopback starts (`127.0.0.1`, `localhost`, `::1`) continue to work without a login when `GRADIO_AUTH` is unset, and apply the login whenever `GRADIO_AUTH=user:pass` or `tool-compass ui --auth user:pass` is set (malformed values exit with code 2). Non-loopback starts and the Docker UI image require `GRADIO_AUTH=user:pass`, or `TOOL_COMPASS_UI_ALLOW_NO_LOGIN=1` when running behind a proxy that enforces its own login (which prints a startup warning and hides the UI execute controls).
|
|
15
|
+
- Added a dated `pip-audit` exception in CI until 2026-12-10 (#157) for 39 unreachable `pillow` 12.3.0 advisories held below `13.0.0` by `gradio` 6.31.0's `pillow<13.0` requirement, and raised the coverage floor (`[tool.coverage.report].fail_under`) from 77 to 78.
|
|
16
|
+
- The HTTP gateway off loopback (`HOST` other than `127.0.0.1`, `localhost`, or `::1`) — including the `mcp-gateway` Docker image, the `docker-compose.yml` `gateway` service, and `fly.toml` — now refuses to start (exits 2) unless a non-empty bearer token is configured via `TOOL_COMPASS_GATEWAY_AUTH_TOKEN` (or `gateway_auth_token` in `compass_config.json`, or `fly secrets set TOOL_COMPASS_GATEWAY_AUTH_TOKEN=<token>` on Fly.io) or the proxy opt-out `TOOL_COMPASS_GATEWAY_ALLOW_NO_TOKEN=1` is set (which logs a warning on every start). Loopback HTTP starts without a token continue to work unchanged, and `/health` and `/ready` remain unauthenticated for probes.
|
|
17
|
+
- Site dependencies updated with `npm audit fix` (`vite`, `undici`, `zod` and related packages); `npm audit` now reports 0 vulnerabilities for `site/`.
|
|
18
|
+
- The CI dependency audit is split in two: the core install is audited strictly with no exceptions, and the Web UI extra (`gradio`) keeps the dated Pillow exception.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- The gateway's bearer check compares bytes instead of text. A non-ASCII `Authorization` header (or a non-ASCII configured token) made `hmac.compare_digest` raise, so the request got a 500 instead of a 401. It still refused the request, and a non-ASCII token now works.
|
|
23
|
+
|
|
24
|
+
## [2.5.5] - 2026-10-15
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- **The Docker image no longer crashes with "Illegal instruction" on a CPU older than the one that built it.** `hnswlib` has no wheel for the image's Python, so the build compiles it, and its `setup.py` adds `-march=native` unless `HNSWLIB_NO_NATIVE` is set. The compiled extension therefore carried the build host's CPU extensions, and on a CPU without them `import hnswlib` (first reached from `indexer.py`) killed the process with SIGILL before the gateway printed anything. The builder stage now sets `HNSWLIB_NO_NATIVE=1`. It surfaced as an intermittent failure of the required `Docker mcp-gateway` smoke check, where a cached image layer built on one hosted runner ran on a different one.
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- The CI Docker smoke waits up to 3 minutes instead of 90 seconds, fails at once if the container exits, and on a timeout sends SIGABRT so Python writes its stack to the log. No effect on the published package.
|
|
33
|
+
|
|
10
34
|
## [2.5.4] - 2026-10-14
|
|
11
35
|
|
|
12
36
|
### Security
|
|
@@ -42,7 +66,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
42
66
|
|
|
43
67
|
- `.gitattributes` pins LF on `*.sh`, the `Dockerfile` and the entrypoint. A
|
|
44
68
|
shell script checked out with CRLF on Windows makes the shebang
|
|
45
|
-
`#!/bin/sh
|
|
69
|
+
`#!/bin/sh
|
|
70
|
+
`, and Linux then fails with "no such file or directory" naming
|
|
46
71
|
the script rather than the line endings — invisible to CI, which checks out
|
|
47
72
|
LF on Linux, and visible only to a contributor building the image on Windows.
|
|
48
73
|
Caught on the sibling xrpl-camp repo the same day.
|
|
@@ -28,6 +28,15 @@ COPY cli.py gateway.py ui.py indexer.py embedder.py chain_indexer.py \
|
|
|
28
28
|
# the `tool-compass` console script ends up on PATH (ships with the image).
|
|
29
29
|
RUN python -m venv /opt/venv
|
|
30
30
|
ENV PATH="/opt/venv/bin:$PATH"
|
|
31
|
+
# hnswlib publishes no wheel for this interpreter, so pip compiles it here, and
|
|
32
|
+
# its setup.py adds -march=native unless HNSWLIB_NO_NATIVE is set. That bakes the
|
|
33
|
+
# build machine's CPU extensions (AVX-512 on some hosted runners) into the image;
|
|
34
|
+
# on a CPU without them the first `import hnswlib` dies with SIGILL ("Illegal
|
|
35
|
+
# instruction") before the gateway prints anything. Observed as an intermittent
|
|
36
|
+
# CI smoke failure when a cached layer built on one runner ran on another, and
|
|
37
|
+
# it is the same hazard for anyone pulling the published image onto an older CPU.
|
|
38
|
+
# Builder stage only: the production stage copies the venv, not the variable.
|
|
39
|
+
ENV HNSWLIB_NO_NATIVE=1
|
|
31
40
|
RUN pip install --no-cache-dir --upgrade pip && \
|
|
32
41
|
pip install --no-cache-dir -r requirements.txt && \
|
|
33
42
|
pip install --no-cache-dir uvicorn && \
|
|
@@ -104,9 +113,10 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
|
|
104
113
|
|
|
105
114
|
# Default command: Run Gradio UI.
|
|
106
115
|
# UI-DOCKER-BIND-001: bind 0.0.0.0 explicitly so the UI is reachable through the
|
|
107
|
-
# published port mapping
|
|
108
|
-
#
|
|
109
|
-
#
|
|
116
|
+
# published port mapping; without this the UI bound to 127.0.0.1 inside the
|
|
117
|
+
# container and was unreachable. Because 0.0.0.0 is non-loopback, startup
|
|
118
|
+
# refuses to run unless GRADIO_AUTH=user:pass is set (or
|
|
119
|
+
# TOOL_COMPASS_UI_ALLOW_NO_LOGIN=1 is set behind a proxy that does its own login).
|
|
110
120
|
CMD ["python", "ui.py", "--host", "0.0.0.0", "--port", "7860"]
|
|
111
121
|
|
|
112
122
|
# =============================================================================
|
|
@@ -114,12 +124,15 @@ CMD ["python", "ui.py", "--host", "0.0.0.0", "--port", "7860"]
|
|
|
114
124
|
# =============================================================================
|
|
115
125
|
FROM production AS mcp-gateway
|
|
116
126
|
|
|
117
|
-
# Override for HTTP mode (Fly.io / Smithery)
|
|
127
|
+
# Override for HTTP mode (Fly.io / Smithery / reverse-proxy deployments).
|
|
118
128
|
# ci-infra-01: gateway.py's _run_http defaults HOST to 127.0.0.1 (loopback), so
|
|
119
|
-
# without this the published image binds loopback and
|
|
120
|
-
#
|
|
121
|
-
#
|
|
122
|
-
#
|
|
129
|
+
# without this the published image binds loopback and orchestrators reaching the
|
|
130
|
+
# container over the network cannot connect. Because HOST=0.0.0.0 is non-loopback,
|
|
131
|
+
# the container refuses to start (exit 2) unless the operator passes
|
|
132
|
+
# TOOL_COMPASS_GATEWAY_AUTH_TOKEN (or sets gateway_auth_token in config), or sets
|
|
133
|
+
# TOOL_COMPASS_GATEWAY_ALLOW_NO_TOKEN=1 behind an authenticating proxy. Neither
|
|
134
|
+
# variable is set here so the image fails closed by default; /health stays exempt
|
|
135
|
+
# so the HEALTHCHECK below works with a token set.
|
|
123
136
|
ENV PORT=8080 \
|
|
124
137
|
HOST=0.0.0.0
|
|
125
138
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: tool-compass
|
|
3
|
-
Version: 2.5.
|
|
3
|
+
Version: 2.5.6
|
|
4
4
|
Summary: Semantic MCP tool discovery gateway - find tools by intent, not memory
|
|
5
5
|
Project-URL: Homepage, https://github.com/mcp-tool-shop-org/tool-compass
|
|
6
6
|
Project-URL: Documentation, https://github.com/mcp-tool-shop-org/tool-compass#readme
|
|
@@ -143,21 +143,31 @@ tool-compass ui
|
|
|
143
143
|
git clone https://github.com/mcp-tool-shop-org/tool-compass.git
|
|
144
144
|
cd tool-compass
|
|
145
145
|
|
|
146
|
-
# Start with Docker Compose (requires Ollama running locally)
|
|
147
|
-
docker
|
|
146
|
+
# Start with Docker Compose (requires Ollama running locally and a UI login)
|
|
147
|
+
GRADIO_AUTH=user:pass docker compose up
|
|
148
148
|
|
|
149
149
|
# Or include Ollama in the stack
|
|
150
|
-
docker
|
|
150
|
+
GRADIO_AUTH=user:pass docker compose --profile with-ollama up
|
|
151
151
|
|
|
152
152
|
# Access the UI at http://localhost:7860
|
|
153
153
|
```
|
|
154
154
|
|
|
155
|
-
Or run the published image directly, without cloning:
|
|
155
|
+
Or run the published UI image directly, without cloning:
|
|
156
156
|
|
|
157
157
|
```bash
|
|
158
|
-
docker run --rm -p 7860:7860
|
|
158
|
+
docker run --rm -p 7860:7860 \
|
|
159
|
+
-e GRADIO_AUTH=user:pass \
|
|
160
|
+
-v tool-compass-data:/app/tool_compass/db \
|
|
161
|
+
ghcr.io/mcp-tool-shop-org/tool-compass:ui
|
|
159
162
|
```
|
|
160
163
|
|
|
164
|
+
> **UI login required in containers.** Because the container binds `0.0.0.0`,
|
|
165
|
+
> startup refuses to run without a login. Start it in one of two ways: set
|
|
166
|
+
> `GRADIO_AUTH=user:pass` (via `.env`, shell environment, or `-e`), or set
|
|
167
|
+
> `TOOL_COMPASS_UI_ALLOW_NO_LOGIN=1` when deploying behind a reverse proxy that
|
|
168
|
+
> enforces its own login (prints a startup warning and hides the UI execute
|
|
169
|
+
> controls).
|
|
170
|
+
|
|
161
171
|
> **Mount the volume.** The semantic index lives in `/app/tool_compass/db`, and
|
|
162
172
|
> building it means embedding every tool in every configured server. Without a
|
|
163
173
|
> volume that work is thrown away when the container exits and paid again on the
|
|
@@ -169,6 +179,19 @@ docker run --rm -p 7860:7860 -v tool-compass-data:/app/tool_compass/db ghcr.
|
|
|
169
179
|
> `linux/amd64` and `linux/arm64`, so the same tag runs on x86_64 servers
|
|
170
180
|
> and Apple Silicon / ARM workstations.
|
|
171
181
|
|
|
182
|
+
To run the **MCP HTTP gateway** container (`mcp-gateway` stage, port `8080`), supply a bearer token — because the container binds `HOST=0.0.0.0`, it refuses to start without `TOOL_COMPASS_GATEWAY_AUTH_TOKEN` (or `TOOL_COMPASS_GATEWAY_ALLOW_NO_TOKEN=1` when behind an authenticating reverse proxy):
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
# Docker Compose (gateway profile)
|
|
186
|
+
TOOL_COMPASS_GATEWAY_AUTH_TOKEN=<your-token> docker compose --profile gateway up
|
|
187
|
+
|
|
188
|
+
# Or published gateway image directly
|
|
189
|
+
docker run --rm -p 8080:8080 \
|
|
190
|
+
-e TOOL_COMPASS_GATEWAY_AUTH_TOKEN=<your-token> \
|
|
191
|
+
-v tool-compass-data:/app/tool_compass/db \
|
|
192
|
+
ghcr.io/mcp-tool-shop-org/tool-compass:gateway
|
|
193
|
+
```
|
|
194
|
+
|
|
172
195
|
## Features
|
|
173
196
|
|
|
174
197
|
- **Hybrid Search** - Semantic (HNSW) + lexical fusion with exact-name boost — describe what you want, or paste a tool name and it ranks #1
|
|
@@ -289,7 +312,11 @@ The `hint` field in compass results guides this flow, suggesting when to use `de
|
|
|
289
312
|
| `OLLAMA_URL` | Ollama server URL | `http://localhost:11434` |
|
|
290
313
|
| `COMFYUI_URL` | ComfyUI server | `http://localhost:8188` |
|
|
291
314
|
| `PORT` | Set to enable HTTP transport (e.g., for Fly.io) | unset (stdio) |
|
|
292
|
-
| `
|
|
315
|
+
| `HOST` | Bind address for the HTTP transport; non-loopback values require `TOOL_COMPASS_GATEWAY_AUTH_TOKEN` (or `gateway_auth_token`) unless `TOOL_COMPASS_GATEWAY_ALLOW_NO_TOKEN=1` is set | `127.0.0.1` |
|
|
316
|
+
| `TOOL_COMPASS_GATEWAY_AUTH_TOKEN` | Bearer token for the HTTP transport (overrides `gateway_auth_token` in `compass_config.json`). Required when `HOST` is not loopback (`127.0.0.1`, `localhost`, `::1`); optional on loopback | unset (refuses off loopback) |
|
|
317
|
+
| `TOOL_COMPASS_GATEWAY_ALLOW_NO_TOKEN` | Set to `1` to allow binding the HTTP gateway off loopback without a bearer token when an authenticating reverse proxy sits in front (logs a warning on every start) | unset (disabled) |
|
|
318
|
+
| `GRADIO_AUTH` | UI login (`user:pass`); applied on every UI start when set, and required off loopback / in Docker / on `--share` | unset (loopback only) |
|
|
319
|
+
| `TOOL_COMPASS_UI_ALLOW_NO_LOGIN` | Set to `1` to allow starting the UI off loopback without `GRADIO_AUTH` behind an authenticating proxy (warns and hides execute controls) | unset |
|
|
293
320
|
|
|
294
321
|
**Default data directories:**
|
|
295
322
|
- **Windows:** `%LOCALAPPDATA%\tool-compass\`
|
|
@@ -98,21 +98,31 @@ tool-compass ui
|
|
|
98
98
|
git clone https://github.com/mcp-tool-shop-org/tool-compass.git
|
|
99
99
|
cd tool-compass
|
|
100
100
|
|
|
101
|
-
# Start with Docker Compose (requires Ollama running locally)
|
|
102
|
-
docker
|
|
101
|
+
# Start with Docker Compose (requires Ollama running locally and a UI login)
|
|
102
|
+
GRADIO_AUTH=user:pass docker compose up
|
|
103
103
|
|
|
104
104
|
# Or include Ollama in the stack
|
|
105
|
-
docker
|
|
105
|
+
GRADIO_AUTH=user:pass docker compose --profile with-ollama up
|
|
106
106
|
|
|
107
107
|
# Access the UI at http://localhost:7860
|
|
108
108
|
```
|
|
109
109
|
|
|
110
|
-
Or run the published image directly, without cloning:
|
|
110
|
+
Or run the published UI image directly, without cloning:
|
|
111
111
|
|
|
112
112
|
```bash
|
|
113
|
-
docker run --rm -p 7860:7860
|
|
113
|
+
docker run --rm -p 7860:7860 \
|
|
114
|
+
-e GRADIO_AUTH=user:pass \
|
|
115
|
+
-v tool-compass-data:/app/tool_compass/db \
|
|
116
|
+
ghcr.io/mcp-tool-shop-org/tool-compass:ui
|
|
114
117
|
```
|
|
115
118
|
|
|
119
|
+
> **UI login required in containers.** Because the container binds `0.0.0.0`,
|
|
120
|
+
> startup refuses to run without a login. Start it in one of two ways: set
|
|
121
|
+
> `GRADIO_AUTH=user:pass` (via `.env`, shell environment, or `-e`), or set
|
|
122
|
+
> `TOOL_COMPASS_UI_ALLOW_NO_LOGIN=1` when deploying behind a reverse proxy that
|
|
123
|
+
> enforces its own login (prints a startup warning and hides the UI execute
|
|
124
|
+
> controls).
|
|
125
|
+
|
|
116
126
|
> **Mount the volume.** The semantic index lives in `/app/tool_compass/db`, and
|
|
117
127
|
> building it means embedding every tool in every configured server. Without a
|
|
118
128
|
> volume that work is thrown away when the container exits and paid again on the
|
|
@@ -124,6 +134,19 @@ docker run --rm -p 7860:7860 -v tool-compass-data:/app/tool_compass/db ghcr.
|
|
|
124
134
|
> `linux/amd64` and `linux/arm64`, so the same tag runs on x86_64 servers
|
|
125
135
|
> and Apple Silicon / ARM workstations.
|
|
126
136
|
|
|
137
|
+
To run the **MCP HTTP gateway** container (`mcp-gateway` stage, port `8080`), supply a bearer token — because the container binds `HOST=0.0.0.0`, it refuses to start without `TOOL_COMPASS_GATEWAY_AUTH_TOKEN` (or `TOOL_COMPASS_GATEWAY_ALLOW_NO_TOKEN=1` when behind an authenticating reverse proxy):
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# Docker Compose (gateway profile)
|
|
141
|
+
TOOL_COMPASS_GATEWAY_AUTH_TOKEN=<your-token> docker compose --profile gateway up
|
|
142
|
+
|
|
143
|
+
# Or published gateway image directly
|
|
144
|
+
docker run --rm -p 8080:8080 \
|
|
145
|
+
-e TOOL_COMPASS_GATEWAY_AUTH_TOKEN=<your-token> \
|
|
146
|
+
-v tool-compass-data:/app/tool_compass/db \
|
|
147
|
+
ghcr.io/mcp-tool-shop-org/tool-compass:gateway
|
|
148
|
+
```
|
|
149
|
+
|
|
127
150
|
## Features
|
|
128
151
|
|
|
129
152
|
- **Hybrid Search** - Semantic (HNSW) + lexical fusion with exact-name boost — describe what you want, or paste a tool name and it ranks #1
|
|
@@ -244,7 +267,11 @@ The `hint` field in compass results guides this flow, suggesting when to use `de
|
|
|
244
267
|
| `OLLAMA_URL` | Ollama server URL | `http://localhost:11434` |
|
|
245
268
|
| `COMFYUI_URL` | ComfyUI server | `http://localhost:8188` |
|
|
246
269
|
| `PORT` | Set to enable HTTP transport (e.g., for Fly.io) | unset (stdio) |
|
|
247
|
-
| `
|
|
270
|
+
| `HOST` | Bind address for the HTTP transport; non-loopback values require `TOOL_COMPASS_GATEWAY_AUTH_TOKEN` (or `gateway_auth_token`) unless `TOOL_COMPASS_GATEWAY_ALLOW_NO_TOKEN=1` is set | `127.0.0.1` |
|
|
271
|
+
| `TOOL_COMPASS_GATEWAY_AUTH_TOKEN` | Bearer token for the HTTP transport (overrides `gateway_auth_token` in `compass_config.json`). Required when `HOST` is not loopback (`127.0.0.1`, `localhost`, `::1`); optional on loopback | unset (refuses off loopback) |
|
|
272
|
+
| `TOOL_COMPASS_GATEWAY_ALLOW_NO_TOKEN` | Set to `1` to allow binding the HTTP gateway off loopback without a bearer token when an authenticating reverse proxy sits in front (logs a warning on every start) | unset (disabled) |
|
|
273
|
+
| `GRADIO_AUTH` | UI login (`user:pass`); applied on every UI start when set, and required off loopback / in Docker / on `--share` | unset (loopback only) |
|
|
274
|
+
| `TOOL_COMPASS_UI_ALLOW_NO_LOGIN` | Set to `1` to allow starting the UI off loopback without `GRADIO_AUTH` behind an authenticating proxy (warns and hides execute controls) | unset |
|
|
248
275
|
|
|
249
276
|
**Default data directories:**
|
|
250
277
|
- **Windows:** `%LOCALAPPDATA%\tool-compass\`
|
|
@@ -61,8 +61,9 @@ Tool Compass is designed as a **local development tool**. It has these security
|
|
|
61
61
|
|
|
62
62
|
| Component | Security Model |
|
|
63
63
|
|-----------|----------------|
|
|
64
|
-
| Gradio UI |
|
|
65
|
-
| MCP Gateway |
|
|
64
|
+
| Gradio UI | Loopback (`127.0.0.1` / `localhost` / `::1`) has no login by default unless `GRADIO_AUTH` / `--auth` is set; non-loopback binds (including Docker) and `--share` require `GRADIO_AUTH=user:pass` (or `TOOL_COMPASS_UI_ALLOW_NO_LOGIN=1` behind an authenticating proxy, which warns and hides execute controls) |
|
|
65
|
+
| MCP Gateway (stdio) | Local subprocess transport; trusts configured backend servers |
|
|
66
|
+
| MCP Gateway (HTTP) | Binds `127.0.0.1` by default; off loopback refuses to start without `TOOL_COMPASS_GATEWAY_AUTH_TOKEN` (`gateway_auth_token`) or `TOOL_COMPASS_GATEWAY_ALLOW_NO_TOKEN=1` behind an authenticating proxy (`/health` and `/ready` remain unauthenticated for probes); trusts configured backend servers |
|
|
66
67
|
| Analytics DB | Local SQLite, no encryption |
|
|
67
68
|
| Embeddings | Sent to local Ollama |
|
|
68
69
|
|
|
@@ -70,14 +71,12 @@ Tool Compass is designed as a **local development tool**. It has these security
|
|
|
70
71
|
|
|
71
72
|
If deploying Tool Compass in a shared environment:
|
|
72
73
|
|
|
73
|
-
1. **
|
|
74
|
-
|
|
75
|
-
demo.launch(auth=("user", "password"))
|
|
76
|
-
```
|
|
74
|
+
1. **Configure UI login**:
|
|
75
|
+
Set `GRADIO_AUTH=user:pass` (or pass `tool-compass ui --auth user:pass`). Non-loopback binds and the Docker UI image refuse to start without `GRADIO_AUTH` unless `TOOL_COMPASS_UI_ALLOW_NO_LOGIN=1` is explicitly set behind a reverse proxy that enforces its own login (which prints a startup warning and hides the UI execute controls).
|
|
77
76
|
|
|
78
77
|
2. **Use environment variables** for sensitive config (not `compass_config.json`)
|
|
79
78
|
|
|
80
|
-
3. **Network isolation**: Run behind
|
|
79
|
+
3. **Network isolation and HTTP gateway auth**: Run behind an authenticating reverse proxy (`TOOL_COMPASS_UI_ALLOW_NO_LOGIN=1` if delegating UI login to the proxy). When the HTTP gateway binds off loopback (`HOST` not `127.0.0.1`, `localhost`, or `::1`), set `TOOL_COMPASS_GATEWAY_AUTH_TOKEN` (or `gateway_auth_token` in config, or `fly secrets set TOOL_COMPASS_GATEWAY_AUTH_TOKEN=<token>` on Fly.io); only set `TOOL_COMPASS_GATEWAY_ALLOW_NO_TOKEN=1` when a proxy in front enforces authentication and blocks direct access to the gateway port
|
|
81
80
|
|
|
82
81
|
4. **Rate limiting**: Add nginx/Cloudflare rate limiting for the UI
|
|
83
82
|
|