casper-network-mcp 0.1.0__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.
- casper_network_mcp-0.1.0/.github/workflows/ci.yml +72 -0
- casper_network_mcp-0.1.0/.github/workflows/release.yml +104 -0
- casper_network_mcp-0.1.0/.gitignore +10 -0
- casper_network_mcp-0.1.0/.mcp.json.example +9 -0
- casper_network_mcp-0.1.0/.python-version +1 -0
- casper_network_mcp-0.1.0/LICENSE +21 -0
- casper_network_mcp-0.1.0/NOTICE.md +202 -0
- casper_network_mcp-0.1.0/PKG-INFO +145 -0
- casper_network_mcp-0.1.0/README.md +130 -0
- casper_network_mcp-0.1.0/SECURITY.md +25 -0
- casper_network_mcp-0.1.0/THIRD_PARTY_NOTICES.md +55 -0
- casper_network_mcp-0.1.0/pyproject.toml +35 -0
- casper_network_mcp-0.1.0/scripts/bench_find_tool.py +107 -0
- casper_network_mcp-0.1.0/scripts/build_index.py +40 -0
- casper_network_mcp-0.1.0/scripts/build_manifests.py +52 -0
- casper_network_mcp-0.1.0/scripts/make_lock.py +74 -0
- casper_network_mcp-0.1.0/scripts/refresh_specs.py +255 -0
- casper_network_mcp-0.1.0/scripts/spec_pins.json +292 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/__init__.py +3 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/__main__.py +3 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/access.py +286 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/core/__init__.py +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/core/annotations.py +38 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/core/budget.py +456 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/core/errors.py +20 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/core/gate.py +166 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/core/http.py +313 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/core/kinds.py +397 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/core/logins.py +35 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/core/paths.py +82 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/core/redact.py +190 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/core/scope_ids.py +30 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/core/serve.py +82 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/core/url_validation.py +101 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/openapi_gen/__init__.py +16 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/openapi_gen/http_exec.py +79 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/openapi_gen/ir.py +514 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/openapi_gen/manifest.py +260 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/openapi_gen/manifests/central.json +98256 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/openapi_gen/manifests/clearpass.json +28633 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/openapi_gen/manifests/mist.json +53068 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/openapi_gen/naming.py +93 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/openapi_gen/runtime.py +444 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/__init__.py +25 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/_base.py +282 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/_tools.py +141 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/central/__init__.py +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/central/client.py +265 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/central/compat.py +458 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/central/config.py +3243 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/central/labels.yaml +253 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/central/monitoring.py +3692 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/central/nac.py +1087 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/central/ops.py +1078 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/central/reads.py +442 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/central/scope_maps.py +585 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/central/ssid.py +997 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/central/tools.py +32 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/clearpass/__init__.py +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/clearpass/client.py +45 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/clearpass/labels.yaml +34 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/clearpass/tools.py +553 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/mist/__init__.py +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/mist/_common.py +100 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/mist/alarms.py +77 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/mist/client.py +67 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/mist/events.py +140 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/mist/inventory.py +50 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/mist/labels.yaml +51 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/mist/marvis.py +43 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/mist/sle.py +85 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/mist/tools.py +727 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/products/specs_tools.py +111 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/py.typed +0 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/router/__init__.py +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/router/dispatch.py +103 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/router/exact.py +71 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/router/find.py +307 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/router/index.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/router/index.py +338 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/router/synonyms.yaml +133 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/sdk_compat.py +214 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/server.py +144 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/MANIFEST.json +475 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/NOTICE.md +178 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/application-experience-e2t121zmq0.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/assignments-efby11mq0s.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/central-nac-9a25qv24mq.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/central-nac-service-18et1xmq0s.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/clearpass-api-operations-318h42r1xm.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/clearpass-certificate-authority-1ajpg01cml.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/clearpass-endpoint-visibility-at4cgf25ml.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/clearpass-enforcement-profile-at4cgf1qml.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/clearpass-global-server-configuration-15btrd1aem.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/clearpass-guest-actions-15btrd12ml.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/clearpass-guest-configuration-at4cgfzml8.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/clearpass-identities-1wxkxoml85.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/clearpass-insight-318h42r1cm.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/clearpass-integrations-a48hf0fml8.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/clearpass-local-server-configuration-1ajpg031ml.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/clearpass-logs-a48hf0uml8.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/clearpass-platform-certificates-a48hf010ml.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/clearpass-policy-elements-a48hf01qml.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/clearpass-session-control-at4cgf25ml.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/clearpass-tools-and-utilities-at4cgf38ml.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/config-management-3zc1034mq0.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/configuration-health-b374ik1cmq.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/extensions-1bgu2cmq0s.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/firmware-policy-40jz1kmq0s.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/gateway-clustering-orchestration-1bgu2cmq0s.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/high-availability-3zc101qmq0.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/interfaces-1bgu1hmq0s.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/iot-2vuu5nz1bm.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/miscellaneous-e2t122vmq0.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/mist.openapi.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/monitoring-7wjo8aumqq.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/named-object-1bgu2jmq0s.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/network-services-3zc1034mq0.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/notifications-dpi09gmqqu.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/reporting-11dzpz39mq.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/roles-policy-3zc101qmq0.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/routing-overlays-40jzhmq0s5.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/scope-management-1fkx1wmq0s.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/security-efby2pmq0s.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/services-11dzpz39mq.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/services-tdgmkgmq0s.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/system-tdgmkhmq0s.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/telemetry-18etfmq0s6.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/troubleshooting-5v41h1vmqq.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/tunnels-tdgmkhmq0s.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/vlans-networks-40jz3amq0s.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs/wireless-efbynmq0s6.json +1 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs_bundle.py +152 -0
- casper_network_mcp-0.1.0/src/casper_network_mcp/specs_index.py +867 -0
- casper_network_mcp-0.1.0/tests/bench/find_tool_questions.yaml +193 -0
- casper_network_mcp-0.1.0/tests/conftest.py +226 -0
- casper_network_mcp-0.1.0/tests/products/test_backends.py +24 -0
- casper_network_mcp-0.1.0/tests/products/test_central_compat.py +174 -0
- casper_network_mcp-0.1.0/tests/products/test_central_tools.py +350 -0
- casper_network_mcp-0.1.0/tests/products/test_clearpass_tools.py +182 -0
- casper_network_mcp-0.1.0/tests/products/test_clients.py +228 -0
- casper_network_mcp-0.1.0/tests/products/test_mist_tools.py +363 -0
- casper_network_mcp-0.1.0/tests/products/test_overviews.py +203 -0
- casper_network_mcp-0.1.0/tests/redact_reviewed.txt +380 -0
- casper_network_mcp-0.1.0/tests/spec_branches.yaml +94 -0
- casper_network_mcp-0.1.0/tests/spec_check.py +319 -0
- casper_network_mcp-0.1.0/tests/test_access.py +323 -0
- casper_network_mcp-0.1.0/tests/test_boundary.py +38 -0
- casper_network_mcp-0.1.0/tests/test_budget.py +36 -0
- casper_network_mcp-0.1.0/tests/test_find_tool_bench.py +41 -0
- casper_network_mcp-0.1.0/tests/test_gate.py +139 -0
- casper_network_mcp-0.1.0/tests/test_http.py +84 -0
- casper_network_mcp-0.1.0/tests/test_kinds.py +152 -0
- casper_network_mcp-0.1.0/tests/test_labels.py +207 -0
- casper_network_mcp-0.1.0/tests/test_manifests.py +157 -0
- casper_network_mcp-0.1.0/tests/test_mcp_e2e.py +108 -0
- casper_network_mcp-0.1.0/tests/test_no_private_sdk_access.py +106 -0
- casper_network_mcp-0.1.0/tests/test_openapi_gen.py +441 -0
- casper_network_mcp-0.1.0/tests/test_paths.py +83 -0
- casper_network_mcp-0.1.0/tests/test_redact.py +161 -0
- casper_network_mcp-0.1.0/tests/test_release_files.py +119 -0
- casper_network_mcp-0.1.0/tests/test_router_cursor.py +184 -0
- casper_network_mcp-0.1.0/tests/test_router_dispatch.py +160 -0
- casper_network_mcp-0.1.0/tests/test_router_index.py +92 -0
- casper_network_mcp-0.1.0/tests/test_router_response_budget.py +85 -0
- casper_network_mcp-0.1.0/tests/test_router_surface.py +94 -0
- casper_network_mcp-0.1.0/tests/test_shared_transport.py +186 -0
- casper_network_mcp-0.1.0/tests/test_spec.py +144 -0
- casper_network_mcp-0.1.0/tests/test_specs_bundle.py +181 -0
- casper_network_mcp-0.1.0/tests/test_specs_index.py +333 -0
- casper_network_mcp-0.1.0/tests/test_specs_tools.py +45 -0
- casper_network_mcp-0.1.0/tests/test_wheel.py +139 -0
- casper_network_mcp-0.1.0/uv.lock +1291 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
test:
|
|
13
|
+
name: Tests (${{ matrix.os }}, Python ${{ matrix.python }})
|
|
14
|
+
strategy:
|
|
15
|
+
fail-fast: false
|
|
16
|
+
matrix:
|
|
17
|
+
os: [ubuntu-latest, macos-latest]
|
|
18
|
+
python: ["3.11", "3.13"]
|
|
19
|
+
runs-on: ${{ matrix.os }}
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
with:
|
|
23
|
+
persist-credentials: false
|
|
24
|
+
- uses: astral-sh/setup-uv@v6
|
|
25
|
+
with:
|
|
26
|
+
python-version: ${{ matrix.python }}
|
|
27
|
+
- name: Install
|
|
28
|
+
run: uv sync --locked
|
|
29
|
+
- name: Lint
|
|
30
|
+
run: uv run ruff check .
|
|
31
|
+
- name: Types
|
|
32
|
+
run: uv run mypy src/casper_network_mcp/core src/casper_network_mcp/access.py src/casper_network_mcp/router
|
|
33
|
+
- name: Generated files are current
|
|
34
|
+
run: |
|
|
35
|
+
uv run python scripts/build_manifests.py --check
|
|
36
|
+
uv run python scripts/build_index.py --check
|
|
37
|
+
- name: Tests (boundary, spec check, labels, find_tool bench, wheel)
|
|
38
|
+
run: uv run pytest -q
|
|
39
|
+
- name: Build
|
|
40
|
+
run: uv build
|
|
41
|
+
|
|
42
|
+
scrub:
|
|
43
|
+
name: Nothing personal, no RAG, no env files
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v4
|
|
47
|
+
with:
|
|
48
|
+
persist-credentials: false
|
|
49
|
+
- name: Generic scrub greps
|
|
50
|
+
shell: bash
|
|
51
|
+
run: |
|
|
52
|
+
# Vendor documents (and the manifests built from them) are upstream bytes pinned by hash,
|
|
53
|
+
# so they are left out of the address and word checks. The boundary and wheel tests hold deny lists.
|
|
54
|
+
files() {
|
|
55
|
+
git ls-files -z -- . \
|
|
56
|
+
':!:src/casper_network_mcp/specs/*.json' \
|
|
57
|
+
':!:src/casper_network_mcp/openapi_gen/manifests/*.json' \
|
|
58
|
+
':!:.github/**' ':!:uv.lock' ':!:tests/test_boundary.py' ':!:tests/test_specs_bundle.py' \
|
|
59
|
+
':!:tests/test_wheel.py'
|
|
60
|
+
}
|
|
61
|
+
fail=0
|
|
62
|
+
check() {
|
|
63
|
+
if files | xargs -0 grep -nE $3 "$2"; then echo "::error::$1"; fail=1; fi
|
|
64
|
+
}
|
|
65
|
+
check "private (RFC 1918) address; use 192.0.2.x, 198.51.100.x or 203.0.113.x" \
|
|
66
|
+
'\b(10\.[0-9]+\.[0-9]+\.[0-9]+|172\.(1[6-9]|2[0-9]|3[01])\.[0-9]+\.[0-9]+|192\.168\.[0-9]+\.[0-9]+)\b'
|
|
67
|
+
check "home path" '/Users/|~/\.mist-lab'
|
|
68
|
+
check "env file loading" 'dotenv|load_dotenv'
|
|
69
|
+
check "RAG or scraper word" 'ingestion|scrape|playwright|lancedb|fastembed|ollama|milvus|\bredis\b' -i
|
|
70
|
+
check "browser identity" 'User-Agent.*(Safari|Mozilla)' -i
|
|
71
|
+
check "personal address" '@gmail|\.local\b'
|
|
72
|
+
exit $fail
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# A v* tag builds the wheel, writes the hash-locked install file, checks that file installs with
|
|
4
|
+
# Casper's exact command on every supported system, then publishes those same files.
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
tags: ["v*"]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
with:
|
|
18
|
+
persist-credentials: false
|
|
19
|
+
- uses: astral-sh/setup-uv@v6
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.11"
|
|
22
|
+
- name: Tag matches the package version
|
|
23
|
+
shell: bash
|
|
24
|
+
run: |
|
|
25
|
+
version="$(uv run --frozen python -c 'import casper_network_mcp as m; print(m.__version__)')"
|
|
26
|
+
test "v${version}" = "${GITHUB_REF_NAME}"
|
|
27
|
+
echo "VERSION=${version}" >> "$GITHUB_ENV"
|
|
28
|
+
- name: Build
|
|
29
|
+
run: uv build
|
|
30
|
+
- name: Lock file from the built wheel
|
|
31
|
+
run: uv run --frozen python scripts/make_lock.py "$VERSION" --dist dist --out casper-network-mcp.lock.txt
|
|
32
|
+
- uses: actions/upload-artifact@v4
|
|
33
|
+
with:
|
|
34
|
+
name: dist
|
|
35
|
+
path: dist/
|
|
36
|
+
- uses: actions/upload-artifact@v4
|
|
37
|
+
with:
|
|
38
|
+
name: lock
|
|
39
|
+
path: casper-network-mcp.lock.txt
|
|
40
|
+
|
|
41
|
+
check-lock:
|
|
42
|
+
needs: build
|
|
43
|
+
strategy:
|
|
44
|
+
fail-fast: true
|
|
45
|
+
matrix:
|
|
46
|
+
os: [ubuntu-latest, macos-latest]
|
|
47
|
+
python: ["3.11", "3.13"]
|
|
48
|
+
runs-on: ${{ matrix.os }}
|
|
49
|
+
steps:
|
|
50
|
+
- uses: astral-sh/setup-uv@v6
|
|
51
|
+
with:
|
|
52
|
+
python-version: ${{ matrix.python }}
|
|
53
|
+
- uses: actions/download-artifact@v4
|
|
54
|
+
with:
|
|
55
|
+
name: dist
|
|
56
|
+
path: dist
|
|
57
|
+
- uses: actions/download-artifact@v4
|
|
58
|
+
with:
|
|
59
|
+
name: lock
|
|
60
|
+
- name: Install with Casper's command into an empty environment
|
|
61
|
+
shell: bash
|
|
62
|
+
run: |
|
|
63
|
+
uv venv --python "${{ matrix.python }}" "$RUNNER_TEMP/venv"
|
|
64
|
+
uv pip install --require-hashes --no-deps --only-binary :all: --find-links dist \
|
|
65
|
+
--python "$RUNNER_TEMP/venv/bin/python" -r casper-network-mcp.lock.txt
|
|
66
|
+
- name: Runs with no logins
|
|
67
|
+
shell: bash
|
|
68
|
+
working-directory: ${{ runner.temp }}
|
|
69
|
+
run: env -i PATH=/usr/bin:/bin HOME="$RUNNER_TEMP" "$RUNNER_TEMP/venv/bin/casper-network-mcp" --help
|
|
70
|
+
|
|
71
|
+
publish:
|
|
72
|
+
needs: [build, check-lock]
|
|
73
|
+
runs-on: ubuntu-latest
|
|
74
|
+
environment: pypi
|
|
75
|
+
permissions:
|
|
76
|
+
id-token: write
|
|
77
|
+
steps:
|
|
78
|
+
- uses: actions/download-artifact@v4
|
|
79
|
+
with:
|
|
80
|
+
name: dist
|
|
81
|
+
path: dist
|
|
82
|
+
- name: Publish to PyPI (trusted publishing)
|
|
83
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
84
|
+
|
|
85
|
+
attach-lock:
|
|
86
|
+
needs: [publish]
|
|
87
|
+
runs-on: ubuntu-latest
|
|
88
|
+
permissions:
|
|
89
|
+
contents: write
|
|
90
|
+
steps:
|
|
91
|
+
- uses: actions/download-artifact@v4
|
|
92
|
+
with:
|
|
93
|
+
name: lock
|
|
94
|
+
- uses: actions/download-artifact@v4
|
|
95
|
+
with:
|
|
96
|
+
name: dist
|
|
97
|
+
path: dist
|
|
98
|
+
- name: Attach the lock file and wheel to the GitHub release
|
|
99
|
+
env:
|
|
100
|
+
GH_TOKEN: ${{ github.token }}
|
|
101
|
+
run: |
|
|
102
|
+
gh release create "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" --title "$GITHUB_REF_NAME" \
|
|
103
|
+
--notes "Install with Casper, or: uv pip install --require-hashes --no-deps --only-binary :all: -r casper-network-mcp.lock.txt" \
|
|
104
|
+
casper-network-mcp.lock.txt dist/*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.11
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Choaterboater
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# Notices
|
|
2
|
+
|
|
3
|
+
casper-network-mcp's own code is under the MIT licence in `LICENSE`. The package also ships material that is not
|
|
4
|
+
covered by that licence:
|
|
5
|
+
|
|
6
|
+
- **HPE Aruba Networking's API documents** (30 New Central and 16 ClearPass OpenAPI documents in
|
|
7
|
+
`src/casper_network_mcp/specs/`). They are proprietary HPE material, not open source. Section A and C below say
|
|
8
|
+
on what basis they are redistributed.
|
|
9
|
+
- **Juniper Mist's OpenAPI document** (`mist.openapi.json`), under the MIT licence reproduced in section B below.
|
|
10
|
+
- **Files built from those documents**: the generated tool lists in
|
|
11
|
+
`src/casper_network_mcp/openapi_gen/manifests/` and find_tool's word index in
|
|
12
|
+
`src/casper_network_mcp/router/index.json` hold operation ids, paths, parameter names, and the operation and
|
|
13
|
+
parameter summaries and full descriptions, taken word for word from the documents. What came from HPE's
|
|
14
|
+
documents stays under the terms in sections A and C; what came from Mist's document stays under section B's MIT
|
|
15
|
+
licence. Removing a document (sections A and C) therefore also means removing its entries from those files: after
|
|
16
|
+
deleting the document and its `specs/MANIFEST.json` entry from `specs/`, and its pins from `scripts/spec_pins.json`, run
|
|
17
|
+
`scripts/build_manifests.py` and `scripts/build_index.py` and commit what they write. The tests that compare
|
|
18
|
+
the generated tools with the bundled documents, and `lookup_api`, then cover only the documents that are left.
|
|
19
|
+
- **Code adapted from other MIT projects**: see `THIRD_PARTY_NOTICES.md`.
|
|
20
|
+
|
|
21
|
+
The rest of this file is `src/casper_network_mcp/specs/NOTICE.md`, word for word (a test keeps the two the same).
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Third-party notice — bundled OpenAPI documents
|
|
26
|
+
|
|
27
|
+
`casper_network_mcp/specs/` holds **47 OpenAPI documents from two upstreams under
|
|
28
|
+
two different licensing regimes.** They are not interchangeable, and the
|
|
29
|
+
difference matters if you redistribute this package.
|
|
30
|
+
|
|
31
|
+
| Files | Upstream | Licence | Section |
|
|
32
|
+
| --- | --- | --- | --- |
|
|
33
|
+
| 30 New Central documents (everything except `mist.openapi.json` and `clearpass-*.json`) | HPE Aruba Networking developer portal | **Proprietary HPE material. Not open source.** | [A](#a--the-30-new-central-documents) |
|
|
34
|
+
| `mist.openapi.json` | `mistsys/mist_openapi` on GitHub | **MIT** — full text reproduced below | [B](#b--mistopenapijson) |
|
|
35
|
+
| 16 ClearPass documents (`clearpass-*.json`) | HPE Aruba Networking developer portal | **Proprietary HPE material. Not open source.** | [C](#c--the-16-clearpass-documents) |
|
|
36
|
+
|
|
37
|
+
Every file is stored as the exact bytes the upstream served. `MANIFEST.json`
|
|
38
|
+
beside this file records, for each one, the URL actually fetched, the date,
|
|
39
|
+
the SHA-256 of those bytes and the number of API paths.
|
|
40
|
+
`scripts/refresh_specs.py` fetches them again; `--check` re-fetches and
|
|
41
|
+
confirms every hash without writing anything.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## A — the 30 New Central documents
|
|
46
|
+
|
|
47
|
+
### What they are
|
|
48
|
+
|
|
49
|
+
30 OpenAPI 3.x documents describing the HPE Aruba Networking **New Central**
|
|
50
|
+
REST API — 779 API paths in total. They are the API descriptions the
|
|
51
|
+
developer portal itself serves to render its reference pages. They are **not**
|
|
52
|
+
documentation we wrote, and they are not derived, summarised or regenerated:
|
|
53
|
+
each file is the upstream document byte for byte.
|
|
54
|
+
|
|
55
|
+
### Who publishes them, and where they came from
|
|
56
|
+
|
|
57
|
+
Hewlett Packard Enterprise / Aruba Networking, at
|
|
58
|
+
<https://developer.arubanetworks.com/>. The portal runs on ReadMe, and each
|
|
59
|
+
reference page points at an API-registry document.
|
|
60
|
+
|
|
61
|
+
They were fetched from HPE's public developer-portal API registry by
|
|
62
|
+
`scripts/refresh_specs.py`, straight from
|
|
63
|
+
`https://dash.readme.com/api/v1/api-registry/<registry_id>`, which needs no
|
|
64
|
+
login. The script names this project in its User-Agent and sends no browser
|
|
65
|
+
headers and no cookies. Each file's URL, date and sha256 are in
|
|
66
|
+
MANIFEST.json; `reference_page` there is the developer-portal page the
|
|
67
|
+
document backs. The registry ids are pinned in `scripts/spec_pins.json`.
|
|
68
|
+
|
|
69
|
+
### Licence and redistribution basis
|
|
70
|
+
|
|
71
|
+
**These 30 documents are proprietary HPE Aruba Networking material. They are
|
|
72
|
+
not open source, and this repository's MIT licence does not extend to them.**
|
|
73
|
+
|
|
74
|
+
HPE publishes them without an accompanying licence grant and without an
|
|
75
|
+
authentication barrier, as the machine-readable form of public API reference
|
|
76
|
+
documentation whose entire purpose is to be consumed by API clients. They are
|
|
77
|
+
redistributed here verbatim, with attribution and provenance, so that
|
|
78
|
+
`lookup_api` answers exact API questions from a clean clone with no network
|
|
79
|
+
access — the same use the publisher intends, moved offline.
|
|
80
|
+
|
|
81
|
+
This is a good-faith reliance on published-for-integration intent, not a
|
|
82
|
+
licence. Specifically:
|
|
83
|
+
|
|
84
|
+
- No warranty and no endorsement by HPE is claimed or implied.
|
|
85
|
+
- "HPE", "Aruba", "Aruba Networking" and "New Central" are marks of Hewlett
|
|
86
|
+
Packard Enterprise, used here only to identify the API being described.
|
|
87
|
+
- If HPE asks for these documents to be removed, remove them. Nothing outside
|
|
88
|
+
this directory depends on the files being *committed* —
|
|
89
|
+
`scripts/refresh_specs.py` reproduces them from the upstream portal, and
|
|
90
|
+
`scripts/spec_pins.json` keeps the pointers.
|
|
91
|
+
|
|
92
|
+
Downstream users redistributing this repository inherit that position and
|
|
93
|
+
should make their own assessment.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## B — `mist.openapi.json`
|
|
98
|
+
|
|
99
|
+
### What it is
|
|
100
|
+
|
|
101
|
+
One OpenAPI 3.1.0 document describing the entire **Juniper Mist** REST API —
|
|
102
|
+
762 API paths, `info.version` `2610.1.0`. It is the upstream
|
|
103
|
+
file byte for byte.
|
|
104
|
+
|
|
105
|
+
### Who publishes it, and where it came from
|
|
106
|
+
|
|
107
|
+
Mist Systems / Juniper Networks, at <https://github.com/mistsys/mist_openapi>.
|
|
108
|
+
|
|
109
|
+
Pinned to commit
|
|
110
|
+
[`79274e6cd85327ef51a9ab99a9c40a999d4b669a`](https://github.com/mistsys/mist_openapi/commit/79274e6cd85327ef51a9ab99a9c40a999d4b669a)
|
|
111
|
+
and fetched by `scripts/refresh_specs.py` from the immutable raw URL
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
https://raw.githubusercontent.com/mistsys/mist_openapi/79274e6cd85327ef51a9ab99a9c40a999d4b669a/mist.openapi.json
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
A branch URL is deliberately not used: it changes under you, so it could not
|
|
118
|
+
pin anything.
|
|
119
|
+
|
|
120
|
+
### Licence
|
|
121
|
+
|
|
122
|
+
MIT, per the `LICENSE` file at the pinned commit. Reproduced in full as MIT
|
|
123
|
+
requires:
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
MIT License
|
|
127
|
+
|
|
128
|
+
Copyright (c) 2020 Thomas Munzer
|
|
129
|
+
|
|
130
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
131
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
132
|
+
in the Software without restriction, including without limitation the rights
|
|
133
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
134
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
135
|
+
furnished to do so, subject to the following conditions:
|
|
136
|
+
|
|
137
|
+
The above copyright notice and this permission notice shall be included in all
|
|
138
|
+
copies or substantial portions of the Software.
|
|
139
|
+
|
|
140
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
141
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
142
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
143
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
144
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
145
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
146
|
+
SOFTWARE.
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Source: <https://raw.githubusercontent.com/mistsys/mist_openapi/79274e6cd85327ef51a9ab99a9c40a999d4b669a/LICENSE>.
|
|
150
|
+
"Juniper", "Mist" and "Marvis" are marks of Juniper Networks, used here only to
|
|
151
|
+
identify the API being described. No endorsement by Juniper is claimed.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## C — the 16 ClearPass documents
|
|
156
|
+
|
|
157
|
+
### What they are
|
|
158
|
+
|
|
159
|
+
16 OpenAPI 3.0 documents describing the HPE Aruba Networking **ClearPass
|
|
160
|
+
Policy Manager** REST API (`info.version` 6.12.7) — 335 API paths in total.
|
|
161
|
+
They are the API descriptions the developer portal itself serves to render
|
|
162
|
+
its ClearPass reference pages. Like section A's files, each one is the
|
|
163
|
+
upstream document byte for byte, not documentation we wrote. Their paths are
|
|
164
|
+
relative to the ClearPass server's `/api` base.
|
|
165
|
+
|
|
166
|
+
### Who publishes them, and where they came from
|
|
167
|
+
|
|
168
|
+
Hewlett Packard Enterprise / Aruba Networking, at
|
|
169
|
+
<https://developer.arubanetworks.com/cppm/reference>.
|
|
170
|
+
|
|
171
|
+
They were fetched the same way as section A's files: by
|
|
172
|
+
`scripts/refresh_specs.py`, straight from
|
|
173
|
+
`https://dash.readme.com/api/v1/api-registry/<registry_id>`, which needs no
|
|
174
|
+
login, with a User-Agent naming this project and no browser headers or
|
|
175
|
+
cookies. Each file's URL, date and sha256 are in MANIFEST.json; the registry
|
|
176
|
+
ids are pinned in `scripts/spec_pins.json` under `clearpass`.
|
|
177
|
+
|
|
178
|
+
### Licence and redistribution basis
|
|
179
|
+
|
|
180
|
+
**These 16 documents are proprietary HPE Aruba Networking material. They are
|
|
181
|
+
not open source, and this repository's MIT licence does not extend to them.**
|
|
182
|
+
|
|
183
|
+
HPE publishes them without an accompanying licence grant and without an
|
|
184
|
+
authentication barrier, as the machine-readable form of public API reference
|
|
185
|
+
documentation whose entire purpose is to be consumed by API clients. They are
|
|
186
|
+
redistributed here verbatim, with attribution and provenance, so that
|
|
187
|
+
`lookup_api` answers exact API questions from a clean clone with no network
|
|
188
|
+
access — the same use the publisher intends, moved offline.
|
|
189
|
+
|
|
190
|
+
This is a good-faith reliance on published-for-integration intent, not a
|
|
191
|
+
licence. Specifically:
|
|
192
|
+
|
|
193
|
+
- No warranty and no endorsement by HPE is claimed or implied.
|
|
194
|
+
- "HPE", "Aruba", "Aruba Networking" and "ClearPass" are marks of Hewlett
|
|
195
|
+
Packard Enterprise, used here only to identify the API being described.
|
|
196
|
+
- If HPE asks for these documents to be removed, remove them. Nothing outside
|
|
197
|
+
this directory depends on the files being *committed* —
|
|
198
|
+
`scripts/refresh_specs.py` reproduces them from the upstream portal, and
|
|
199
|
+
`scripts/spec_pins.json` keeps the pointers.
|
|
200
|
+
|
|
201
|
+
Downstream users redistributing this repository inherit that position and
|
|
202
|
+
should make their own assessment.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: casper-network-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: One small MCP router for HPE Aruba Networking Central, Juniper Mist and ClearPass, built for Casper.
|
|
5
|
+
License-Expression: MIT AND LicenseRef-HPE-API-Documentation
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
License-File: NOTICE.md
|
|
8
|
+
License-File: THIRD_PARTY_NOTICES.md
|
|
9
|
+
License-File: src/casper_network_mcp/specs/NOTICE.md
|
|
10
|
+
Requires-Python: >=3.11
|
|
11
|
+
Requires-Dist: httpx<1,>=0.27
|
|
12
|
+
Requires-Dist: mcp[cli]<3,>=2.0
|
|
13
|
+
Requires-Dist: pyyaml<7,>=6
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# casper-network-mcp
|
|
17
|
+
|
|
18
|
+
One small MCP server for HPE Aruba Networking Central, Juniper Mist and HPE Aruba Networking ClearPass, built for
|
|
19
|
+
[Casper](https://github.com/Choaterboater/casper). Your AI sees four tools; behind them are about 3,900 tools for the
|
|
20
|
+
three products, each one labelled with the kind of change it makes.
|
|
21
|
+
|
|
22
|
+
You normally never install this yourself: Casper sets it up, pins the exact version and starts it for you.
|
|
23
|
+
|
|
24
|
+
## What it does
|
|
25
|
+
|
|
26
|
+
| Tool | What it is for |
|
|
27
|
+
| --- | --- |
|
|
28
|
+
| `find_tool` | Finds the right tool for what you asked ("bounce port 7 on the closet switch") and says what kind of change it makes: read, troubleshoot, config, disruptive, firmware, delete or admin. |
|
|
29
|
+
| `invoke_read_tool` | Runs a tool that only reads, or a check that changes nothing. Anything else is refused. |
|
|
30
|
+
| `invoke_tool` | Runs any tool, including ones that change your network. Casper asks you first. |
|
|
31
|
+
| `access_check` | Says, for each product, whether a login is set and where that login can change things. |
|
|
32
|
+
|
|
33
|
+
Behind them:
|
|
34
|
+
|
|
35
|
+
- hand-written tools for everyday work (sites, clients, alarms, switch ports, guests, sessions, SSIDs, VLANs and
|
|
36
|
+
more), each one checked against the vendor's own API description;
|
|
37
|
+
- one generated tool for every operation in the bundled API descriptions;
|
|
38
|
+
- overview tools for broad questions: `central_site_overview`, `mist_site_overview` and `clearpass_overview` give
|
|
39
|
+
health, device counts and the top alarms in one read;
|
|
40
|
+
- `lookup_api`, which answers exact questions about the vendors' APIs (endpoints, fields, allowed values) from the
|
|
41
|
+
bundled documents, with no network.
|
|
42
|
+
|
|
43
|
+
## Running it
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
uvx --from casper-network-mcp==0.1.0 casper-network-mcp --read-only
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
| Option | Meaning |
|
|
50
|
+
| --- | --- |
|
|
51
|
+
| `--read-only` | Only read and run checks; never send a change. Read once at start: nothing turns writes on while it runs. Casper passes this until you allow changes. |
|
|
52
|
+
| `--transport stdio` | The default: talk over standard input and output. |
|
|
53
|
+
| `--transport http --port 8010` | Listen on this machine only (`127.0.0.1`). |
|
|
54
|
+
|
|
55
|
+
From a checkout, `.mcp.json.example` starts it read-only with `uv run`; logins come from your shell.
|
|
56
|
+
|
|
57
|
+
## Logins
|
|
58
|
+
|
|
59
|
+
The server reads only these variables from the environment Casper starts it with. It reads no settings files.
|
|
60
|
+
Leave out a product you do not use: the server still starts, `access_check` says that login is missing, and a call
|
|
61
|
+
to one of its tools answers `{"error": "login_missing", "product": "..."}`.
|
|
62
|
+
|
|
63
|
+
| Product | Variables |
|
|
64
|
+
| --- | --- |
|
|
65
|
+
| Juniper Mist | `MIST_API_TOKEN`, and `MIST_HOST` if your cloud is not `api.mist.com` |
|
|
66
|
+
| HPE Aruba Networking Central | `CENTRAL_BASE_URL`, `CENTRAL_CLIENT_ID`, `CENTRAL_CLIENT_SECRET` |
|
|
67
|
+
| HPE Aruba Networking ClearPass | `CLEARPASS_BASE_URL`, `CLEARPASS_API_TOKEN` |
|
|
68
|
+
|
|
69
|
+
## Changes to your network
|
|
70
|
+
|
|
71
|
+
There are no write switches. What a login may do is set by its role in the product, and Casper asks you before
|
|
72
|
+
every change, showing the tool and what it changes. On top of that:
|
|
73
|
+
|
|
74
|
+
- `--read-only` refuses every change before anything is sent;
|
|
75
|
+
- a path piece that could reach somewhere else (`/`, `?`, `#`, `..`) is refused before anything is sent;
|
|
76
|
+
- when the server knows a Mist login can only read a site, a change to that site is refused before anything is
|
|
77
|
+
sent;
|
|
78
|
+
- tools that disrupt the network (reboots, port and PoE bounces, disconnects) are labelled disruptive, so Casper
|
|
79
|
+
asks every time;
|
|
80
|
+
- tokens, passwords and pre-shared keys are hidden in replies and errors.
|
|
81
|
+
|
|
82
|
+
The server never asks you to type anything and never treats an argument the AI sets as your approval. Approval is
|
|
83
|
+
Casper's box only.
|
|
84
|
+
|
|
85
|
+
## How well find_tool finds tools
|
|
86
|
+
|
|
87
|
+
`find_tool` was measured on a fixed set of 60 plain questions (20 each for Central, Mist and ClearPass, in
|
|
88
|
+
`tests/bench/find_tool_questions.yaml`), then tuned one change at a time. A change stayed only if it found more
|
|
89
|
+
right tools in the top 3, or answered faster without finding fewer. Run `uv run python scripts/bench_find_tool.py`
|
|
90
|
+
to measure it yourself.
|
|
91
|
+
|
|
92
|
+
| | Right tool first | Right tool in top 3 | Top 3, no product given | Time per question (p50 / p95) | First question in a new process |
|
|
93
|
+
| --- | --- | --- | --- | --- | --- |
|
|
94
|
+
| Before | 67% | 77% | 68% | 0.6 / 1.6 ms | 3.4 s |
|
|
95
|
+
| After | 85% | 100% | 90% | 0.6 / 2.0 ms | 0.4 s |
|
|
96
|
+
|
|
97
|
+
What changed, in order:
|
|
98
|
+
|
|
99
|
+
1. Synonyms (`router/synonyms.yaml`) and plural folding: "access point" finds `ap`, "kick" finds disconnect, "who is
|
|
100
|
+
on" finds clients. Top 3: 77% to 97%.
|
|
101
|
+
2. Ranking by what the question asks: "what" and "show" prefer tools that read, "create", "delete" and "change"
|
|
102
|
+
prefer those changes; the product name in a tool's name no longer counts against it. Top 3: 97% to 98%, first
|
|
103
|
+
pick 75% to 87%. (Weighting name words over description words was tried and dropped: top 3 fell to 90-95%.)
|
|
104
|
+
3. A prebuilt word index shipped in the package (`router/index.json`): the first question no longer loads every
|
|
105
|
+
tool. First question: 3.4 s to 0.4 s.
|
|
106
|
+
4. Overview tools for broad questions (`central_site_overview`, `mist_site_overview`, `clearpass_overview`: health,
|
|
107
|
+
device counts and top alarms in one read) and `mist_list_site_clients` for "who is on the wifi". A synonym that
|
|
108
|
+
spreads into several words ("wifi" to wlan, ssid, wireless) now counts once. Top 3: 98% to 100%.
|
|
109
|
+
|
|
110
|
+
Times are on a laptop with the router already loaded, except the last column.
|
|
111
|
+
|
|
112
|
+
## What is in the package
|
|
113
|
+
|
|
114
|
+
The package includes HPE's proprietary API documents (not MIT; see specs/NOTICE.md) and Juniper Mist's MIT
|
|
115
|
+
OpenAPI file. They are stored exactly as the vendors serve them; `scripts/refresh_specs.py --check` fetches them
|
|
116
|
+
again and confirms every hash. See `NOTICE.md` and `THIRD_PARTY_NOTICES.md`.
|
|
117
|
+
|
|
118
|
+
The package has no install step, downloads nothing when it starts and never updates itself.
|
|
119
|
+
|
|
120
|
+
## Working on it
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
uv sync
|
|
124
|
+
uv run pytest -q
|
|
125
|
+
uv run ruff check .
|
|
126
|
+
uv run python scripts/bench_find_tool.py # find_tool accuracy and speed
|
|
127
|
+
uv run python scripts/build_manifests.py # after the bundled specs change
|
|
128
|
+
uv run python scripts/build_index.py # after any tool changes
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
A release is built from a `v*` tag: the wheel, then `casper-network-mcp.lock.txt` (every dependency pinned by hash,
|
|
132
|
+
plus this package pinned to the wheel's own hash, made by `scripts/make_lock.py`). The release checks that lock
|
|
133
|
+
installs with Casper's exact command before publishing:
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
uv pip install --require-hashes --no-deps --only-binary :all: -r casper-network-mcp.lock.txt
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Security
|
|
140
|
+
|
|
141
|
+
Report problems privately; see `SECURITY.md`.
|
|
142
|
+
|
|
143
|
+
## Licence
|
|
144
|
+
|
|
145
|
+
MIT for this project's code (`LICENSE`). The bundled vendor documents keep their own terms (`NOTICE.md`).
|