vrx-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.
Files changed (73) hide show
  1. vrx_mcp-0.1.0/.env.example +12 -0
  2. vrx_mcp-0.1.0/.github/workflows/ci.yml +16 -0
  3. vrx_mcp-0.1.0/.github/workflows/release.yml +46 -0
  4. vrx_mcp-0.1.0/.gitignore +14 -0
  5. vrx_mcp-0.1.0/CHANGELOG.md +7 -0
  6. vrx_mcp-0.1.0/CONTRIBUTING.md +51 -0
  7. vrx_mcp-0.1.0/LICENSE +21 -0
  8. vrx_mcp-0.1.0/PKG-INFO +292 -0
  9. vrx_mcp-0.1.0/README.md +257 -0
  10. vrx_mcp-0.1.0/docs/ENDPOINTS.md +92 -0
  11. vrx_mcp-0.1.0/pyproject.toml +70 -0
  12. vrx_mcp-0.1.0/scripts/generate_from_openapi.py +364 -0
  13. vrx_mcp-0.1.0/scripts/run.ps1 +1 -0
  14. vrx_mcp-0.1.0/scripts/run.sh +3 -0
  15. vrx_mcp-0.1.0/scripts/setup.ps1 +2 -0
  16. vrx_mcp-0.1.0/scripts/setup.sh +4 -0
  17. vrx_mcp-0.1.0/src/vrx_mcp/__init__.py +5 -0
  18. vrx_mcp-0.1.0/src/vrx_mcp/client.py +159 -0
  19. vrx_mcp-0.1.0/src/vrx_mcp/config.py +87 -0
  20. vrx_mcp-0.1.0/src/vrx_mcp/errors.py +23 -0
  21. vrx_mcp-0.1.0/src/vrx_mcp/server.py +71 -0
  22. vrx_mcp-0.1.0/src/vrx_mcp/tools/__init__.py +16 -0
  23. vrx_mcp-0.1.0/src/vrx_mcp/tools/_common.py +49 -0
  24. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/__init__.py +45 -0
  25. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/aggregation.py +56 -0
  26. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/automation.py +74 -0
  27. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/automation_task_templates.py +39 -0
  28. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/automations.py +65 -0
  29. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/date.py +22 -0
  30. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/endpoint.py +44 -0
  31. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/endpoint_attributes.py +44 -0
  32. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/endpoint_vulnerability.py +49 -0
  33. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/external_reference_external_references.py +42 -0
  34. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/incident_event.py +49 -0
  35. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/operating_system_family.py +32 -0
  36. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/organization_endpoint_external_reference_external_references.py +30 -0
  37. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/organization_endpoint_group.py +62 -0
  38. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/organization_endpoint_patch_patch_packages.py +49 -0
  39. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/organization_endpoint_publisher_operating_systems.py +38 -0
  40. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/organization_endpoint_publisher_product_versions.py +30 -0
  41. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/organization_endpoint_vulnerabilities.py +30 -0
  42. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/organization_external_reference_source_settings.py +38 -0
  43. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/organization_publisher_operating_systems.py +38 -0
  44. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/organization_publisher_products.py +38 -0
  45. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/organization_scan_input.py +56 -0
  46. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/patch_management.py +54 -0
  47. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/patch_package.py +32 -0
  48. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/patch_package_links.py +32 -0
  49. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/publisher_product_photos.py +28 -0
  50. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/script_template.py +30 -0
  51. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/script_template_commands.py +32 -0
  52. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/task.py +28 -0
  53. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/task_endpoints_event.py +54 -0
  54. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/task_event.py +49 -0
  55. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/task_template.py +38 -0
  56. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/user.py +30 -0
  57. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/user_invitation.py +72 -0
  58. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/vulnerability.py +38 -0
  59. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/vulnerability_attack_vectors.py +32 -0
  60. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/vulnerability_internal_tags.py +32 -0
  61. vrx_mcp-0.1.0/src/vrx_mcp/tools/_generated/vulnerability_links.py +32 -0
  62. vrx_mcp-0.1.0/src/vrx_mcp/tools/request.py +56 -0
  63. vrx_mcp-0.1.0/tests/__init__.py +0 -0
  64. vrx_mcp-0.1.0/tests/fixtures/mini_openapi.json +73 -0
  65. vrx_mcp-0.1.0/tests/test_client.py +100 -0
  66. vrx_mcp-0.1.0/tests/test_common.py +47 -0
  67. vrx_mcp-0.1.0/tests/test_config.py +78 -0
  68. vrx_mcp-0.1.0/tests/test_errors.py +22 -0
  69. vrx_mcp-0.1.0/tests/test_generator.py +90 -0
  70. vrx_mcp-0.1.0/tests/test_registration.py +46 -0
  71. vrx_mcp-0.1.0/tests/test_request_tool.py +37 -0
  72. vrx_mcp-0.1.0/tests/test_server.py +31 -0
  73. vrx_mcp-0.1.0/tests/test_version.py +5 -0
