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.
- adaptive_mcp-0.1.0/.env.example +15 -0
- adaptive_mcp-0.1.0/.github/workflows/ci.yml +25 -0
- adaptive_mcp-0.1.0/.github/workflows/release.yml +36 -0
- adaptive_mcp-0.1.0/.gitignore +26 -0
- adaptive_mcp-0.1.0/LICENSE +21 -0
- adaptive_mcp-0.1.0/PKG-INFO +290 -0
- adaptive_mcp-0.1.0/README.md +261 -0
- adaptive_mcp-0.1.0/docs/ENDPOINTS.md +21 -0
- adaptive_mcp-0.1.0/docs/superpowers/plans/2026-06-09-adaptive-mcp-server.md +1999 -0
- adaptive_mcp-0.1.0/docs/superpowers/specs/2026-06-09-adaptive-mcp-server-design.md +251 -0
- adaptive_mcp-0.1.0/pyproject.toml +67 -0
- adaptive_mcp-0.1.0/scripts/generate_from_openapi.py +290 -0
- adaptive_mcp-0.1.0/scripts/smoke_test.py +27 -0
- adaptive_mcp-0.1.0/src/adaptive_mcp/__init__.py +5 -0
- adaptive_mcp-0.1.0/src/adaptive_mcp/client.py +212 -0
- adaptive_mcp-0.1.0/src/adaptive_mcp/config.py +107 -0
- adaptive_mcp-0.1.0/src/adaptive_mcp/errors.py +27 -0
- adaptive_mcp-0.1.0/src/adaptive_mcp/server.py +87 -0
- adaptive_mcp-0.1.0/src/adaptive_mcp/tools/__init__.py +21 -0
- adaptive_mcp-0.1.0/src/adaptive_mcp/tools/_common.py +40 -0
- adaptive_mcp-0.1.0/src/adaptive_mcp/tools/_generated/__init__.py +17 -0
- adaptive_mcp-0.1.0/src/adaptive_mcp/tools/_generated/audit_logs.py +40 -0
- adaptive_mcp-0.1.0/src/adaptive_mcp/tools/_generated/groups.py +46 -0
- adaptive_mcp-0.1.0/src/adaptive_mcp/tools/_generated/phishing.py +64 -0
- adaptive_mcp-0.1.0/src/adaptive_mcp/tools/_generated/training.py +47 -0
- adaptive_mcp-0.1.0/src/adaptive_mcp/tools/_generated/users.py +37 -0
- adaptive_mcp-0.1.0/src/adaptive_mcp/tools/request.py +41 -0
- adaptive_mcp-0.1.0/tests/__init__.py +0 -0
- adaptive_mcp-0.1.0/tests/fixtures/mini_openapi.json +38 -0
- adaptive_mcp-0.1.0/tests/test_client.py +97 -0
- adaptive_mcp-0.1.0/tests/test_common.py +45 -0
- adaptive_mcp-0.1.0/tests/test_config.py +67 -0
- adaptive_mcp-0.1.0/tests/test_errors.py +17 -0
- adaptive_mcp-0.1.0/tests/test_generator.py +92 -0
- adaptive_mcp-0.1.0/tests/test_registration.py +54 -0
- adaptive_mcp-0.1.0/tests/test_request_tool.py +24 -0
- 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
|
+
[](https://pypi.org/project/adaptive-mcp/)
|
|
33
|
+
[](https://pypi.org/project/adaptive-mcp/)
|
|
34
|
+
[](LICENSE)
|
|
35
|
+
[](https://github.com/Space-C0wboy/Adaptive-Security-MCP-Server/actions/workflows/ci.yml)
|
|
36
|
+
[](#)
|
|
37
|
+
[](#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
|
+
[](https://pypi.org/project/adaptive-mcp/)
|
|
4
|
+
[](https://pypi.org/project/adaptive-mcp/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://github.com/Space-C0wboy/Adaptive-Security-MCP-Server/actions/workflows/ci.yml)
|
|
7
|
+
[](#)
|
|
8
|
+
[](#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).
|