adaptive-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 (37) hide show
  1. adaptive_mcp-0.1.0/.env.example +15 -0
  2. adaptive_mcp-0.1.0/.github/workflows/ci.yml +25 -0
  3. adaptive_mcp-0.1.0/.github/workflows/release.yml +36 -0
  4. adaptive_mcp-0.1.0/.gitignore +26 -0
  5. adaptive_mcp-0.1.0/LICENSE +21 -0
  6. adaptive_mcp-0.1.0/PKG-INFO +290 -0
  7. adaptive_mcp-0.1.0/README.md +261 -0
  8. adaptive_mcp-0.1.0/docs/ENDPOINTS.md +21 -0
  9. adaptive_mcp-0.1.0/docs/superpowers/plans/2026-06-09-adaptive-mcp-server.md +1999 -0
  10. adaptive_mcp-0.1.0/docs/superpowers/specs/2026-06-09-adaptive-mcp-server-design.md +251 -0
  11. adaptive_mcp-0.1.0/pyproject.toml +67 -0
  12. adaptive_mcp-0.1.0/scripts/generate_from_openapi.py +290 -0
  13. adaptive_mcp-0.1.0/scripts/smoke_test.py +27 -0
  14. adaptive_mcp-0.1.0/src/adaptive_mcp/__init__.py +5 -0
  15. adaptive_mcp-0.1.0/src/adaptive_mcp/client.py +212 -0
  16. adaptive_mcp-0.1.0/src/adaptive_mcp/config.py +107 -0
  17. adaptive_mcp-0.1.0/src/adaptive_mcp/errors.py +27 -0
  18. adaptive_mcp-0.1.0/src/adaptive_mcp/server.py +87 -0
  19. adaptive_mcp-0.1.0/src/adaptive_mcp/tools/__init__.py +21 -0
  20. adaptive_mcp-0.1.0/src/adaptive_mcp/tools/_common.py +40 -0
  21. adaptive_mcp-0.1.0/src/adaptive_mcp/tools/_generated/__init__.py +17 -0
  22. adaptive_mcp-0.1.0/src/adaptive_mcp/tools/_generated/audit_logs.py +40 -0
  23. adaptive_mcp-0.1.0/src/adaptive_mcp/tools/_generated/groups.py +46 -0
  24. adaptive_mcp-0.1.0/src/adaptive_mcp/tools/_generated/phishing.py +64 -0
  25. adaptive_mcp-0.1.0/src/adaptive_mcp/tools/_generated/training.py +47 -0
  26. adaptive_mcp-0.1.0/src/adaptive_mcp/tools/_generated/users.py +37 -0
  27. adaptive_mcp-0.1.0/src/adaptive_mcp/tools/request.py +41 -0
  28. adaptive_mcp-0.1.0/tests/__init__.py +0 -0
  29. adaptive_mcp-0.1.0/tests/fixtures/mini_openapi.json +38 -0
  30. adaptive_mcp-0.1.0/tests/test_client.py +97 -0
  31. adaptive_mcp-0.1.0/tests/test_common.py +45 -0
  32. adaptive_mcp-0.1.0/tests/test_config.py +67 -0
  33. adaptive_mcp-0.1.0/tests/test_errors.py +17 -0
  34. adaptive_mcp-0.1.0/tests/test_generator.py +92 -0
  35. adaptive_mcp-0.1.0/tests/test_registration.py +54 -0
  36. adaptive_mcp-0.1.0/tests/test_request_tool.py +24 -0
  37. adaptive_mcp-0.1.0/tests/test_server.py +23 -0