@@ -0,0 +1,12 @@
1
+ # Vicarius vRx MCP server configuration
2
+ VRX_API_KEY=your-api-key-here
3
+ # REQUIRED (no default): full API base URL for your tenant. Replace <dashboard>.
4
+ VRX_BASE_URL=https://<dashboard>.vicarius.cloud/vicarius-external-data-api
5
+ # Auth header name carrying the API key (confirmed: vicarius-token).
6
+ VRX_AUTH_HEADER=vicarius-token
7
+ # Start read-only (no mutating tools, vrx_request GET-only) until you trust it.
8
+ VRX_READ_ONLY=true
9
+ VRX_TIMEOUT=60
10
+ LOG_LEVEL=INFO
11
+ MCP_HTTP_HOST=127.0.0.1
12
+ MCP_HTTP_PORT=8765
@@ -0,0 +1,16 @@
1
+ name: CI
2
+ on: [push, pull_request]
3
+ jobs:
4
+ test:
5
+ runs-on: ubuntu-latest
6
+ strategy:
7
+ matrix:
8
+ python-version: ["3.10", "3.11", "3.12"]
9
+ steps:
10
+ - uses: actions/checkout@v4
11
+ - uses: actions/setup-python@v5
12
+ with:
13
+ python-version: ${{ matrix.python-version }}
14
+ - run: pip install -e ".[dev]"
15
+ - run: ruff check .
16
+ - run: pytest -v
@@ -0,0 +1,46 @@
1
+ name: Release
2
+
3
+ # Publishes to PyPI when a GitHub Release is published.
4
+ # Authentication uses PyPI Trusted Publishing (OIDC) — no API token is stored.
5
+ # One-time setup on PyPI: add a Trusted Publisher (or "pending publisher" before the
6
+ # first upload) for project `vrx-mcp` with owner `Space-C0wboy`,
7
+ # repository `vicarius-vrx-mcp-server`, workflow `release.yml`, environment `pypi`.
8
+
9
+ on:
10
+ release:
11
+ types: [published]
12
+
13
+ jobs:
14
+ build:
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.12"
21
+ - name: Build sdist and wheel
22
+ run: |
23
+ python -m pip install --upgrade build
24
+ python -m build
25
+ - name: Check distribution metadata
26
+ run: |
27
+ python -m pip install --upgrade twine
28
+ python -m twine check dist/*
29
+ - uses: actions/upload-artifact@v4
30
+ with:
31
+ name: dist
32
+ path: dist/
33
+
34
+ publish:
35
+ needs: build
36
+ runs-on: ubuntu-latest
37
+ environment: pypi
38
+ permissions:
39
+ id-token: write # required for PyPI Trusted Publishing (OIDC)
40
+ steps:
41
+ - uses: actions/download-artifact@v4
42
+ with:
43
+ name: dist
44
+ path: dist/
45
+ - name: Publish to PyPI
46
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,14 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .venv/
4
+ venv/
5
+ *.egg-info/
6
+ dist/
7
+ build/
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ .env
11
+ # Vendor/customer-proprietary reference material is not redistributed
12
+ Reference Material/
13
+ # Internal design/planning artifacts (kept locally, not published)
14
+ docs/superpowers/
@@ -0,0 +1,7 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 (unreleased)
4
+
5
+ - Initial release: MCP server for the Vicarius vRx External Data API.
6
+ - Tools generated from the OpenAPI spec across all controller domains.
7
+ - `vrx_request` escape hatch; read-only mode; rate-limit-aware retries.
@@ -0,0 +1,51 @@
1
+ # Contributing
2
+
3
+ ## Development
4
+
5
+ ```bash
6
+ git clone https://github.com/Space-C0wboy/vicarius-vrx-mcp-server
7
+ cd vicarius-vrx-mcp-server
8
+ python -m venv .venv
9
+ .venv/Scripts/python -m pip install -e ".[dev]" # Windows
10
+ # .venv/bin/python -m pip install -e ".[dev]" # macOS/Linux
11
+
12
+ .venv/Scripts/python -m pytest # full suite (httpx fully mocked; no live calls)
13
+ .venv/Scripts/python -m ruff check . # lint
14
+ ```
15
+
16
+ ## Regenerating tools
17
+
18
+ Tool modules under `src/vrx_mcp/tools/_generated/` are generated from the OpenAPI spec and
19
+ are **not hand-edited**. To change a tool, edit `scripts/generate_from_openapi.py` (its
20
+ `OVERRIDES` / `MUTATING_OVERRIDES` maps and classification helpers) and regenerate:
21
+
22
+ ```bash
23
+ .venv/Scripts/python scripts/generate_from_openapi.py "Reference Material/api-docs.json"
24
+ ```
25
+
26
+ Generation is deterministic — re-running it produces a byte-identical, reviewable diff. The
27
+ OpenAPI spec lives in `Reference Material/`, which is gitignored (vendor-proprietary).
28
+
29
+ ## Releasing (PyPI)
30
+
31
+ Publishing is automated by `.github/workflows/release.yml` using **PyPI Trusted Publishing
32
+ (OIDC)** — no API token is stored. The workflow builds the sdist/wheel, runs `twine check`,
33
+ and uploads to PyPI when a **GitHub Release is published**, via the `pypi` environment.
34
+
35
+ The PyPI Trusted Publisher and the GitHub `pypi` environment are already configured
36
+ (publisher: project `vrx-mcp`, owner `Space-C0wboy`, repo `vicarius-vrx-mcp-server`,
37
+ workflow `release.yml`, environment `pypi`).
38
+
39
+ To cut a release:
40
+
41
+ 1. Bump the version in `pyproject.toml` and `src/vrx_mcp/__init__.py`, update
42
+ `CHANGELOG.md`, and commit.
43
+ 2. Tag and push, e.g. `git tag v0.2.0 && git push origin v0.2.0`.
44
+ 3. Create a GitHub Release for that tag. Publishing the Release triggers the workflow,
45
+ which builds and uploads to PyPI.
46
+
47
+ Sanity-check the build locally before releasing:
48
+
49
+ ```bash
50
+ .venv/Scripts/python -m build && .venv/Scripts/python -m twine check dist/*
51
+ ```
vrx_mcp-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 McLeod Software
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.
vrx_mcp-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,292 @@
1
+ Metadata-Version: 2.4
2
+ Name: vrx-mcp
3
+ Version: 0.1.0
4
+ Summary: Unofficial MCP server for the Vicarius vRx External Data API
5
+ Project-URL: Homepage, https://github.com/Space-C0wboy/vicarius-vrx-mcp-server
6
+ Project-URL: Repository, https://github.com/Space-C0wboy/vicarius-vrx-mcp-server
7
+ Project-URL: Issues, https://github.com/Space-C0wboy/vicarius-vrx-mcp-server/issues
8
+ Author: McLeod Software
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: mcp,model-context-protocol,patch-management,security,vicarius,vrx,vulnerability-management
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Information Technology
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Security
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: fastmcp>=3.0.0
25
+ Requires-Dist: httpx>=0.27.0
26
+ Requires-Dist: pydantic>=2.0.0
27
+ Requires-Dist: python-dotenv>=1.0.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: build>=1.2.0; extra == 'dev'
30
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
31
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
32
+ Requires-Dist: ruff>=0.5.0; extra == 'dev'
33
+ Requires-Dist: twine>=5.0.0; extra == 'dev'
34
+ Description-Content-Type: text/markdown
35
+
36
+ # Vicarius vRx MCP Server
37
+
38
+ [![PyPI version](https://img.shields.io/pypi/v/vrx-mcp.svg)](https://pypi.org/project/vrx-mcp/)
39
+ [![Python versions](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue.svg)](https://pypi.org/project/vrx-mcp/)
40
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
41
+ [![CI](https://github.com/Space-C0wboy/vicarius-vrx-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/Space-C0wboy/vicarius-vrx-mcp-server/actions/workflows/ci.yml)
42
+ [![status: beta](https://img.shields.io/badge/status-beta-orange.svg)](#)
43
+
44
+ A [Model Context Protocol](https://modelcontextprotocol.io) server that exposes the
45
+ **Vicarius vRx External Data API** (REST) to AI assistants. It provides **88 tools across 37
46
+ API domains** — Vulnerabilities/CVEs, Endpoints (Assets), Patches & Updates, Publishers &
47
+ Products, Tasks & Events, Automations & Scripts, Users, and more — plus a generic
48
+ `vrx_request` escape hatch for anything not covered by a dedicated tool. The tool set is
49
+ **generated directly from the vRx OpenAPI specification**, so it stays faithful to the real
50
+ API surface, and the generated output is deterministic and committed.
51
+
52
+ > [!IMPORTANT]
53
+ > **Unofficial project.** This is an independent, internally-built MCP server developed
54
+ > against Vicarius's published API documentation. It is **not** an official Vicarius product
55
+ > and is not affiliated with, endorsed by, or supported by Vicarius. "Vicarius" and "vRx"
56
+ > are trademarks of their respective owner. For official support of the vRx platform or the
57
+ > API itself, contact Vicarius directly.
58
+
59
+ > [!WARNING]
60
+ > **Beta software — not yet recommended for production.** This project is under active
61
+ > development. The tool surface may still change between versions, and not every endpoint has
62
+ > been exercised against every tenant/entitlement configuration.
63
+ >
64
+ > **This server can perform destructive actions against your vRx tenant.** Tools can delete
65
+ > assets and asset groups, create/update/delete users and invitations, modify automations and
66
+ > scan inputs, and update tasks. A hallucinated tool argument from your AI assistant could
67
+ > change your tenant configuration.
68
+ >
69
+ > **Recommended posture:**
70
+ > - **Run read-only first.** Set `VRX_READ_ONLY=true` to register only read tools and make
71
+ > `vrx_request` reject any non-GET request. Lift it only when you need to write.
72
+ > - Use a vRx API key scoped to the **minimum permissions** your use case requires.
73
+ > - Review every mutating tool call before allowing execution. Claude Desktop requires
74
+ > tool-call approval by default — keep that enabled.
75
+ > - Treat the API key with the same care as portal admin credentials.
76
+ > - The HTTP transport binds to `127.0.0.1` by default. Do not expose it to the public
77
+ > internet without adding authentication.
78
+
79
+ ## Tools
80
+
81
+ **88 tools across 37 API controllers** (59 read + 29 mutating), plus the `vrx_request` escape
82
+ hatch — **89 total in full mode, 60 in read-only mode** (mutating tools are not registered when
83
+ read-only). The table below groups the controllers into functional domains.
84
+
85
+ | Domain | Read | Write | Notable tools |
86
+ |--------|:----:|:-----:|---------------|
87
+ | **Vulnerabilities & CVEs** | 9 | 0 | `vulnerability_search`, `vulnerability_count`, `endpoint_vulnerability_filter`, `organization_endpoint_vulnerabilities_search`, `vulnerability_attack_vectors_search_by_fields`, `vulnerability_links_search_by_fields` |
88
+ | **Endpoints (Assets)** | 7 | 5 | `endpoint_search`, `endpoint_attributes_search`, `organization_endpoint_group_search`, `aggregation_search_group`, `endpoint_delete`, `organization_endpoint_group_insert` |
89
+ | **Patches & Updates** | 11 | 3 | `patch_management_patch`, `patch_management_cve_info`, `organization_endpoint_patch_patch_packages_filter`, `organization_endpoint_external_reference_external_references_search`, `patch_package_search_by_fields` |
90
+ | **Publishers, Products & OS** | 9 | 0 | `organization_publisher_products_search`, `organization_endpoint_publisher_product_versions_search`, `organization_publisher_operating_systems_search`, `operating_system_family_search_by_fields` |
91
+ | **Tasks & Events** | 10 | 7 | `task_event_filter`, `task_endpoints_event_filter`, `incident_event_filter`, `task_update`, `task_template_insert`, `automation_task_templates_insert` |
92
+ | **Automations & Scripts** | 9 | 9 | `automation_search`, `automations_automations`, `script_template_search`, `organization_scan_input_search`, `automation_delete`, `organization_scan_input_update` |
93
+ | **Users & Invitations** | 3 | 5 | `user_search`, `user_invitation_search`, `user_invitation_insert`, `user_invitation_update`, `user_invitation_delete` |
94
+ | **Utilities** | 1 | 0 | `date_get_current_date` |
95
+
96
+ See [`docs/ENDPOINTS.md`](docs/ENDPOINTS.md) for the **full tool ↔ method ↔ path mapping** (all
97
+ 88 tools with their mutating flag).
98
+
99
+ **Highlights:**
100
+
101
+ - **Search tools** (`endpoint_search`, `vulnerability_search`, `organization_endpoint_group_search`, …)
102
+ accept an **RSQL `q` filter** plus `from`/`size` paging — see [Querying](#querying).
103
+ - **Filter / count tools** (`*_filter`, `*_count`) cover event streams (incident events, task
104
+ events) and counts for dashboards.
105
+ - **Aggregation tools** (`aggregation_group`, `aggregation_search_group`) power grouped/rollup
106
+ queries (e.g. count of active CVEs grouped by vulnerability).
107
+ - **`vrx_request` escape hatch** issues an arbitrary request against the API for any endpoint
108
+ without a dedicated tool. In read-only mode it rejects every non-GET method.
109
+ - **Read-only safety is enforced at two layers** — mutating tools are never registered in
110
+ read-only mode, *and* `vrx_request` independently refuses mutations.
111
+
112
+ ## Quick start
113
+
114
+ ### Install
115
+
116
+ ```bash
117
+ # with uv (recommended)
118
+ uv tool install vrx-mcp
119
+
120
+ # or with pip
121
+ pip install vrx-mcp
122
+ ```
123
+
124
+ This installs the `vrx-mcp` console script. For development from source:
125
+
126
+ ```bash
127
+ git clone https://github.com/Space-C0wboy/vicarius-vrx-mcp-server
128
+ cd vicarius-vrx-mcp-server
129
+ python -m venv .venv
130
+ .venv/Scripts/python -m pip install -e ".[dev]" # Windows
131
+ # .venv/bin/python -m pip install -e ".[dev]" # macOS/Linux
132
+ ```
133
+
134
+ ### Getting an API key
135
+
136
+ 1. In the vRx portal, go to **Settings**, select the **api** tag, then **Create Integration**.
137
+ 2. Copy the generated API key — this is your `VRX_API_KEY`.
138
+ 3. Your base URL is `https://<your-dashboard>.vicarius.cloud/vicarius-external-data-api`.
139
+
140
+ Requests authenticate with the **`vicarius-token`** header (the API key value); this server
141
+ sets it for you on every request.
142
+
143
+ ### Configuration
144
+
145
+ Copy `.env.example` to `.env` and set:
146
+
147
+ | Variable | Required | Default | Description |
148
+ |----------|----------|---------|-------------|
149
+ | `VRX_API_KEY` | **yes** | — | Your vRx API key (Settings → api → Create Integration) |
150
+ | `VRX_BASE_URL` | **yes** | — | Full API base URL, e.g. `https://<dashboard>.vicarius.cloud/vicarius-external-data-api`. **No default** — the server fails fast if unset (no tenant is hardcoded) |
151
+ | `VRX_AUTH_HEADER` | no | `vicarius-token` | Header name carrying the API key |
152
+ | `VRX_READ_ONLY` | no | `false` | When true, no mutating tools are registered and `vrx_request` rejects non-GET requests |
153
+ | `VRX_TIMEOUT` | no | `60` | Request timeout in seconds |
154
+ | `LOG_LEVEL` | no | `INFO` | Logging level (logs go to stderr) |
155
+ | `MCP_HTTP_HOST` / `MCP_HTTP_PORT` | no | `127.0.0.1:8765` | HTTP transport bind |
156
+
157
+ ### Run
158
+
159
+ - **stdio** (default, for Claude Desktop/Code): `vrx-mcp`
160
+ - **HTTP**: `vrx-mcp --transport http --port 8765`
161
+
162
+ ## Querying
163
+
164
+ vRx search endpoints use **RSQL** in the `q` query parameter:
165
+
166
+ | Operator | Meaning | Example |
167
+ |----------|---------|---------|
168
+ | `==` | equals | `endpointName=='HOST01'` |
169
+ | `=in=(a,b,c)` | in list | `endpointId=in=(101,102,103)` |
170
+ | `=re='regex'` | regex match | `vulnerabilityExternalReference.externalReferenceExternalId=re='.*(cve-2024).*'` |
171
+ | `>` / `<` | compare | `analyticsEventCreatedAtNano>1682913600000000000` |
172
+
173
+ **Pagination:** every query takes `from` (offset) and `size`. **`size` ≤ 500** per request and
174
+ **`from` ≤ 10,000**. To page beyond offset 10,000, use **seek paging**: keep `from=0`, add a
175
+ `sort` (e.g. `-endpointId`), and add a `q` comparison on the last value seen
176
+ (e.g. `q=endpointId<525236`), repeating until the result is empty.
177
+
178
+ **Response envelope:** responses wrap results in a standard shape —
179
+ `serverResponseResult.serverResponseResultCode` (`"SUCCESS"`), `serverResponseCount` (total
180
+ matching records), and `serverResponseObject` (the array of records).
181
+
182
+ **Rate limits:** the API allows **60 queries / 60 seconds per organization scope** and returns
183
+ `HTTP 429` with an `X-Rate-Limit-Retry-After-Seconds` header when exceeded. The client
184
+ automatically retries 429s (and transient 5xx/network errors) with backoff, honoring that
185
+ header.
186
+
187
+ ## Read-only mode
188
+
189
+ Set `VRX_READ_ONLY=true` to run the server safely against production. In this mode:
190
+
191
+ - **No mutating tools are registered** — only the 59 read tools (+ `vrx_request`) are exposed.
192
+ - **`vrx_request` rejects any non-GET method**, so it can only run read operations.
193
+
194
+ Read-only mode is strongly recommended for analyst-assistant, reporting, and dashboard use
195
+ cases where the model should never change tenant state. The shipped `.env.example` defaults to
196
+ read-only.
197
+
198
+ ## Editor integration
199
+
200
+ ### Claude Code
201
+
202
+ ```bash
203
+ claude mcp add vrx \
204
+ --env VRX_API_KEY=your-key-here \
205
+ --env VRX_BASE_URL=https://your-dashboard.vicarius.cloud/vicarius-external-data-api \
206
+ --env VRX_READ_ONLY=true \
207
+ -- vrx-mcp
208
+ ```
209
+
210
+ ### Claude Desktop
211
+
212
+ Edit `claude_desktop_config.json`:
213
+ - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
214
+ - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
215
+
216
+ ```json
217
+ {
218
+ "mcpServers": {
219
+ "vrx": {
220
+ "command": "vrx-mcp",
221
+ "env": {
222
+ "VRX_API_KEY": "your-key-here",
223
+ "VRX_BASE_URL": "https://your-dashboard.vicarius.cloud/vicarius-external-data-api",
224
+ "VRX_READ_ONLY": "true"
225
+ }
226
+ }
227
+ }
228
+ }
229
+ ```
230
+
231
+ Restart Claude Desktop, then confirm `vrx` appears in the tools menu.
232
+
233
+ ## Example prompts
234
+
235
+ - *"List the first 100 assets in vRx."* → `endpoint_search` (`from=0`, `size=100`).
236
+ - *"Find the asset named HOST01."* → `endpoint_search` (`q=endpointName=='HOST01'`).
237
+ - *"Show me all Critical CVEs."* → `vulnerability_search`
238
+ (`q=vulnerabilitySensitivityLevel.sensitivityLevelName=='Critical'`).
239
+ - *"Which assets are affected by CVE-2024-3094?"* → `vulnerability_search` to resolve the CVE,
240
+ then `endpoint_search` with a `searchQuerys` join body on `OrganizationEndpointVulnerabilities`.
241
+ - *"List endpoints with critical missing patches."* →
242
+ `organization_endpoint_external_reference_external_references_search`
243
+ (`q=...patchSensitivityLevel.sensitivityLevelName=='Critical'`).
244
+ - *"Get attack vectors and links for a vulnerability."* → `vulnerability_attack_vectors_search_by_fields`
245
+ / `vulnerability_links_search_by_fields` (`q=vulnerabilityId==<id>`).
246
+ - *"Show the recent event log."* → `incident_event_filter` (sort + `analyticsEventCreatedAtNano` range).
247
+ - *"Count active CVEs grouped by vulnerability."* → `aggregation_search_group`.
248
+ - *"Call an endpoint I don't have a tool for."* → `vrx_request` (`method`, `path`, `query`, `body`).
249
+
250
+ ## How tools are generated
251
+
252
+ The tool modules are generated from the vRx OpenAPI specification:
253
+
254
+ ```bash
255
+ python scripts/generate_from_openapi.py "Reference Material/api-docs.json"
256
+ ```
257
+
258
+ This regenerates the modules under `src/vrx_mcp/tools/_generated/` and the catalog at
259
+ `docs/ENDPOINTS.md`. The generated files are **not hand-edited** — to change a tool, edit the
260
+ generator (its `OVERRIDES` / `MUTATING_OVERRIDES` maps) and regenerate. Generation is
261
+ deterministic, so re-running it produces a byte-identical, reviewable diff.
262
+
263
+ The OpenAPI spec and other vRx reference material live in the **`Reference Material/`**
264
+ directory, which is **gitignored** (vendor/customer-proprietary material, not redistributed).
265
+
266
+ Key generator behavior:
267
+ - Operations are grouped by OpenAPI controller tag into one module per domain.
268
+ - Redundant **GET/POST search twins** are collapsed to a single tool (the POST/body form).
269
+ - Each operation is classified **mutating** (`PUT`/`DELETE`, or a non-search `POST`) or
270
+ **read** (`GET`, or a search-style `POST`); mutating tools are hidden in read-only mode.
271
+
272
+ ## Development
273
+
274
+ ```bash
275
+ .venv/Scripts/python -m pytest # full suite (httpx fully mocked; no live calls)
276
+ .venv/Scripts/python -m ruff check . # lint
277
+ .venv/Scripts/python scripts/generate_from_openapi.py "Reference Material/api-docs.json" # regenerate
278
+ ```
279
+
280
+ CI runs ruff + pytest on Python 3.10 / 3.11 / 3.12 (see `.github/workflows/ci.yml`).
281
+
282
+ Maintainers: see [CONTRIBUTING.md](CONTRIBUTING.md) for the release process.
283
+
284
+ ## License
285
+
286
+ [MIT](LICENSE)
287
+
288
+ ## Support
289
+
290
+ This is an unofficial, internal project. For vRx platform or API questions, contact Vicarius
291
+ directly. For issues with this MCP server, open an issue on the
292
+ [GitHub repository](https://github.com/Space-C0wboy/vicarius-vrx-mcp-server/issues).