dopesecurity-mcp-server 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.
- dopesecurity_mcp_server-0.1.0/.gitignore +15 -0
- dopesecurity_mcp_server-0.1.0/CHANGELOG.md +7 -0
- dopesecurity_mcp_server-0.1.0/LICENSE +21 -0
- dopesecurity_mcp_server-0.1.0/PKG-INFO +241 -0
- dopesecurity_mcp_server-0.1.0/README.md +211 -0
- dopesecurity_mcp_server-0.1.0/VERSION +1 -0
- dopesecurity_mcp_server-0.1.0/pyproject.toml +94 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/__init__.py +1 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/__init__.py +5 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/__main__.py +135 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/auth.py +209 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/config.py +172 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/errors.py +236 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/flightdeck/__init__.py +1 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/flightdeck/client.py +437 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/flightdeck/models.py +27 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/instructions.py +69 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/py.typed +1 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/schemas.py +578 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/server.py +139 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/services/__init__.py +1 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/services/custom_categories.py +93 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/services/endpoints.py +43 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/services/policies.py +433 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/tools/__init__.py +17 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/tools/custom_categories.py +158 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/tools/endpoints.py +69 -0
- dopesecurity_mcp_server-0.1.0/src/dopesecurity/mcp_server/tools/policies.py +438 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
.venv/
|
|
2
|
+
.pytest_cache/
|
|
3
|
+
.ruff_cache/
|
|
4
|
+
.mypy_cache/
|
|
5
|
+
.amp/
|
|
6
|
+
.ropeproject/
|
|
7
|
+
dist/
|
|
8
|
+
*.egg-info/
|
|
9
|
+
__pycache__/
|
|
10
|
+
*.pyc
|
|
11
|
+
.DS_Store
|
|
12
|
+
|
|
13
|
+
# Scratch file used to capture failing tool runs during development.
|
|
14
|
+
# Repo-root only; intentionally not docs/failures.md.
|
|
15
|
+
/failures.md
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dope.security
|
|
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,241 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dopesecurity-mcp-server
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local MCP server for the dope.security Flightdeck partner API
|
|
5
|
+
Project-URL: Homepage, https://dope.security
|
|
6
|
+
Project-URL: Repository, https://github.com/dopesecurity/mcp
|
|
7
|
+
Project-URL: Changelog, https://github.com/dopesecurity/mcp/blob/main/CHANGELOG.md
|
|
8
|
+
Author: dope.security
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ai,dope.security,mcp,model-context-protocol,security,swg
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Information Technology
|
|
14
|
+
Classifier: Intended Audience :: System Administrators
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Security
|
|
21
|
+
Classifier: Topic :: System :: Systems Administration
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Python: >=3.11
|
|
24
|
+
Requires-Dist: httpx>=0.27.0
|
|
25
|
+
Requires-Dist: mcp>=1.2.0
|
|
26
|
+
Requires-Dist: pydantic-settings>=2.2
|
|
27
|
+
Requires-Dist: pydantic>=2.6
|
|
28
|
+
Requires-Dist: structlog>=24.1.0
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# dopesecurity-mcp-server
|
|
32
|
+
|
|
33
|
+
The Dope MCP is a local [Model Context Protocol](https://modelcontextprotocol.io)
|
|
34
|
+
server that lets an AI assistant talk to your dope.security tenant —
|
|
35
|
+
look at endpoints, read and tweak policies, and curate custom URL
|
|
36
|
+
categories. It wraps most of the Flightdeck partner API, runs on your
|
|
37
|
+
machine, and is **read-only out of the box**: nothing changes in your
|
|
38
|
+
tenant until you explicitly turn writes on. It's currently in beta, we
|
|
39
|
+
hope you enjoy using it.
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
Installation is via `uvx`.
|
|
44
|
+
|
|
45
|
+
Runs the server on demand. Nothing is installed globally.
|
|
46
|
+
|
|
47
|
+
**Prerequisites**
|
|
48
|
+
|
|
49
|
+
1. Install `uv` — see [Astral's install guide](https://docs.astral.sh/uv/getting-started/installation/).
|
|
50
|
+
2. Install a Python runtime with `uv`:
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
uv python install 3.11
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**MCP client config**
|
|
57
|
+
|
|
58
|
+
Add the server to your MCP client configuration:
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"mcpServers": {
|
|
63
|
+
"dope-security": {
|
|
64
|
+
"command": "uvx",
|
|
65
|
+
"args": ["dopesecurity-mcp-server"],
|
|
66
|
+
"env": {
|
|
67
|
+
"DOPE_CLIENT_ID": "your-client-id",
|
|
68
|
+
"DOPE_CLIENT_SECRET": "your-client-secret",
|
|
69
|
+
"DOPE_ENABLE_MUTATIONS": "false",
|
|
70
|
+
"DOPE_ENABLE_DESTRUCTIVE": "false"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Three tiers of access
|
|
78
|
+
|
|
79
|
+
The tool surface is gated by two environment variables, both `false`
|
|
80
|
+
by default. Tools that aren't enabled by the active combination are
|
|
81
|
+
**not registered** at all — they don't exist on the MCP wire.
|
|
82
|
+
|
|
83
|
+
| `DOPE_ENABLE_MUTATIONS` | `DOPE_ENABLE_DESTRUCTIVE` | What the agent can do |
|
|
84
|
+
| ----------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
85
|
+
| `false` | `false` | **Read-only.** Inspect endpoints, policies, custom categories. Cannot modify the tenant. |
|
|
86
|
+
| `true` | `false` | **Read + write.** Per-entry creates, updates, upserts, assigns, unassigns, and per-entry deletes. Cannot drop a whole policy or wipe a section. |
|
|
87
|
+
| `true` | `true` | **Read + write + destructive.** Adds whole-policy drops, whole-section resets to base, whole-custom-category deletes, and wipe-all-URLs. |
|
|
88
|
+
| `false` | `true` | Invalid — the server refuses to start. |
|
|
89
|
+
|
|
90
|
+
Flightdeck RBAC still applies on top of whichever tier you enable:
|
|
91
|
+
even when a tool is registered, Flightdeck may reject the call because
|
|
92
|
+
your OAuth client's role doesn't permit it. Start with read-only,
|
|
93
|
+
flip to mutations when you trust the agent's workflow, and only enable
|
|
94
|
+
destructive when you explicitly want the agent to be able to start
|
|
95
|
+
over.
|
|
96
|
+
|
|
97
|
+
## Configuration reference
|
|
98
|
+
|
|
99
|
+
| Env var | CLI flag | Default | Description |
|
|
100
|
+
| ------------------------ | ---------------------- | ------- | -------------------------------------------------------------------------------------------- |
|
|
101
|
+
| `DOPE_CLIENT_ID` | — | — | API client ID issued from the dope console. **Required.** |
|
|
102
|
+
| `DOPE_CLIENT_SECRET` | — | — | API client secret issued from the dope console. **Required.** |
|
|
103
|
+
| `DOPE_ENABLE_MUTATIONS` | `--enable-mutations` | `false` | Expose write tools that modify tenant state. |
|
|
104
|
+
| `DOPE_ENABLE_DESTRUCTIVE`| `--enable-destructive` | `false` | Additionally expose destructive tools (whole-policy drops, whole-section resets). Requires mutations. |
|
|
105
|
+
| `DOPE_TIMEOUT_SECONDS` | `--timeout-seconds` | `30` | HTTP timeout for Flightdeck calls. |
|
|
106
|
+
| `DOPE_LOG_LEVEL` | `--log-level` | `INFO` | Log verbosity (logs go to stderr only). |
|
|
107
|
+
|
|
108
|
+
`DOPE_CLIENT_ID` and `DOPE_CLIENT_SECRET` should be provided as
|
|
109
|
+
environment variables. You can grab the credentials from the
|
|
110
|
+
[dope console](https://inflight.dope.security/dope.console/settings/api-client-credentials).
|
|
111
|
+
|
|
112
|
+
## Available tools
|
|
113
|
+
|
|
114
|
+
### Endpoints (read-only)
|
|
115
|
+
|
|
116
|
+
| Tool | Description |
|
|
117
|
+
| ------------------- | ---------------------------------------- |
|
|
118
|
+
| `search_endpoints` | List or search endpoints (cursor paged). |
|
|
119
|
+
|
|
120
|
+
### Policies (read)
|
|
121
|
+
|
|
122
|
+
| Tool | Description |
|
|
123
|
+
| ---------------------------------------- | ---------------------------------------- |
|
|
124
|
+
| `list_policies` | List all policies. |
|
|
125
|
+
| `get_policy_assignments` | Show users/groups assigned to a policy. |
|
|
126
|
+
| `get_policy_restrictions` | Show per-category restrictions. |
|
|
127
|
+
| `get_policy_exceptions` | Show per-category exceptions. |
|
|
128
|
+
| `get_policy_url_bypass` | List URL bypass entries. |
|
|
129
|
+
| `get_policy_application_bypass_entries` | List application bypass entries. |
|
|
130
|
+
|
|
131
|
+
### Policies (write — only when mutations enabled)
|
|
132
|
+
|
|
133
|
+
| Tool | Description |
|
|
134
|
+
| --------------------------------------------- | ---------------------------------------------- |
|
|
135
|
+
| `create_policy` | Create a new policy. |
|
|
136
|
+
| `assign_policy_principals` | Add users/groups to a policy. |
|
|
137
|
+
| `unassign_policy_principals` | Remove users/groups from a policy. |
|
|
138
|
+
| `update_policy_restrictions` | Update per-category restrictions. |
|
|
139
|
+
| `replace_policy_category_exceptions` | Replace exceptions for the submitted category. |
|
|
140
|
+
| `upsert_policy_url_bypass` | Add or update URL bypass entries. |
|
|
141
|
+
| `delete_policy_url_bypass_entries` | Delete named URL bypass entries. |
|
|
142
|
+
| `upsert_policy_application_bypass` | Add or update application bypass entries. |
|
|
143
|
+
| `delete_policy_application_bypass_entries` | Delete named application bypass entries. |
|
|
144
|
+
|
|
145
|
+
### Policies (destructive — only when both mutations and destructive are enabled)
|
|
146
|
+
|
|
147
|
+
| Tool | Description |
|
|
148
|
+
| ------------------------------------------ | ---------------------------------------- |
|
|
149
|
+
| `delete_policy` | Delete a whole policy. |
|
|
150
|
+
| `reset_policy_restrictions_to_base` | Reset all restrictions to Base. |
|
|
151
|
+
| `reset_policy_url_bypass_to_base` | Reset URL bypass to Base. |
|
|
152
|
+
| `reset_policy_application_bypass_to_base` | Reset application bypass to Base. |
|
|
153
|
+
|
|
154
|
+
### Custom categories (read)
|
|
155
|
+
|
|
156
|
+
| Tool | Description |
|
|
157
|
+
| -------------------------- | --------------------------------- |
|
|
158
|
+
| `list_custom_categories` | List all custom categories. |
|
|
159
|
+
| `get_custom_category_urls` | List URLs in a custom category. |
|
|
160
|
+
|
|
161
|
+
### Custom categories (write — only when mutations enabled)
|
|
162
|
+
|
|
163
|
+
| Tool | Description |
|
|
164
|
+
| ------------------------------------- | ------------------------------------ |
|
|
165
|
+
| `create_custom_category` | Create a new custom category. |
|
|
166
|
+
| `add_urls_to_custom_category` | Add URLs to a custom category. |
|
|
167
|
+
| `delete_single_url_from_custom_category` | Remove one URL from a category. |
|
|
168
|
+
|
|
169
|
+
### Custom categories (destructive — only when both mutations and destructive are enabled)
|
|
170
|
+
|
|
171
|
+
| Tool | Description |
|
|
172
|
+
| ------------------------------------- | ------------------------------------ |
|
|
173
|
+
| `delete_custom_category` | Delete a whole custom category. |
|
|
174
|
+
| `delete_all_urls_from_custom_category`| Wipe every URL from a category. |
|
|
175
|
+
|
|
176
|
+
## Developing
|
|
177
|
+
|
|
178
|
+
### Setup and verification
|
|
179
|
+
|
|
180
|
+
From the repository root:
|
|
181
|
+
|
|
182
|
+
```sh
|
|
183
|
+
make install # uv sync --locked
|
|
184
|
+
make check # lint + typecheck + unit tests
|
|
185
|
+
make integration-tests # requires DOPE_MCP_TESTS_CLIENT_SECRET
|
|
186
|
+
uv run dopesecurity-mcp-server --help
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Run `make help` to see all available targets.
|
|
190
|
+
|
|
191
|
+
### Known limitations
|
|
192
|
+
|
|
193
|
+
- `assign_policy_principals` and `unassign_policy_principals` are
|
|
194
|
+
read-merge-write on top of Flightdeck's overwrite-only assignments
|
|
195
|
+
endpoint, so concurrent edits to the same policy may be clobbered.
|
|
196
|
+
- Pagination is cursor-based; the mcp server does not auto-fetch all pages.
|
|
197
|
+
|
|
198
|
+
### Flightdeck routes deliberately omitted from MCP
|
|
199
|
+
|
|
200
|
+
Some Flightdeck partner API routes are intentionally **not** exposed as
|
|
201
|
+
MCP tools and will not be added. This is the list — treat it as a
|
|
202
|
+
"don't bother proposing this" register.
|
|
203
|
+
|
|
204
|
+
- `PUT /custom_categories/{name}/urls` — overwrite-all semantics. An
|
|
205
|
+
agent calling this with a partial list silently destroys every URL it
|
|
206
|
+
didn't mention. Use `add_urls_to_custom_category`,
|
|
207
|
+
`delete_single_url_from_custom_category`, and
|
|
208
|
+
`delete_all_urls_from_custom_category` instead, which force the agent
|
|
209
|
+
to state intent explicitly.
|
|
210
|
+
|
|
211
|
+
### Running a local checkout from an MCP client
|
|
212
|
+
|
|
213
|
+
To point an MCP client (Amp, Claude Desktop, etc.) at your local checkout
|
|
214
|
+
instead of the published `uvx` package, replace the `command`/`args` so the
|
|
215
|
+
client launches the server through `uv run --directory`:
|
|
216
|
+
|
|
217
|
+
```json
|
|
218
|
+
{
|
|
219
|
+
"mcpServers": {
|
|
220
|
+
"dope-security-dev": {
|
|
221
|
+
"command": "uv",
|
|
222
|
+
"args": [
|
|
223
|
+
"run",
|
|
224
|
+
"--directory",
|
|
225
|
+
"/absolute/path/to/dopemcp",
|
|
226
|
+
"dopesecurity-mcp-server"
|
|
227
|
+
],
|
|
228
|
+
"env": {
|
|
229
|
+
"DOPE_CLIENT_ID": "your-client-id",
|
|
230
|
+
"DOPE_CLIENT_SECRET": "your-client-secret",
|
|
231
|
+
"DOPE_ENABLE_MUTATIONS": "true",
|
|
232
|
+
"DOPE_ENABLE_DESTRUCTIVE": "true",
|
|
233
|
+
"DOPE_LOG_LEVEL": "DEBUG"
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Replace `/absolute/path/to/dopemcp` with the path to your clone. The MCP
|
|
241
|
+
client spawns the server over stdio on demand.
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# dopesecurity-mcp-server
|
|
2
|
+
|
|
3
|
+
The Dope MCP is a local [Model Context Protocol](https://modelcontextprotocol.io)
|
|
4
|
+
server that lets an AI assistant talk to your dope.security tenant —
|
|
5
|
+
look at endpoints, read and tweak policies, and curate custom URL
|
|
6
|
+
categories. It wraps most of the Flightdeck partner API, runs on your
|
|
7
|
+
machine, and is **read-only out of the box**: nothing changes in your
|
|
8
|
+
tenant until you explicitly turn writes on. It's currently in beta, we
|
|
9
|
+
hope you enjoy using it.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
Installation is via `uvx`.
|
|
14
|
+
|
|
15
|
+
Runs the server on demand. Nothing is installed globally.
|
|
16
|
+
|
|
17
|
+
**Prerequisites**
|
|
18
|
+
|
|
19
|
+
1. Install `uv` — see [Astral's install guide](https://docs.astral.sh/uv/getting-started/installation/).
|
|
20
|
+
2. Install a Python runtime with `uv`:
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
uv python install 3.11
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**MCP client config**
|
|
27
|
+
|
|
28
|
+
Add the server to your MCP client configuration:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"mcpServers": {
|
|
33
|
+
"dope-security": {
|
|
34
|
+
"command": "uvx",
|
|
35
|
+
"args": ["dopesecurity-mcp-server"],
|
|
36
|
+
"env": {
|
|
37
|
+
"DOPE_CLIENT_ID": "your-client-id",
|
|
38
|
+
"DOPE_CLIENT_SECRET": "your-client-secret",
|
|
39
|
+
"DOPE_ENABLE_MUTATIONS": "false",
|
|
40
|
+
"DOPE_ENABLE_DESTRUCTIVE": "false"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Three tiers of access
|
|
48
|
+
|
|
49
|
+
The tool surface is gated by two environment variables, both `false`
|
|
50
|
+
by default. Tools that aren't enabled by the active combination are
|
|
51
|
+
**not registered** at all — they don't exist on the MCP wire.
|
|
52
|
+
|
|
53
|
+
| `DOPE_ENABLE_MUTATIONS` | `DOPE_ENABLE_DESTRUCTIVE` | What the agent can do |
|
|
54
|
+
| ----------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
55
|
+
| `false` | `false` | **Read-only.** Inspect endpoints, policies, custom categories. Cannot modify the tenant. |
|
|
56
|
+
| `true` | `false` | **Read + write.** Per-entry creates, updates, upserts, assigns, unassigns, and per-entry deletes. Cannot drop a whole policy or wipe a section. |
|
|
57
|
+
| `true` | `true` | **Read + write + destructive.** Adds whole-policy drops, whole-section resets to base, whole-custom-category deletes, and wipe-all-URLs. |
|
|
58
|
+
| `false` | `true` | Invalid — the server refuses to start. |
|
|
59
|
+
|
|
60
|
+
Flightdeck RBAC still applies on top of whichever tier you enable:
|
|
61
|
+
even when a tool is registered, Flightdeck may reject the call because
|
|
62
|
+
your OAuth client's role doesn't permit it. Start with read-only,
|
|
63
|
+
flip to mutations when you trust the agent's workflow, and only enable
|
|
64
|
+
destructive when you explicitly want the agent to be able to start
|
|
65
|
+
over.
|
|
66
|
+
|
|
67
|
+
## Configuration reference
|
|
68
|
+
|
|
69
|
+
| Env var | CLI flag | Default | Description |
|
|
70
|
+
| ------------------------ | ---------------------- | ------- | -------------------------------------------------------------------------------------------- |
|
|
71
|
+
| `DOPE_CLIENT_ID` | — | — | API client ID issued from the dope console. **Required.** |
|
|
72
|
+
| `DOPE_CLIENT_SECRET` | — | — | API client secret issued from the dope console. **Required.** |
|
|
73
|
+
| `DOPE_ENABLE_MUTATIONS` | `--enable-mutations` | `false` | Expose write tools that modify tenant state. |
|
|
74
|
+
| `DOPE_ENABLE_DESTRUCTIVE`| `--enable-destructive` | `false` | Additionally expose destructive tools (whole-policy drops, whole-section resets). Requires mutations. |
|
|
75
|
+
| `DOPE_TIMEOUT_SECONDS` | `--timeout-seconds` | `30` | HTTP timeout for Flightdeck calls. |
|
|
76
|
+
| `DOPE_LOG_LEVEL` | `--log-level` | `INFO` | Log verbosity (logs go to stderr only). |
|
|
77
|
+
|
|
78
|
+
`DOPE_CLIENT_ID` and `DOPE_CLIENT_SECRET` should be provided as
|
|
79
|
+
environment variables. You can grab the credentials from the
|
|
80
|
+
[dope console](https://inflight.dope.security/dope.console/settings/api-client-credentials).
|
|
81
|
+
|
|
82
|
+
## Available tools
|
|
83
|
+
|
|
84
|
+
### Endpoints (read-only)
|
|
85
|
+
|
|
86
|
+
| Tool | Description |
|
|
87
|
+
| ------------------- | ---------------------------------------- |
|
|
88
|
+
| `search_endpoints` | List or search endpoints (cursor paged). |
|
|
89
|
+
|
|
90
|
+
### Policies (read)
|
|
91
|
+
|
|
92
|
+
| Tool | Description |
|
|
93
|
+
| ---------------------------------------- | ---------------------------------------- |
|
|
94
|
+
| `list_policies` | List all policies. |
|
|
95
|
+
| `get_policy_assignments` | Show users/groups assigned to a policy. |
|
|
96
|
+
| `get_policy_restrictions` | Show per-category restrictions. |
|
|
97
|
+
| `get_policy_exceptions` | Show per-category exceptions. |
|
|
98
|
+
| `get_policy_url_bypass` | List URL bypass entries. |
|
|
99
|
+
| `get_policy_application_bypass_entries` | List application bypass entries. |
|
|
100
|
+
|
|
101
|
+
### Policies (write — only when mutations enabled)
|
|
102
|
+
|
|
103
|
+
| Tool | Description |
|
|
104
|
+
| --------------------------------------------- | ---------------------------------------------- |
|
|
105
|
+
| `create_policy` | Create a new policy. |
|
|
106
|
+
| `assign_policy_principals` | Add users/groups to a policy. |
|
|
107
|
+
| `unassign_policy_principals` | Remove users/groups from a policy. |
|
|
108
|
+
| `update_policy_restrictions` | Update per-category restrictions. |
|
|
109
|
+
| `replace_policy_category_exceptions` | Replace exceptions for the submitted category. |
|
|
110
|
+
| `upsert_policy_url_bypass` | Add or update URL bypass entries. |
|
|
111
|
+
| `delete_policy_url_bypass_entries` | Delete named URL bypass entries. |
|
|
112
|
+
| `upsert_policy_application_bypass` | Add or update application bypass entries. |
|
|
113
|
+
| `delete_policy_application_bypass_entries` | Delete named application bypass entries. |
|
|
114
|
+
|
|
115
|
+
### Policies (destructive — only when both mutations and destructive are enabled)
|
|
116
|
+
|
|
117
|
+
| Tool | Description |
|
|
118
|
+
| ------------------------------------------ | ---------------------------------------- |
|
|
119
|
+
| `delete_policy` | Delete a whole policy. |
|
|
120
|
+
| `reset_policy_restrictions_to_base` | Reset all restrictions to Base. |
|
|
121
|
+
| `reset_policy_url_bypass_to_base` | Reset URL bypass to Base. |
|
|
122
|
+
| `reset_policy_application_bypass_to_base` | Reset application bypass to Base. |
|
|
123
|
+
|
|
124
|
+
### Custom categories (read)
|
|
125
|
+
|
|
126
|
+
| Tool | Description |
|
|
127
|
+
| -------------------------- | --------------------------------- |
|
|
128
|
+
| `list_custom_categories` | List all custom categories. |
|
|
129
|
+
| `get_custom_category_urls` | List URLs in a custom category. |
|
|
130
|
+
|
|
131
|
+
### Custom categories (write — only when mutations enabled)
|
|
132
|
+
|
|
133
|
+
| Tool | Description |
|
|
134
|
+
| ------------------------------------- | ------------------------------------ |
|
|
135
|
+
| `create_custom_category` | Create a new custom category. |
|
|
136
|
+
| `add_urls_to_custom_category` | Add URLs to a custom category. |
|
|
137
|
+
| `delete_single_url_from_custom_category` | Remove one URL from a category. |
|
|
138
|
+
|
|
139
|
+
### Custom categories (destructive — only when both mutations and destructive are enabled)
|
|
140
|
+
|
|
141
|
+
| Tool | Description |
|
|
142
|
+
| ------------------------------------- | ------------------------------------ |
|
|
143
|
+
| `delete_custom_category` | Delete a whole custom category. |
|
|
144
|
+
| `delete_all_urls_from_custom_category`| Wipe every URL from a category. |
|
|
145
|
+
|
|
146
|
+
## Developing
|
|
147
|
+
|
|
148
|
+
### Setup and verification
|
|
149
|
+
|
|
150
|
+
From the repository root:
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
make install # uv sync --locked
|
|
154
|
+
make check # lint + typecheck + unit tests
|
|
155
|
+
make integration-tests # requires DOPE_MCP_TESTS_CLIENT_SECRET
|
|
156
|
+
uv run dopesecurity-mcp-server --help
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Run `make help` to see all available targets.
|
|
160
|
+
|
|
161
|
+
### Known limitations
|
|
162
|
+
|
|
163
|
+
- `assign_policy_principals` and `unassign_policy_principals` are
|
|
164
|
+
read-merge-write on top of Flightdeck's overwrite-only assignments
|
|
165
|
+
endpoint, so concurrent edits to the same policy may be clobbered.
|
|
166
|
+
- Pagination is cursor-based; the mcp server does not auto-fetch all pages.
|
|
167
|
+
|
|
168
|
+
### Flightdeck routes deliberately omitted from MCP
|
|
169
|
+
|
|
170
|
+
Some Flightdeck partner API routes are intentionally **not** exposed as
|
|
171
|
+
MCP tools and will not be added. This is the list — treat it as a
|
|
172
|
+
"don't bother proposing this" register.
|
|
173
|
+
|
|
174
|
+
- `PUT /custom_categories/{name}/urls` — overwrite-all semantics. An
|
|
175
|
+
agent calling this with a partial list silently destroys every URL it
|
|
176
|
+
didn't mention. Use `add_urls_to_custom_category`,
|
|
177
|
+
`delete_single_url_from_custom_category`, and
|
|
178
|
+
`delete_all_urls_from_custom_category` instead, which force the agent
|
|
179
|
+
to state intent explicitly.
|
|
180
|
+
|
|
181
|
+
### Running a local checkout from an MCP client
|
|
182
|
+
|
|
183
|
+
To point an MCP client (Amp, Claude Desktop, etc.) at your local checkout
|
|
184
|
+
instead of the published `uvx` package, replace the `command`/`args` so the
|
|
185
|
+
client launches the server through `uv run --directory`:
|
|
186
|
+
|
|
187
|
+
```json
|
|
188
|
+
{
|
|
189
|
+
"mcpServers": {
|
|
190
|
+
"dope-security-dev": {
|
|
191
|
+
"command": "uv",
|
|
192
|
+
"args": [
|
|
193
|
+
"run",
|
|
194
|
+
"--directory",
|
|
195
|
+
"/absolute/path/to/dopemcp",
|
|
196
|
+
"dopesecurity-mcp-server"
|
|
197
|
+
],
|
|
198
|
+
"env": {
|
|
199
|
+
"DOPE_CLIENT_ID": "your-client-id",
|
|
200
|
+
"DOPE_CLIENT_SECRET": "your-client-secret",
|
|
201
|
+
"DOPE_ENABLE_MUTATIONS": "true",
|
|
202
|
+
"DOPE_ENABLE_DESTRUCTIVE": "true",
|
|
203
|
+
"DOPE_LOG_LEVEL": "DEBUG"
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Replace `/absolute/path/to/dopemcp` with the path to your clone. The MCP
|
|
211
|
+
client spawns the server over stdio on demand.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.0
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "dopesecurity-mcp-server"
|
|
3
|
+
dynamic = ["version"]
|
|
4
|
+
description = "Local MCP server for the dope.security Flightdeck partner API"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
license-files = ["LICENSE"]
|
|
9
|
+
authors = [{ name = "dope.security" }]
|
|
10
|
+
keywords = ["mcp", "model-context-protocol", "ai", "dope.security", "security", "swg"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 4 - Beta",
|
|
13
|
+
"Intended Audience :: System Administrators",
|
|
14
|
+
"Intended Audience :: Information Technology",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.11",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Programming Language :: Python :: 3.13",
|
|
20
|
+
"Topic :: Security",
|
|
21
|
+
"Topic :: System :: Systems Administration",
|
|
22
|
+
"Typing :: Typed",
|
|
23
|
+
]
|
|
24
|
+
dependencies = [
|
|
25
|
+
"mcp>=1.2.0",
|
|
26
|
+
"httpx>=0.27.0",
|
|
27
|
+
"pydantic>=2.6",
|
|
28
|
+
"pydantic-settings>=2.2",
|
|
29
|
+
"structlog>=24.1.0",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://dope.security"
|
|
34
|
+
Repository = "https://github.com/dopesecurity/mcp"
|
|
35
|
+
Changelog = "https://github.com/dopesecurity/mcp/blob/main/CHANGELOG.md"
|
|
36
|
+
|
|
37
|
+
[project.scripts]
|
|
38
|
+
dopesecurity-mcp-server = "dopesecurity.mcp_server.__main__:main"
|
|
39
|
+
|
|
40
|
+
[build-system]
|
|
41
|
+
requires = ["hatchling"]
|
|
42
|
+
build-backend = "hatchling.build"
|
|
43
|
+
|
|
44
|
+
[tool.hatch.version]
|
|
45
|
+
path = "VERSION"
|
|
46
|
+
pattern = "^(?P<version>.+)$"
|
|
47
|
+
|
|
48
|
+
[tool.hatch.build.targets.wheel]
|
|
49
|
+
packages = ["src/dopesecurity"]
|
|
50
|
+
exclude = ["**/tests/**"]
|
|
51
|
+
|
|
52
|
+
[tool.hatch.build.targets.sdist]
|
|
53
|
+
include = [
|
|
54
|
+
"/src/dopesecurity",
|
|
55
|
+
"/README.md",
|
|
56
|
+
"/CHANGELOG.md",
|
|
57
|
+
"/LICENSE",
|
|
58
|
+
"/VERSION",
|
|
59
|
+
"/pyproject.toml",
|
|
60
|
+
]
|
|
61
|
+
exclude = ["**/tests/**"]
|
|
62
|
+
|
|
63
|
+
[dependency-groups]
|
|
64
|
+
dev = [
|
|
65
|
+
"pytest>=8.0",
|
|
66
|
+
"pytest-asyncio>=0.23",
|
|
67
|
+
"ruff>=0.5.0",
|
|
68
|
+
"mypy>=1.10",
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
[tool.ruff]
|
|
72
|
+
target-version = "py311"
|
|
73
|
+
src = ["src"]
|
|
74
|
+
line-length = 100
|
|
75
|
+
|
|
76
|
+
[tool.ruff.lint]
|
|
77
|
+
select = ["E", "F", "W", "I", "B", "UP", "N"]
|
|
78
|
+
ignore = ["E501"]
|
|
79
|
+
|
|
80
|
+
[tool.mypy]
|
|
81
|
+
python_version = "3.11"
|
|
82
|
+
strict = true
|
|
83
|
+
packages = ["dopesecurity.mcp_server"]
|
|
84
|
+
mypy_path = "src"
|
|
85
|
+
explicit_package_bases = true
|
|
86
|
+
|
|
87
|
+
[[tool.mypy.overrides]]
|
|
88
|
+
module = "mcp.*"
|
|
89
|
+
ignore_missing_imports = true
|
|
90
|
+
|
|
91
|
+
[tool.pytest.ini_options]
|
|
92
|
+
testpaths = ["src"]
|
|
93
|
+
asyncio_mode = "auto"
|
|
94
|
+
filterwarnings = ["error"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""dope.security Python packages."""
|