@@ -0,0 +1,15 @@
1
+ # Adaptive Security MCP Server — environment configuration
2
+ # Copy this file to .env and fill in your API key.
3
+
4
+ # REQUIRED — your Adaptive API token (Admin portal → Settings → API Tokens).
5
+ # Sent as: Authorization: Bearer <token>
6
+ ADAPTIVE_API_KEY=
7
+
8
+ # Optional — defaults shown.
9
+ # ADAPTIVE_BASE_URL=https://api.adaptivesecurity.com
10
+ # ADAPTIVE_TIMEOUT=60
11
+ # LOG_LEVEL=INFO
12
+
13
+ # Optional — only used with the HTTP transport (--transport http).
14
+ # MCP_HTTP_HOST=127.0.0.1
15
+ # MCP_HTTP_PORT=8765
@@ -0,0 +1,25 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ python-version: ["3.10", "3.11", "3.12"]
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - name: Install uv
17
+ uses: astral-sh/setup-uv@v5
18
+ - name: Set up Python ${{ matrix.python-version }}
19
+ run: uv python install ${{ matrix.python-version }}
20
+ - name: Install
21
+ run: uv pip install --system -e ".[dev]"
22
+ - name: Lint
23
+ run: ruff check .
24
+ - name: Test
25
+ run: pytest
@@ -0,0 +1,36 @@
1
+ name: Release
2
+ on:
3
+ push:
4
+ tags: ["v*"]
5
+
6
+ jobs:
7
+ build:
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - uses: actions/checkout@v4
11
+ - uses: actions/setup-python@v5
12
+ with:
13
+ python-version: "3.12"
14
+ - run: python -m pip install build
15
+ - run: python -m build
16
+ - uses: actions/upload-artifact@v4
17
+ with:
18
+ name: dist
19
+ path: dist/*
20
+
21
+ publish:
22
+ needs: build
23
+ runs-on: ubuntu-latest
24
+ # Must match the "Environment name" configured for the PyPI trusted publisher.
25
+ environment:
26
+ name: pypi
27
+ url: https://pypi.org/project/adaptive-mcp/
28
+ permissions:
29
+ # OIDC token used by PyPI trusted publishing — no API token/secret needed.
30
+ id-token: write
31
+ steps:
32
+ - uses: actions/download-artifact@v4
33
+ with:
34
+ name: dist
35
+ path: dist
36
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,26 @@
1
+ # Secrets / local env
2
+ .env
3
+ .env.*
4
+ !.env.example
5
+
6
+ # Vendor reference material — not redistributed
7
+ Source Material/
8
+
9
+ # Python
10
+ __pycache__/
11
+ *.py[cod]
12
+ *.egg-info/
13
+ .eggs/
14
+ build/
15
+ dist/
16
+ .venv/
17
+ venv/
18
+ uv.lock
19
+ .pytest_cache/
20
+ .ruff_cache/
21
+ .mypy_cache/
22
+
23
+ # OS / editor
24
+ .DS_Store
25
+ .idea/
26
+ .vscode/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kierston Grantham
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,290 @@
1
+ Metadata-Version: 2.4
2
+ Name: adaptive-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP server for the Adaptive Security Awareness Training API
5
+ Author: Kierston Grantham
6
+ License: MIT
7
+ Keywords: adaptive,ai-tools,awareness-training,claude,mcp,phishing,security
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Information Technology
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Security
17
+ Classifier: Typing :: Typed
18
+ Requires-Python: >=3.10
19
+ Requires-Dist: fastmcp<3.0,>=2.0.0
20
+ Requires-Dist: httpx<1.0,>=0.27.0
21
+ Requires-Dist: pydantic<3.0,>=2.6.0
22
+ Requires-Dist: python-dotenv<2.0,>=1.0.0
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest-asyncio<2.0,>=0.23.0; extra == 'dev'
25
+ Requires-Dist: pytest-httpx<1.0,>=0.30.0; extra == 'dev'
26
+ Requires-Dist: pytest<9.0,>=8.0.0; extra == 'dev'
27
+ Requires-Dist: ruff<1.0,>=0.4.0; extra == 'dev'
28
+ Description-Content-Type: text/markdown
29
+
30
+ # Adaptive Security Awareness Training MCP Server
31
+
32
+ [![PyPI version](https://img.shields.io/pypi/v/adaptive-mcp.svg)](https://pypi.org/project/adaptive-mcp/)
33
+ [![Python versions](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue.svg)](https://pypi.org/project/adaptive-mcp/)
34
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
35
+ [![CI](https://github.com/Space-C0wboy/Adaptive-Security-MCP-Server/actions/workflows/ci.yml/badge.svg)](https://github.com/Space-C0wboy/Adaptive-Security-MCP-Server/actions/workflows/ci.yml)
36
+ [![status: beta](https://img.shields.io/badge/status-beta-orange.svg)](#)
37
+ [![read-only API](https://img.shields.io/badge/API-read--only-brightgreen.svg)](#read-only-by-design)
38
+
39
+ A [Model Context Protocol](https://modelcontextprotocol.io) server that exposes the
40
+ **Adaptive Security Awareness Training API (v2)** (REST) to AI assistants. It provides
41
+ **15 tools across 5 API domains** — Audit Logs, Groups, Phishing, Training, and Users —
42
+ plus a generic `adaptive_request` escape hatch for anything not covered by a dedicated
43
+ tool. The tool set is **generated directly from the Adaptive OpenAPI specification**, so it
44
+ stays faithful to the real API surface, and the generated output is deterministic and
45
+ committed.
46
+
47
+ > [!IMPORTANT]
48
+ > **Unofficial project.** This is an independent, internally-built MCP server developed
49
+ > against Adaptive Security's published API documentation. It is **not** an official
50
+ > Adaptive Security product and is not affiliated with, endorsed by, or supported by
51
+ > Adaptive Security. "Adaptive Security" is a trademark of its respective owner. For
52
+ > official support of the Adaptive platform or the API itself, contact Adaptive directly.
53
+
54
+ > [!NOTE]
55
+ > **Read-only by design.** Every Adaptive API endpoint this server exposes is an HTTP
56
+ > `GET`, and the client only ever issues `GET` requests — including the `adaptive_request`
57
+ > escape hatch. **This server cannot create, modify, or delete anything in your Adaptive
58
+ > tenant.** There is no write surface and therefore no `READ_ONLY` switch to manage: it is
59
+ > always safe to point at production for analyst-assistant, reporting, and dashboard use.
60
+
61
+ > [!WARNING]
62
+ > **Beta software — not yet recommended for unattended production use.** This project is
63
+ > under active development; the tool surface may still change between versions, and not
64
+ > every endpoint has been exercised against every tenant/entitlement configuration.
65
+ >
66
+ > - Treat your `ADAPTIVE_API_KEY` with the same care as portal admin credentials. Scope it
67
+ > to the minimum your use case requires.
68
+ > - The HTTP transport binds to `127.0.0.1` by default. Do not expose it to the public
69
+ > internet without adding authentication.
70
+ > - Keep Claude Desktop's tool-call approval enabled so you can see each request before it runs.
71
+
72
+ ## Tools
73
+
74
+ **15 tools across 5 domains** (all read-only), plus the `adaptive_request` escape hatch —
75
+ **16 total**. The table below groups them by domain.
76
+
77
+ | Domain | Tools | What it covers |
78
+ |--------|-------|----------------|
79
+ | **Users** | `list_users`, `get_user` | The org's people directory and per-user detail |
80
+ | **Groups** | `list_groups`, `get_group`, `get_group_members` | User groups and their membership |
81
+ | **Phishing** | `list_phishing_campaigns`, `get_phishing_campaign`, `list_campaign_simulations`, `get_simulation`, `get_phishing_enrollments` | Phishing simulation campaigns, the individual simulations within them, and per-user enrollment/results |
82
+ | **Training** | `list_training_campaigns`, `get_training_campaign`, `get_training_campaign_enrollments` | Security-awareness training campaigns and per-user enrollment/completion |
83
+ | **Audit Logs** | `list_audit_logs`, `get_audit_log` | Administrative audit trail, filterable by action type and date range |
84
+
85
+ See [`docs/ENDPOINTS.md`](docs/ENDPOINTS.md) for the **full tool ↔ method ↔ path mapping** (all
86
+ 15 tools).
87
+
88
+ **Highlights:**
89
+
90
+ - **List tools** (`list_users`, `list_phishing_campaigns`, …) are **cursor-paginated** —
91
+ pass `page_size` and a `page_after` cursor; the response carries the next `page_after`.
92
+ See [Pagination & responses](#pagination--responses).
93
+ - **Filter tools** (`get_phishing_enrollments`, `get_training_campaign_enrollments`) narrow
94
+ enrollment data by `user_id` / `campaign_id` / `simulation_id`.
95
+ - **`list_audit_logs`** filters the admin audit trail by `start_date`, `end_date`, and a list
96
+ of `actions` (e.g. `CREATED_TRAINING_CAMPAIGN`, `SCHEDULED_TRAINING_CAMPAIGN`, `ADDED_ADMIN`).
97
+ - **`adaptive_request` escape hatch** issues a raw `GET` against any path for endpoints
98
+ without a dedicated tool. It is GET-only by construction — it cannot mutate.
99
+
100
+ ## Quick start
101
+
102
+ ### Install
103
+
104
+ ```bash
105
+ # with uv (recommended)
106
+ uv tool install adaptive-mcp
107
+
108
+ # or with pip
109
+ pip install adaptive-mcp
110
+ ```
111
+
112
+ This installs the `adaptive-mcp` console script.
113
+
114
+ > [!NOTE]
115
+ > PyPI publishing is pending the first tagged release — until then, install from source
116
+ > (below). A push of a `v*` tag publishes to PyPI via GitHub Actions trusted publishing.
117
+
118
+ For development from source:
119
+
120
+ ```bash
121
+ git clone https://github.com/Space-C0wboy/Adaptive-Security-MCP-Server
122
+ cd Adaptive-Security-MCP-Server
123
+ uv venv && uv pip install -e ".[dev]"
124
+ ```
125
+
126
+ ### Getting an API token
127
+
128
+ 1. In the Adaptive Admin portal, go to **Settings → API Tokens**.
129
+ 2. Create a token and copy it — this is your `ADAPTIVE_API_KEY`.
130
+
131
+ Requests authenticate with the **`Authorization: Bearer <token>`** header; this server sets
132
+ it for you on every request.
133
+
134
+ ### Configuration
135
+
136
+ Copy `.env.example` to `.env` and set:
137
+
138
+ | Variable | Required | Default | Description |
139
+ |----------|----------|---------|-------------|
140
+ | `ADAPTIVE_API_KEY` | **yes** | — | Your Adaptive API token (Settings → API Tokens) |
141
+ | `ADAPTIVE_BASE_URL` | no | `https://api.adaptivesecurity.com` | API root |
142
+ | `ADAPTIVE_TIMEOUT` | no | `60` | Request timeout in seconds |
143
+ | `LOG_LEVEL` | no | `INFO` | Logging level (logs go to stderr) |
144
+ | `MCP_HTTP_HOST` / `MCP_HTTP_PORT` | no | `127.0.0.1:8765` | HTTP transport bind |
145
+
146
+ ### Run
147
+
148
+ - **stdio** (default, for Claude Desktop/Code): `adaptive-mcp` (or `uv run adaptive-mcp` from source)
149
+ - **HTTP**: `adaptive-mcp --transport http --port 8765`
150
+
151
+ ## Pagination & responses
152
+
153
+ Adaptive list/filter endpoints use **opaque cursor pagination** via two query parameters:
154
+
155
+ | Parameter | Type | Meaning |
156
+ |-----------|------|---------|
157
+ | `page_size` | integer | Max records per page. Default **50** for `list_groups`, `list_phishing_campaigns`, `list_campaign_simulations`, and `get_phishing_enrollments`; **100** for every other list/filter tool. |
158
+ | `page_after` | string | Opaque cursor for the next page. Omit on the first call; pass the value returned by the previous response. |
159
+
160
+ **Response envelope:** a list response is an object with the records under a domain-named key
161
+ plus the next cursor, e.g.:
162
+
163
+ ```json
164
+ {
165
+ "users": [ { "id": "...", "email": "..." } ],
166
+ "page_after": "eyJpZCI6..."
167
+ }
168
+ ```
169
+
170
+ To page through everything, keep calling the same tool with `page_after` set to the value
171
+ from the previous response until `page_after` comes back empty/absent.
172
+
173
+ Filter parameters on specific tools:
174
+
175
+ | Tool | Filters |
176
+ |------|---------|
177
+ | `get_phishing_enrollments` | `user_id`, `campaign_id`, `simulation_id` |
178
+ | `get_training_campaign_enrollments` | `user_id`, `campaign_id` |
179
+ | `list_audit_logs` | `start_date`, `end_date`, `actions` (list of action types) |
180
+
181
+ ## Editor integration
182
+
183
+ ### Claude Code
184
+
185
+ ```bash
186
+ claude mcp add adaptive \
187
+ --env ADAPTIVE_API_KEY=your-token-here \
188
+ -- adaptive-mcp
189
+ ```
190
+
191
+ From source (not yet installed as a tool):
192
+
193
+ ```bash
194
+ claude mcp add adaptive \
195
+ --env ADAPTIVE_API_KEY=your-token-here \
196
+ -- uv run --directory /absolute/path/to/Adaptive-Security-MCP-Server adaptive-mcp
197
+ ```
198
+
199
+ ### Claude Desktop
200
+
201
+ Edit `claude_desktop_config.json`:
202
+ - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
203
+ - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
204
+
205
+ ```json
206
+ {
207
+ "mcpServers": {
208
+ "adaptive": {
209
+ "command": "adaptive-mcp",
210
+ "env": {
211
+ "ADAPTIVE_API_KEY": "your-token-here"
212
+ }
213
+ }
214
+ }
215
+ }
216
+ ```
217
+
218
+ If running from source instead of an installed tool, use `uv` with `--directory`:
219
+
220
+ ```json
221
+ {
222
+ "mcpServers": {
223
+ "adaptive": {
224
+ "command": "uv",
225
+ "args": ["run", "--directory", "/absolute/path/to/Adaptive-Security-MCP-Server", "adaptive-mcp"],
226
+ "env": { "ADAPTIVE_API_KEY": "your-token-here" }
227
+ }
228
+ }
229
+ }
230
+ ```
231
+
232
+ Restart Claude Desktop, then confirm `adaptive` appears in the tools menu.
233
+
234
+ ## Example prompts
235
+
236
+ - *"List the first 25 users."* → `list_users` (`page_size=25`).
237
+ - *"Get the details for user `<id>`."* → `get_user` (`userId=<id>`).
238
+ - *"What groups do we have, and who's in the Finance group?"* → `list_groups` → `get_group_members` (`groupId=<id>`).
239
+ - *"Show our phishing campaigns and the simulations in campaign `<id>`."* →
240
+ `list_phishing_campaigns` → `list_campaign_simulations` (`campaignId=<id>`).
241
+ - *"How did user `<id>` do on the phishing simulations?"* → `get_phishing_enrollments` (`user_id=<id>`).
242
+ - *"Which users haven't completed training campaign `<id>`?"* →
243
+ `get_training_campaign_enrollments` (`campaign_id=<id>`).
244
+ - *"Show admin actions in the last week."* → `list_audit_logs`
245
+ (`start_date`, `end_date`, `actions=["ADDED_ADMIN", "CREATED_TRAINING_CAMPAIGN"]`).
246
+ - *"Call an endpoint I don't have a dedicated tool for."* → `adaptive_request` (`path`, optional `params`).
247
+
248
+ ## How tools are generated
249
+
250
+ The tool modules are generated from the Adaptive OpenAPI specification:
251
+
252
+ ```bash
253
+ uv run python scripts/generate_from_openapi.py
254
+ ```
255
+
256
+ This regenerates the modules under `src/adaptive_mcp/tools/_generated/` and the catalog at
257
+ [`docs/ENDPOINTS.md`](docs/ENDPOINTS.md). The generated files are **not hand-edited** — to
258
+ change a tool, edit the generator (its `OVERRIDES` map) and regenerate. Generation is
259
+ deterministic, so re-running it produces a byte-identical, reviewable diff.
260
+
261
+ The OpenAPI spec and other Adaptive reference material live in the **`Source Material/`**
262
+ directory, which is **gitignored** (vendor reference material, not redistributed). CI installs
263
+ from the committed `_generated/` modules and does not regenerate.
264
+
265
+ Key generator behavior:
266
+ - Operations are grouped by OpenAPI tag into one module per domain.
267
+ - Only `GET` operations are generated (the API is read-only); path parameters are interpolated
268
+ into the URL and query parameters are forwarded with their spec defaults.
269
+ - Tool names are the snake_case form of each `operationId`.
270
+
271
+ ## Development
272
+
273
+ ```bash
274
+ uv run pytest # full suite (httpx fully mocked; no live calls)
275
+ uv run ruff check . # lint
276
+ uv run python scripts/generate_from_openapi.py # regenerate tools + ENDPOINTS.md
277
+ ```
278
+
279
+ CI runs ruff + pytest on Python 3.10 / 3.11 / 3.12 (see `.github/workflows/ci.yml`). A pushed
280
+ `v*` tag builds and publishes to PyPI via trusted publishing (see `.github/workflows/release.yml`).
281
+
282
+ ## License
283
+
284
+ [MIT](LICENSE)
285
+
286
+ ## Support
287
+
288
+ This is an unofficial, internal project. For Adaptive platform or API questions, contact
289
+ Adaptive Security directly. For issues with this MCP server, open an issue on the
290
+ [GitHub repository](https://github.com/Space-C0wboy/Adaptive-Security-MCP-Server/issues).
@@ -0,0 +1,261 @@
1
+ # Adaptive Security Awareness Training MCP Server
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/adaptive-mcp.svg)](https://pypi.org/project/adaptive-mcp/)
4
+ [![Python versions](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue.svg)](https://pypi.org/project/adaptive-mcp/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
+ [![CI](https://github.com/Space-C0wboy/Adaptive-Security-MCP-Server/actions/workflows/ci.yml/badge.svg)](https://github.com/Space-C0wboy/Adaptive-Security-MCP-Server/actions/workflows/ci.yml)
7
+ [![status: beta](https://img.shields.io/badge/status-beta-orange.svg)](#)
8
+ [![read-only API](https://img.shields.io/badge/API-read--only-brightgreen.svg)](#read-only-by-design)
9
+
10
+ A [Model Context Protocol](https://modelcontextprotocol.io) server that exposes the
11
+ **Adaptive Security Awareness Training API (v2)** (REST) to AI assistants. It provides
12
+ **15 tools across 5 API domains** — Audit Logs, Groups, Phishing, Training, and Users —
13
+ plus a generic `adaptive_request` escape hatch for anything not covered by a dedicated
14
+ tool. The tool set is **generated directly from the Adaptive OpenAPI specification**, so it
15
+ stays faithful to the real API surface, and the generated output is deterministic and
16
+ committed.
17
+
18
+ > [!IMPORTANT]
19
+ > **Unofficial project.** This is an independent, internally-built MCP server developed
20
+ > against Adaptive Security's published API documentation. It is **not** an official
21
+ > Adaptive Security product and is not affiliated with, endorsed by, or supported by
22
+ > Adaptive Security. "Adaptive Security" is a trademark of its respective owner. For
23
+ > official support of the Adaptive platform or the API itself, contact Adaptive directly.
24
+
25
+ > [!NOTE]
26
+ > **Read-only by design.** Every Adaptive API endpoint this server exposes is an HTTP
27
+ > `GET`, and the client only ever issues `GET` requests — including the `adaptive_request`
28
+ > escape hatch. **This server cannot create, modify, or delete anything in your Adaptive
29
+ > tenant.** There is no write surface and therefore no `READ_ONLY` switch to manage: it is
30
+ > always safe to point at production for analyst-assistant, reporting, and dashboard use.
31
+
32
+ > [!WARNING]
33
+ > **Beta software — not yet recommended for unattended production use.** This project is
34
+ > under active development; the tool surface may still change between versions, and not
35
+ > every endpoint has been exercised against every tenant/entitlement configuration.
36
+ >
37
+ > - Treat your `ADAPTIVE_API_KEY` with the same care as portal admin credentials. Scope it
38
+ > to the minimum your use case requires.
39
+ > - The HTTP transport binds to `127.0.0.1` by default. Do not expose it to the public
40
+ > internet without adding authentication.
41
+ > - Keep Claude Desktop's tool-call approval enabled so you can see each request before it runs.
42
+
43
+ ## Tools
44
+
45
+ **15 tools across 5 domains** (all read-only), plus the `adaptive_request` escape hatch —
46
+ **16 total**. The table below groups them by domain.
47
+
48
+ | Domain | Tools | What it covers |
49
+ |--------|-------|----------------|
50
+ | **Users** | `list_users`, `get_user` | The org's people directory and per-user detail |
51
+ | **Groups** | `list_groups`, `get_group`, `get_group_members` | User groups and their membership |
52
+ | **Phishing** | `list_phishing_campaigns`, `get_phishing_campaign`, `list_campaign_simulations`, `get_simulation`, `get_phishing_enrollments` | Phishing simulation campaigns, the individual simulations within them, and per-user enrollment/results |
53
+ | **Training** | `list_training_campaigns`, `get_training_campaign`, `get_training_campaign_enrollments` | Security-awareness training campaigns and per-user enrollment/completion |
54
+ | **Audit Logs** | `list_audit_logs`, `get_audit_log` | Administrative audit trail, filterable by action type and date range |
55
+
56
+ See [`docs/ENDPOINTS.md`](docs/ENDPOINTS.md) for the **full tool ↔ method ↔ path mapping** (all
57
+ 15 tools).
58
+
59
+ **Highlights:**
60
+
61
+ - **List tools** (`list_users`, `list_phishing_campaigns`, …) are **cursor-paginated** —
62
+ pass `page_size` and a `page_after` cursor; the response carries the next `page_after`.
63
+ See [Pagination & responses](#pagination--responses).
64
+ - **Filter tools** (`get_phishing_enrollments`, `get_training_campaign_enrollments`) narrow
65
+ enrollment data by `user_id` / `campaign_id` / `simulation_id`.
66
+ - **`list_audit_logs`** filters the admin audit trail by `start_date`, `end_date`, and a list
67
+ of `actions` (e.g. `CREATED_TRAINING_CAMPAIGN`, `SCHEDULED_TRAINING_CAMPAIGN`, `ADDED_ADMIN`).
68
+ - **`adaptive_request` escape hatch** issues a raw `GET` against any path for endpoints
69
+ without a dedicated tool. It is GET-only by construction — it cannot mutate.
70
+
71
+ ## Quick start
72
+
73
+ ### Install
74
+
75
+ ```bash
76
+ # with uv (recommended)
77
+ uv tool install adaptive-mcp
78
+
79
+ # or with pip
80
+ pip install adaptive-mcp
81
+ ```
82
+
83
+ This installs the `adaptive-mcp` console script.
84
+
85
+ > [!NOTE]
86
+ > PyPI publishing is pending the first tagged release — until then, install from source
87
+ > (below). A push of a `v*` tag publishes to PyPI via GitHub Actions trusted publishing.
88
+
89
+ For development from source:
90
+
91
+ ```bash
92
+ git clone https://github.com/Space-C0wboy/Adaptive-Security-MCP-Server
93
+ cd Adaptive-Security-MCP-Server
94
+ uv venv && uv pip install -e ".[dev]"
95
+ ```
96
+
97
+ ### Getting an API token
98
+
99
+ 1. In the Adaptive Admin portal, go to **Settings → API Tokens**.
100
+ 2. Create a token and copy it — this is your `ADAPTIVE_API_KEY`.
101
+
102
+ Requests authenticate with the **`Authorization: Bearer <token>`** header; this server sets
103
+ it for you on every request.
104
+
105
+ ### Configuration
106
+
107
+ Copy `.env.example` to `.env` and set:
108
+
109
+ | Variable | Required | Default | Description |
110
+ |----------|----------|---------|-------------|
111
+ | `ADAPTIVE_API_KEY` | **yes** | — | Your Adaptive API token (Settings → API Tokens) |
112
+ | `ADAPTIVE_BASE_URL` | no | `https://api.adaptivesecurity.com` | API root |
113
+ | `ADAPTIVE_TIMEOUT` | no | `60` | Request timeout in seconds |
114
+ | `LOG_LEVEL` | no | `INFO` | Logging level (logs go to stderr) |
115
+ | `MCP_HTTP_HOST` / `MCP_HTTP_PORT` | no | `127.0.0.1:8765` | HTTP transport bind |
116
+
117
+ ### Run
118
+
119
+ - **stdio** (default, for Claude Desktop/Code): `adaptive-mcp` (or `uv run adaptive-mcp` from source)
120
+ - **HTTP**: `adaptive-mcp --transport http --port 8765`
121
+
122
+ ## Pagination & responses
123
+
124
+ Adaptive list/filter endpoints use **opaque cursor pagination** via two query parameters:
125
+
126
+ | Parameter | Type | Meaning |
127
+ |-----------|------|---------|
128
+ | `page_size` | integer | Max records per page. Default **50** for `list_groups`, `list_phishing_campaigns`, `list_campaign_simulations`, and `get_phishing_enrollments`; **100** for every other list/filter tool. |
129
+ | `page_after` | string | Opaque cursor for the next page. Omit on the first call; pass the value returned by the previous response. |
130
+
131
+ **Response envelope:** a list response is an object with the records under a domain-named key
132
+ plus the next cursor, e.g.:
133
+
134
+ ```json
135
+ {
136
+ "users": [ { "id": "...", "email": "..." } ],
137
+ "page_after": "eyJpZCI6..."
138
+ }
139
+ ```
140
+
141
+ To page through everything, keep calling the same tool with `page_after` set to the value
142
+ from the previous response until `page_after` comes back empty/absent.
143
+
144
+ Filter parameters on specific tools:
145
+
146
+ | Tool | Filters |
147
+ |------|---------|
148
+ | `get_phishing_enrollments` | `user_id`, `campaign_id`, `simulation_id` |
149
+ | `get_training_campaign_enrollments` | `user_id`, `campaign_id` |
150
+ | `list_audit_logs` | `start_date`, `end_date`, `actions` (list of action types) |
151
+
152
+ ## Editor integration
153
+
154
+ ### Claude Code
155
+
156
+ ```bash
157
+ claude mcp add adaptive \
158
+ --env ADAPTIVE_API_KEY=your-token-here \
159
+ -- adaptive-mcp
160
+ ```
161
+
162
+ From source (not yet installed as a tool):
163
+
164
+ ```bash
165
+ claude mcp add adaptive \
166
+ --env ADAPTIVE_API_KEY=your-token-here \
167
+ -- uv run --directory /absolute/path/to/Adaptive-Security-MCP-Server adaptive-mcp
168
+ ```
169
+
170
+ ### Claude Desktop
171
+
172
+ Edit `claude_desktop_config.json`:
173
+ - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
174
+ - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
175
+
176
+ ```json
177
+ {
178
+ "mcpServers": {
179
+ "adaptive": {
180
+ "command": "adaptive-mcp",
181
+ "env": {
182
+ "ADAPTIVE_API_KEY": "your-token-here"
183
+ }
184
+ }
185
+ }
186
+ }
187
+ ```
188
+
189
+ If running from source instead of an installed tool, use `uv` with `--directory`:
190
+
191
+ ```json
192
+ {
193
+ "mcpServers": {
194
+ "adaptive": {
195
+ "command": "uv",
196
+ "args": ["run", "--directory", "/absolute/path/to/Adaptive-Security-MCP-Server", "adaptive-mcp"],
197
+ "env": { "ADAPTIVE_API_KEY": "your-token-here" }
198
+ }
199
+ }
200
+ }
201
+ ```
202
+
203
+ Restart Claude Desktop, then confirm `adaptive` appears in the tools menu.
204
+
205
+ ## Example prompts
206
+
207
+ - *"List the first 25 users."* → `list_users` (`page_size=25`).
208
+ - *"Get the details for user `<id>`."* → `get_user` (`userId=<id>`).
209
+ - *"What groups do we have, and who's in the Finance group?"* → `list_groups` → `get_group_members` (`groupId=<id>`).
210
+ - *"Show our phishing campaigns and the simulations in campaign `<id>`."* →
211
+ `list_phishing_campaigns` → `list_campaign_simulations` (`campaignId=<id>`).
212
+ - *"How did user `<id>` do on the phishing simulations?"* → `get_phishing_enrollments` (`user_id=<id>`).
213
+ - *"Which users haven't completed training campaign `<id>`?"* →
214
+ `get_training_campaign_enrollments` (`campaign_id=<id>`).
215
+ - *"Show admin actions in the last week."* → `list_audit_logs`
216
+ (`start_date`, `end_date`, `actions=["ADDED_ADMIN", "CREATED_TRAINING_CAMPAIGN"]`).
217
+ - *"Call an endpoint I don't have a dedicated tool for."* → `adaptive_request` (`path`, optional `params`).
218
+
219
+ ## How tools are generated
220
+
221
+ The tool modules are generated from the Adaptive OpenAPI specification:
222
+
223
+ ```bash
224
+ uv run python scripts/generate_from_openapi.py
225
+ ```
226
+
227
+ This regenerates the modules under `src/adaptive_mcp/tools/_generated/` and the catalog at
228
+ [`docs/ENDPOINTS.md`](docs/ENDPOINTS.md). The generated files are **not hand-edited** — to
229
+ change a tool, edit the generator (its `OVERRIDES` map) and regenerate. Generation is
230
+ deterministic, so re-running it produces a byte-identical, reviewable diff.
231
+
232
+ The OpenAPI spec and other Adaptive reference material live in the **`Source Material/`**
233
+ directory, which is **gitignored** (vendor reference material, not redistributed). CI installs
234
+ from the committed `_generated/` modules and does not regenerate.
235
+
236
+ Key generator behavior:
237
+ - Operations are grouped by OpenAPI tag into one module per domain.
238
+ - Only `GET` operations are generated (the API is read-only); path parameters are interpolated
239
+ into the URL and query parameters are forwarded with their spec defaults.
240
+ - Tool names are the snake_case form of each `operationId`.
241
+
242
+ ## Development
243
+
244
+ ```bash
245
+ uv run pytest # full suite (httpx fully mocked; no live calls)
246
+ uv run ruff check . # lint
247
+ uv run python scripts/generate_from_openapi.py # regenerate tools + ENDPOINTS.md
248
+ ```
249
+
250
+ CI runs ruff + pytest on Python 3.10 / 3.11 / 3.12 (see `.github/workflows/ci.yml`). A pushed
251
+ `v*` tag builds and publishes to PyPI via trusted publishing (see `.github/workflows/release.yml`).
252
+
253
+ ## License
254
+
255
+ [MIT](LICENSE)
256
+
257
+ ## Support
258
+
259
+ This is an unofficial, internal project. For Adaptive platform or API questions, contact
260
+ Adaptive Security directly. For issues with this MCP server, open an issue on the
261
+ [GitHub repository](https://github.com/Space-C0wboy/Adaptive-Security-MCP-Server/issues).