stig-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.
- stig_mcp-0.1.0/LICENSE +21 -0
- stig_mcp-0.1.0/MANIFEST.in +3 -0
- stig_mcp-0.1.0/NOTICE +102 -0
- stig_mcp-0.1.0/PKG-INFO +215 -0
- stig_mcp-0.1.0/README.md +196 -0
- stig_mcp-0.1.0/licenses/apache-2.0.txt +202 -0
- stig_mcp-0.1.0/pyproject.toml +96 -0
- stig_mcp-0.1.0/setup.cfg +4 -0
- stig_mcp-0.1.0/stig_mcp/__init__.py +0 -0
- stig_mcp-0.1.0/stig_mcp/applicability.py +254 -0
- stig_mcp-0.1.0/stig_mcp/applicability.yaml +34 -0
- stig_mcp-0.1.0/stig_mcp/ingest/__init__.py +0 -0
- stig_mcp-0.1.0/stig_mcp/ingest/attack_parser.py +199 -0
- stig_mcp-0.1.0/stig_mcp/ingest/catalog.py +259 -0
- stig_mcp-0.1.0/stig_mcp/ingest/cci_parser.py +67 -0
- stig_mcp-0.1.0/stig_mcp/ingest/config.py +140 -0
- stig_mcp-0.1.0/stig_mcp/ingest/control_catalog.py +59 -0
- stig_mcp-0.1.0/stig_mcp/ingest/control_id.py +14 -0
- stig_mcp-0.1.0/stig_mcp/ingest/currency.py +106 -0
- stig_mcp-0.1.0/stig_mcp/ingest/fetch.py +1016 -0
- stig_mcp-0.1.0/stig_mcp/ingest/id_corrections.py +149 -0
- stig_mcp-0.1.0/stig_mcp/ingest/id_corrections.yaml +38 -0
- stig_mcp-0.1.0/stig_mcp/ingest/inventory.py +365 -0
- stig_mcp-0.1.0/stig_mcp/ingest/library.py +282 -0
- stig_mcp-0.1.0/stig_mcp/ingest/mapping_loader.py +109 -0
- stig_mcp-0.1.0/stig_mcp/ingest/orchestrator.py +1479 -0
- stig_mcp-0.1.0/stig_mcp/ingest/severity.py +10 -0
- stig_mcp-0.1.0/stig_mcp/ingest/stig_parser.py +192 -0
- stig_mcp-0.1.0/stig_mcp/ingest/upstream.py +174 -0
- stig_mcp-0.1.0/stig_mcp/kb/__init__.py +0 -0
- stig_mcp-0.1.0/stig_mcp/kb/actor_match.py +125 -0
- stig_mcp-0.1.0/stig_mcp/kb/db.py +64 -0
- stig_mcp-0.1.0/stig_mcp/kb/freshness.py +145 -0
- stig_mcp-0.1.0/stig_mcp/kb/install.py +413 -0
- stig_mcp-0.1.0/stig_mcp/kb/queries.py +368 -0
- stig_mcp-0.1.0/stig_mcp/kb/releases.py +402 -0
- stig_mcp-0.1.0/stig_mcp/kb/schema.sql +123 -0
- stig_mcp-0.1.0/stig_mcp/resolver/__init__.py +0 -0
- stig_mcp-0.1.0/stig_mcp/resolver/aliases.yaml +54 -0
- stig_mcp-0.1.0/stig_mcp/resolver/normalize.py +207 -0
- stig_mcp-0.1.0/stig_mcp/resolver/resolver.py +938 -0
- stig_mcp-0.1.0/stig_mcp/server/__init__.py +0 -0
- stig_mcp-0.1.0/stig_mcp/server/app.py +284 -0
- stig_mcp-0.1.0/stig_mcp/server/readiness.py +115 -0
- stig_mcp-0.1.0/stig_mcp/server/tools.py +848 -0
- stig_mcp-0.1.0/stig_mcp.egg-info/PKG-INFO +215 -0
- stig_mcp-0.1.0/stig_mcp.egg-info/SOURCES.txt +49 -0
- stig_mcp-0.1.0/stig_mcp.egg-info/dependency_links.txt +1 -0
- stig_mcp-0.1.0/stig_mcp.egg-info/entry_points.txt +6 -0
- stig_mcp-0.1.0/stig_mcp.egg-info/requires.txt +3 -0
- stig_mcp-0.1.0/stig_mcp.egg-info/top_level.txt +1 -0
stig_mcp-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Eric Miller
|
|
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.
|
stig_mcp-0.1.0/NOTICE
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
Third-party notices for stig-mcp
|
|
2
|
+
=================================
|
|
3
|
+
|
|
4
|
+
This knowledge base aggregates content from five upstream sources. This file
|
|
5
|
+
records the attribution and licensing obligations that travel with it. Any
|
|
6
|
+
distributed copy of a built knowledge base must carry this notice and the license
|
|
7
|
+
texts under licenses/ with it.
|
|
8
|
+
|
|
9
|
+
MITRE ATT&CK®
|
|
10
|
+
-------------
|
|
11
|
+
|
|
12
|
+
Technique names, descriptions, and ids ingested from the MITRE ATT&CK®
|
|
13
|
+
Enterprise STIX bundle (`enterprise-attack.json`) originate with MITRE and
|
|
14
|
+
carry the following statement, embedded in that bundle by MITRE:
|
|
15
|
+
|
|
16
|
+
Copyright 2015-2026, The MITRE Corporation. MITRE ATT&CK and ATT&CK are
|
|
17
|
+
registered trademarks of The MITRE Corporation.
|
|
18
|
+
|
|
19
|
+
MITRE's ATT&CK Terms of Use grants a license to use ATT&CK and authorizes
|
|
20
|
+
copies made for those purposes, on the condition that both the copyright
|
|
21
|
+
designation and the license paragraph below travel with each copy. Both are
|
|
22
|
+
quoted verbatim from the LICENSE section of
|
|
23
|
+
https://attack.mitre.org/resources/legal-and-branding/terms-of-use/,
|
|
24
|
+
captured 2026-08-08 (the year in the designation reflects that capture date,
|
|
25
|
+
not a fixed value):
|
|
26
|
+
|
|
27
|
+
The MITRE Corporation (MITRE) hereby grants you a non-exclusive,
|
|
28
|
+
royalty-free license to use ATT&CK® for research, development, and
|
|
29
|
+
commercial purposes. Any copy you make for such purposes is authorized
|
|
30
|
+
provided that you reproduce MITRE's copyright designation and this
|
|
31
|
+
license in any such copy.
|
|
32
|
+
|
|
33
|
+
© 2026 The MITRE Corporation. This work is reproduced and distributed
|
|
34
|
+
with the permission of The MITRE Corporation.
|
|
35
|
+
|
|
36
|
+
stig-mcp is not affiliated with, sponsored by, or endorsed by MITRE.
|
|
37
|
+
|
|
38
|
+
Center for Threat-Informed Defense (CTID) mappings
|
|
39
|
+
---------------------------------------------------
|
|
40
|
+
|
|
41
|
+
The ATT&CK-to-NIST 800-53r5 mapping data ingested from CTID's
|
|
42
|
+
`mappings-explorer` project (`ctid_mappings.json`) is licensed under the
|
|
43
|
+
Apache License, Version 2.0. The full license text is included at
|
|
44
|
+
licenses/apache-2.0.txt. The project carries this notice:
|
|
45
|
+
|
|
46
|
+
© 2024 MITRE. Approved for public release. Document number(s) CT0104.
|
|
47
|
+
|
|
48
|
+
Each mapping record also names the ATT&CK technique it maps, and those names
|
|
49
|
+
fall under the ATT&CK terms above. stig-mcp transforms and subsets this data
|
|
50
|
+
into its knowledge base.
|
|
51
|
+
|
|
52
|
+
DISA STIG content
|
|
53
|
+
-----------------
|
|
54
|
+
|
|
55
|
+
STIG rule metadata, check text, and fix text are ingested from the unclassified
|
|
56
|
+
(`U_`) SRG-STIG Library Compilation, the Rev 4 SRG-STIG Sunset Compilation, and
|
|
57
|
+
individual STIG archives published by the Defense Information Systems Agency
|
|
58
|
+
(DISA) on DoD Cyber Exchange. The
|
|
59
|
+
compilation's readme (SRG-STIG Library Compilation Readme, V2R1, 06 August
|
|
60
|
+
2024) describes the `U_` compilation as containing "only publicly releasable
|
|
61
|
+
STIGs and related content for download by the general public", and states:
|
|
62
|
+
|
|
63
|
+
The compilations may be used and distributed in the same manner as
|
|
64
|
+
individually downloaded documents.
|
|
65
|
+
|
|
66
|
+
Cyber Exchange's Privacy & Security page
|
|
67
|
+
(https://www.cyber.mil/privacy-security/, captured 2026-09-26; archived copy at
|
|
68
|
+
https://web.archive.org/web/20250118065122/https://public.cyber.mil/privacy-security/)
|
|
69
|
+
states: "Information presented on Cyber Exchange is considered public
|
|
70
|
+
information and may be distributed or copied. Use of appropriate
|
|
71
|
+
byline/photo/image credits is requested."
|
|
72
|
+
|
|
73
|
+
Credit: STIG content courtesy of the Defense Information Systems Agency (DISA),
|
|
74
|
+
DoD Cyber Exchange, https://www.cyber.mil/stigs/.
|
|
75
|
+
|
|
76
|
+
Many STIGs are developed jointly by a product vendor and DISA, as the overview
|
|
77
|
+
document of each such STIG states. Text written by DISA is a work of the United
|
|
78
|
+
States Government and is not subject to copyright protection in the United
|
|
79
|
+
States; this notice makes no such claim for vendor-contributed text, whose
|
|
80
|
+
distribution rests on DISA's release statements above. stig-mcp-fetch refuses
|
|
81
|
+
controlled (`CUI_`) content, and stig-mcp-ingest and stig-mcp-extract refuse
|
|
82
|
+
any source file or archive member with a `CUI_` path component; an operator
|
|
83
|
+
who places sources by hand remains responsible for content that is controlled
|
|
84
|
+
but not so named.
|
|
85
|
+
|
|
86
|
+
DISA CCI list
|
|
87
|
+
-------------
|
|
88
|
+
|
|
89
|
+
The Control Correlation Identifier list is published by DISA on Cyber Exchange
|
|
90
|
+
as the public download `U_CCI_List.zip`, from which stig-mcp-fetch extracts
|
|
91
|
+
`U_CCI_List.xml`. The Privacy & Security statement quoted above applies to it.
|
|
92
|
+
|
|
93
|
+
NIST SP 800-53 Revision 5 control catalog
|
|
94
|
+
------------------------------------------
|
|
95
|
+
|
|
96
|
+
The NIST SP 800-53 Revision 5 OSCAL control catalog
|
|
97
|
+
(`nist_800_53_rev5_catalog.json`) is a work of the United States Government and
|
|
98
|
+
is in the public domain within the United States. NIST additionally waives
|
|
99
|
+
copyright and related rights in the work worldwide through the CC0 1.0
|
|
100
|
+
Universal public domain dedication
|
|
101
|
+
(https://creativecommons.org/publicdomain/zero/1.0/), per
|
|
102
|
+
https://github.com/usnistgov/oscal-content/blob/main/LICENSE.md.
|
stig_mcp-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: stig-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server mapping MITRE ATT&CK® -> NIST 800-53r5 -> DISA STIG fix/check steps
|
|
5
|
+
Author: Eric Miller
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Source, https://github.com/jeneric/STIG-MCP
|
|
8
|
+
Project-URL: Issues, https://github.com/jeneric/STIG-MCP/issues
|
|
9
|
+
Project-URL: Security, https://github.com/jeneric/STIG-MCP/security/policy
|
|
10
|
+
Requires-Python: >=3.11
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: NOTICE
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
License-File: licenses/apache-2.0.txt
|
|
15
|
+
Requires-Dist: defusedxml>=0.7.1
|
|
16
|
+
Requires-Dist: mcp<3,>=2.2
|
|
17
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# stig-mcp
|
|
21
|
+
|
|
22
|
+
Local MCP server that maps MITRE ATT&CK® techniques (and actors) to the NIST
|
|
23
|
+
800-53r5 controls that mitigate them, with the DISA STIG fix and check steps for
|
|
24
|
+
the systems under consideration, severity-ordered.
|
|
25
|
+
|
|
26
|
+
<!-- mcp-name: io.github.jeneric/stig-mcp -->
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
This project uses [UV](https://docs.astral.sh/uv/). Install dependencies with:
|
|
31
|
+
|
|
32
|
+
uv sync
|
|
33
|
+
|
|
34
|
+
## Quickstart
|
|
35
|
+
|
|
36
|
+
1. `uv sync`: install dependencies, then wire the server into a client (see "Run the
|
|
37
|
+
server" below) and start it.
|
|
38
|
+
2. Ask the agent to install the knowledge base. It calls the `install_knowledge_base`
|
|
39
|
+
tool, which downloads the newest published release from this project's GitHub releases
|
|
40
|
+
and verifies its SHA-256 before installing it. From a terminal the same is
|
|
41
|
+
`uv run stig-mcp-install-kb`. A host that cannot reach GitHub installs from a file; see
|
|
42
|
+
[docs/operations.md](https://github.com/jeneric/STIG-MCP/blob/main/docs/operations.md), "Install a prebuilt knowledge base". Until the
|
|
43
|
+
first knowledge-base release is published, the install says so and names the build
|
|
44
|
+
commands in the next step.
|
|
45
|
+
3. Or build it yourself: `uv run stig-mcp-fetch` downloads ATT&CK, the CTID mapping, the
|
|
46
|
+
800-53 catalog, and DISA's STIG content. **This transfers roughly a gigabyte** and
|
|
47
|
+
refuses to start with less than 2 GiB free. Then `uv run stig-mcp-ingest` builds the
|
|
48
|
+
knowledge base.
|
|
49
|
+
|
|
50
|
+
On a host that cannot reach `dl.dod.cyber.mil`, place the artifacts in the sources
|
|
51
|
+
directory yourself and go straight to `stig-mcp-ingest`. That is a first-class path rather
|
|
52
|
+
than a fallback: the ingest reads a directory and never consults the fetch. See
|
|
53
|
+
[docs/operations.md](https://github.com/jeneric/STIG-MCP/blob/main/docs/operations.md), "Placing the sources by hand".
|
|
54
|
+
|
|
55
|
+
Afterwards, `uv run stig-mcp-fetch --check` reports what MITRE ATT&CK, CTID, NIST and DISA
|
|
56
|
+
have published since, exiting 10 when there is something to take and 3 when a source could not
|
|
57
|
+
be reached, and `--refresh` takes it.
|
|
58
|
+
Neither rebuilds the knowledge base; see "Keeping current" in the same document.
|
|
59
|
+
|
|
60
|
+
## Run the server
|
|
61
|
+
|
|
62
|
+
uv run stig-mcp
|
|
63
|
+
|
|
64
|
+
This is a stdio MCP server: it speaks JSON-RPC on stdin/stdout and logs to stderr,
|
|
65
|
+
so it is launched by an MCP client rather than run standalone.
|
|
66
|
+
|
|
67
|
+
It starts whether or not the knowledge base exists, and it never answers from one it
|
|
68
|
+
cannot trust. Called before the knowledge base is installed, or against one an older release
|
|
69
|
+
wrote, every tool returns a `not_ready` payload instead of an answer: the reason, which
|
|
70
|
+
source files it can and cannot see, the sources directory it looked in, and the next steps,
|
|
71
|
+
led by the `install_knowledge_base` tool and followed by the commands to run, each in both its
|
|
72
|
+
console-script and `python -m` form. That is deliberate, so an agent can read the remedy from
|
|
73
|
+
the tool result rather than the operator having to find a log pane. Install or rebuild the
|
|
74
|
+
knowledge base and the running server picks it up without a restart.
|
|
75
|
+
|
|
76
|
+
The `check_sources` tool tells an agent whether a newer knowledge base is published. It and
|
|
77
|
+
`install_knowledge_base` are the only two tools that contact the network, and they reach
|
|
78
|
+
only this project's GitHub releases.
|
|
79
|
+
|
|
80
|
+
### GitHub Copilot in VS Code
|
|
81
|
+
|
|
82
|
+
Create `.vscode/mcp.json` in this repository (git-ignored, so it stays local):
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"servers": {
|
|
87
|
+
"stig-mcp": {
|
|
88
|
+
"type": "stdio",
|
|
89
|
+
"command": "uv",
|
|
90
|
+
"args": ["run", "stig-mcp"],
|
|
91
|
+
"cwd": "${workspaceFolder}"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Then:
|
|
98
|
+
|
|
99
|
+
1. Open Copilot Chat and set the mode dropdown to **Agent**. MCP tools are not
|
|
100
|
+
available in Ask or Edit mode.
|
|
101
|
+
2. Command Palette (`Ctrl+Shift+P`, or `Cmd+Shift+P` on macOS) and run
|
|
102
|
+
**MCP: List Servers**, select `stig-mcp`, then **Start**. Trust the server when
|
|
103
|
+
prompted, since it runs a local command.
|
|
104
|
+
3. Click **Configure Tools** in the chat input to confirm the eight tools are listed
|
|
105
|
+
and enabled.
|
|
106
|
+
4. Reference a tool explicitly to verify the wiring, rather than hoping the model
|
|
107
|
+
picks it up on its own. See [docs/user-guide.md](https://github.com/jeneric/STIG-MCP/blob/main/docs/user-guide.md)'s "Getting the
|
|
108
|
+
LLM to use the server" for a prompt shape that reliably does this.
|
|
109
|
+
|
|
110
|
+
Copilot saves a tool answer over 8 KB to a temporary file and reads it back, so with
|
|
111
|
+
manual permissions it asks to read a file named like `…copilot-tool-output-….txt`
|
|
112
|
+
outside the workspace. That file is this server's answer; allow it.
|
|
113
|
+
|
|
114
|
+
To debug, run **MCP: List Servers**, select the server, and choose **Show Output**.
|
|
115
|
+
The two common failures are that `uv` is not on the `PATH` VS Code inherited, which
|
|
116
|
+
looks like a broken server but is a missing command, and an absent knowledge base.
|
|
117
|
+
For the first, use uv's absolute path (`which uv`) as `command`. For the second, see
|
|
118
|
+
[docs/operations.md](https://github.com/jeneric/STIG-MCP/blob/main/docs/operations.md).
|
|
119
|
+
|
|
120
|
+
### Other clients
|
|
121
|
+
|
|
122
|
+
Any MCP client that launches a stdio server works. `uv run` locates the project from
|
|
123
|
+
the working directory, so a client that starts elsewhere needs `--directory`, which
|
|
124
|
+
makes the command independent of where it is launched:
|
|
125
|
+
|
|
126
|
+
uv run --directory /path/to/STIG-MCP stig-mcp
|
|
127
|
+
|
|
128
|
+
For Claude Code, from the repository root:
|
|
129
|
+
|
|
130
|
+
claude mcp add stig-mcp -- uv run stig-mcp
|
|
131
|
+
|
|
132
|
+
By default the knowledge base is not found relative to the working directory, so only `uv`
|
|
133
|
+
cares where the client starts the server. Where it *is* found depends on whether this is a
|
|
134
|
+
checkout or an installed copy. (A relative `STIG_MCP_DATA` does resolve against the working
|
|
135
|
+
directory, so give it an absolute path if the client's is not yours.)
|
|
136
|
+
|
|
137
|
+
### Where the data lives
|
|
138
|
+
|
|
139
|
+
Two environment variables override the defaults, and the defaults differ between a source
|
|
140
|
+
checkout and an installed copy:
|
|
141
|
+
|
|
142
|
+
| | source checkout | installed, POSIX and macOS | installed, Windows |
|
|
143
|
+
|---|---|---|---|
|
|
144
|
+
| data directory (`STIG_MCP_DATA`) | `stig_mcp/data/` | `$XDG_DATA_HOME/stig-mcp`, else `~/.local/share/stig-mcp` | `$XDG_DATA_HOME/stig-mcp`, else `%LOCALAPPDATA%\stig-mcp`, else `~\.local\share\stig-mcp` |
|
|
145
|
+
| mapping overrides (`STIG_MCP_OVERRIDES`) | `overrides.yaml` at the repository root | `$XDG_CONFIG_HOME/stig-mcp/overrides.yaml`, else `~/.config/stig-mcp/overrides.yaml` | `$XDG_CONFIG_HOME/stig-mcp/overrides.yaml`, else `%LOCALAPPDATA%\stig-mcp\overrides.yaml`, else `~\.config\stig-mcp\overrides.yaml` |
|
|
146
|
+
|
|
147
|
+
A checkout is a directory holding both the package and the `pyproject.toml` that declares
|
|
148
|
+
it, so an editable install counts as one. XDG is used on POSIX, including macOS. On Windows
|
|
149
|
+
with the XDG variables unset, the default is `%LOCALAPPDATA%`, because a roaming profile
|
|
150
|
+
copies `~/.local/share` at every logon and logoff, and this project's downloads can run to a
|
|
151
|
+
gigabyte; when
|
|
152
|
+
`%LOCALAPPDATA%` is set this puts the mapping overrides file inside the data directory rather
|
|
153
|
+
than beside it, since Windows has one such variable rather than XDG's separate data and config
|
|
154
|
+
locations. (With `%LOCALAPPDATA%` unset, Windows falls back to the same separate `~/.config`
|
|
155
|
+
and `~/.local/share` trees POSIX uses, so the two stay apart in that case, same as the table
|
|
156
|
+
above shows.)
|
|
157
|
+
|
|
158
|
+
**The XDG variables are read first on every platform, Windows included**, as the table's
|
|
159
|
+
Windows column shows: a Windows host with `XDG_DATA_HOME` set uses it and never reaches
|
|
160
|
+
`%LOCALAPPDATA%`, so the roaming argument above holds only where that variable is unset. The
|
|
161
|
+
order is kept so that an existing install's data directory never moves under it.
|
|
162
|
+
`STIG_MCP_DATA` and `STIG_MCP_OVERRIDES` outrank everything above and are the escape hatch
|
|
163
|
+
everywhere, for a native location or any other.
|
|
164
|
+
|
|
165
|
+
`stig-mcp-ingest` creates the data directory if it does not exist. It refuses to run when
|
|
166
|
+
`STIG_MCP_OVERRIDES` names a file that is not there, rather than silently applying no
|
|
167
|
+
overrides; a missing file at the default location is fine, because that file is optional.
|
|
168
|
+
|
|
169
|
+
## What this server fetches
|
|
170
|
+
|
|
171
|
+
- The MCP server contacts nothing unless `check_sources` or `install_knowledge_base` is
|
|
172
|
+
called. Then it sends HTTPS GET requests to `api.github.com` (this repository's release
|
|
173
|
+
listing) and `github.com` (`/jeneric/STIG-MCP/releases/download/...`), which redirects to
|
|
174
|
+
`release-assets.githubusercontent.com` or `objects.githubusercontent.com`. Any other URL, a
|
|
175
|
+
redirect included, is refused. Nothing is uploaded, and there is no telemetry.
|
|
176
|
+
`install_knowledge_base` given a file path and its SHA-256 requests nothing at all.
|
|
177
|
+
- `stig-mcp-install-kb` contacts the same hosts, and nothing at all with `--file`.
|
|
178
|
+
- `stig-mcp-fetch`, used only to build the knowledge base yourself, downloads from
|
|
179
|
+
`raw.githubusercontent.com` and `api.github.com` (MITRE ATT&CK, the CTID mapping, the NIST
|
|
180
|
+
800-53 catalog) and from `dl.dod.cyber.mil` (DISA).
|
|
181
|
+
|
|
182
|
+
[PRIVACY.md](https://github.com/jeneric/STIG-MCP/blob/main/PRIVACY.md) states what each of these requests sends and what is stored locally.
|
|
183
|
+
|
|
184
|
+
## Example prompts
|
|
185
|
+
|
|
186
|
+
With the knowledge base installed and the server wired into an agent, these are answered
|
|
187
|
+
from it:
|
|
188
|
+
|
|
189
|
+
1. `What DISA STIG steps mitigate T1078 on Windows 11?`
|
|
190
|
+
2. `Which ATT&CK techniques does APT29 use?`
|
|
191
|
+
3. `Which STIG benchmarks apply to RHEL 9?`
|
|
192
|
+
|
|
193
|
+
## Documentation
|
|
194
|
+
|
|
195
|
+
- [docs/operations.md](https://github.com/jeneric/STIG-MCP/blob/main/docs/operations.md): for whoever installs, builds and maintains the knowledge base.
|
|
196
|
+
- [docs/user-guide.md](https://github.com/jeneric/STIG-MCP/blob/main/docs/user-guide.md): for a person talking to an LLM that has this server wired in.
|
|
197
|
+
- [SECURITY.md](https://github.com/jeneric/STIG-MCP/blob/main/SECURITY.md): reporting a vulnerability, and what is in scope.
|
|
198
|
+
- [RELEASING.md](https://github.com/jeneric/STIG-MCP/blob/main/RELEASING.md): for the maintainer, publishing the package to PyPI and the MCP Registry.
|
|
199
|
+
- [PRIVACY.md](https://github.com/jeneric/STIG-MCP/blob/main/PRIVACY.md): what the server and the fetch tool contact, and what is stored locally.
|
|
200
|
+
|
|
201
|
+
## Third-party content
|
|
202
|
+
|
|
203
|
+
The knowledge base aggregates MITRE ATT&CK, CTID mapping, DISA STIG, DISA CCI
|
|
204
|
+
list, and NIST OSCAL content. See [NOTICE](https://github.com/jeneric/STIG-MCP/blob/main/NOTICE) for attribution and licensing obligations
|
|
205
|
+
and [licenses/apache-2.0.txt](https://github.com/jeneric/STIG-MCP/blob/main/licenses/apache-2.0.txt) for the Apache 2.0
|
|
206
|
+
license text that notice requires.
|
|
207
|
+
|
|
208
|
+
## Development
|
|
209
|
+
|
|
210
|
+
Developed with the assistance of Claude Code (Anthropic). All changes were reviewed and
|
|
211
|
+
tested by the maintainer.
|
|
212
|
+
|
|
213
|
+
## Tests
|
|
214
|
+
|
|
215
|
+
uv run pytest
|
stig_mcp-0.1.0/README.md
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# stig-mcp
|
|
2
|
+
|
|
3
|
+
Local MCP server that maps MITRE ATT&CK® techniques (and actors) to the NIST
|
|
4
|
+
800-53r5 controls that mitigate them, with the DISA STIG fix and check steps for
|
|
5
|
+
the systems under consideration, severity-ordered.
|
|
6
|
+
|
|
7
|
+
<!-- mcp-name: io.github.jeneric/stig-mcp -->
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
This project uses [UV](https://docs.astral.sh/uv/). Install dependencies with:
|
|
12
|
+
|
|
13
|
+
uv sync
|
|
14
|
+
|
|
15
|
+
## Quickstart
|
|
16
|
+
|
|
17
|
+
1. `uv sync`: install dependencies, then wire the server into a client (see "Run the
|
|
18
|
+
server" below) and start it.
|
|
19
|
+
2. Ask the agent to install the knowledge base. It calls the `install_knowledge_base`
|
|
20
|
+
tool, which downloads the newest published release from this project's GitHub releases
|
|
21
|
+
and verifies its SHA-256 before installing it. From a terminal the same is
|
|
22
|
+
`uv run stig-mcp-install-kb`. A host that cannot reach GitHub installs from a file; see
|
|
23
|
+
[docs/operations.md](https://github.com/jeneric/STIG-MCP/blob/main/docs/operations.md), "Install a prebuilt knowledge base". Until the
|
|
24
|
+
first knowledge-base release is published, the install says so and names the build
|
|
25
|
+
commands in the next step.
|
|
26
|
+
3. Or build it yourself: `uv run stig-mcp-fetch` downloads ATT&CK, the CTID mapping, the
|
|
27
|
+
800-53 catalog, and DISA's STIG content. **This transfers roughly a gigabyte** and
|
|
28
|
+
refuses to start with less than 2 GiB free. Then `uv run stig-mcp-ingest` builds the
|
|
29
|
+
knowledge base.
|
|
30
|
+
|
|
31
|
+
On a host that cannot reach `dl.dod.cyber.mil`, place the artifacts in the sources
|
|
32
|
+
directory yourself and go straight to `stig-mcp-ingest`. That is a first-class path rather
|
|
33
|
+
than a fallback: the ingest reads a directory and never consults the fetch. See
|
|
34
|
+
[docs/operations.md](https://github.com/jeneric/STIG-MCP/blob/main/docs/operations.md), "Placing the sources by hand".
|
|
35
|
+
|
|
36
|
+
Afterwards, `uv run stig-mcp-fetch --check` reports what MITRE ATT&CK, CTID, NIST and DISA
|
|
37
|
+
have published since, exiting 10 when there is something to take and 3 when a source could not
|
|
38
|
+
be reached, and `--refresh` takes it.
|
|
39
|
+
Neither rebuilds the knowledge base; see "Keeping current" in the same document.
|
|
40
|
+
|
|
41
|
+
## Run the server
|
|
42
|
+
|
|
43
|
+
uv run stig-mcp
|
|
44
|
+
|
|
45
|
+
This is a stdio MCP server: it speaks JSON-RPC on stdin/stdout and logs to stderr,
|
|
46
|
+
so it is launched by an MCP client rather than run standalone.
|
|
47
|
+
|
|
48
|
+
It starts whether or not the knowledge base exists, and it never answers from one it
|
|
49
|
+
cannot trust. Called before the knowledge base is installed, or against one an older release
|
|
50
|
+
wrote, every tool returns a `not_ready` payload instead of an answer: the reason, which
|
|
51
|
+
source files it can and cannot see, the sources directory it looked in, and the next steps,
|
|
52
|
+
led by the `install_knowledge_base` tool and followed by the commands to run, each in both its
|
|
53
|
+
console-script and `python -m` form. That is deliberate, so an agent can read the remedy from
|
|
54
|
+
the tool result rather than the operator having to find a log pane. Install or rebuild the
|
|
55
|
+
knowledge base and the running server picks it up without a restart.
|
|
56
|
+
|
|
57
|
+
The `check_sources` tool tells an agent whether a newer knowledge base is published. It and
|
|
58
|
+
`install_knowledge_base` are the only two tools that contact the network, and they reach
|
|
59
|
+
only this project's GitHub releases.
|
|
60
|
+
|
|
61
|
+
### GitHub Copilot in VS Code
|
|
62
|
+
|
|
63
|
+
Create `.vscode/mcp.json` in this repository (git-ignored, so it stays local):
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"servers": {
|
|
68
|
+
"stig-mcp": {
|
|
69
|
+
"type": "stdio",
|
|
70
|
+
"command": "uv",
|
|
71
|
+
"args": ["run", "stig-mcp"],
|
|
72
|
+
"cwd": "${workspaceFolder}"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Then:
|
|
79
|
+
|
|
80
|
+
1. Open Copilot Chat and set the mode dropdown to **Agent**. MCP tools are not
|
|
81
|
+
available in Ask or Edit mode.
|
|
82
|
+
2. Command Palette (`Ctrl+Shift+P`, or `Cmd+Shift+P` on macOS) and run
|
|
83
|
+
**MCP: List Servers**, select `stig-mcp`, then **Start**. Trust the server when
|
|
84
|
+
prompted, since it runs a local command.
|
|
85
|
+
3. Click **Configure Tools** in the chat input to confirm the eight tools are listed
|
|
86
|
+
and enabled.
|
|
87
|
+
4. Reference a tool explicitly to verify the wiring, rather than hoping the model
|
|
88
|
+
picks it up on its own. See [docs/user-guide.md](https://github.com/jeneric/STIG-MCP/blob/main/docs/user-guide.md)'s "Getting the
|
|
89
|
+
LLM to use the server" for a prompt shape that reliably does this.
|
|
90
|
+
|
|
91
|
+
Copilot saves a tool answer over 8 KB to a temporary file and reads it back, so with
|
|
92
|
+
manual permissions it asks to read a file named like `…copilot-tool-output-….txt`
|
|
93
|
+
outside the workspace. That file is this server's answer; allow it.
|
|
94
|
+
|
|
95
|
+
To debug, run **MCP: List Servers**, select the server, and choose **Show Output**.
|
|
96
|
+
The two common failures are that `uv` is not on the `PATH` VS Code inherited, which
|
|
97
|
+
looks like a broken server but is a missing command, and an absent knowledge base.
|
|
98
|
+
For the first, use uv's absolute path (`which uv`) as `command`. For the second, see
|
|
99
|
+
[docs/operations.md](https://github.com/jeneric/STIG-MCP/blob/main/docs/operations.md).
|
|
100
|
+
|
|
101
|
+
### Other clients
|
|
102
|
+
|
|
103
|
+
Any MCP client that launches a stdio server works. `uv run` locates the project from
|
|
104
|
+
the working directory, so a client that starts elsewhere needs `--directory`, which
|
|
105
|
+
makes the command independent of where it is launched:
|
|
106
|
+
|
|
107
|
+
uv run --directory /path/to/STIG-MCP stig-mcp
|
|
108
|
+
|
|
109
|
+
For Claude Code, from the repository root:
|
|
110
|
+
|
|
111
|
+
claude mcp add stig-mcp -- uv run stig-mcp
|
|
112
|
+
|
|
113
|
+
By default the knowledge base is not found relative to the working directory, so only `uv`
|
|
114
|
+
cares where the client starts the server. Where it *is* found depends on whether this is a
|
|
115
|
+
checkout or an installed copy. (A relative `STIG_MCP_DATA` does resolve against the working
|
|
116
|
+
directory, so give it an absolute path if the client's is not yours.)
|
|
117
|
+
|
|
118
|
+
### Where the data lives
|
|
119
|
+
|
|
120
|
+
Two environment variables override the defaults, and the defaults differ between a source
|
|
121
|
+
checkout and an installed copy:
|
|
122
|
+
|
|
123
|
+
| | source checkout | installed, POSIX and macOS | installed, Windows |
|
|
124
|
+
|---|---|---|---|
|
|
125
|
+
| data directory (`STIG_MCP_DATA`) | `stig_mcp/data/` | `$XDG_DATA_HOME/stig-mcp`, else `~/.local/share/stig-mcp` | `$XDG_DATA_HOME/stig-mcp`, else `%LOCALAPPDATA%\stig-mcp`, else `~\.local\share\stig-mcp` |
|
|
126
|
+
| mapping overrides (`STIG_MCP_OVERRIDES`) | `overrides.yaml` at the repository root | `$XDG_CONFIG_HOME/stig-mcp/overrides.yaml`, else `~/.config/stig-mcp/overrides.yaml` | `$XDG_CONFIG_HOME/stig-mcp/overrides.yaml`, else `%LOCALAPPDATA%\stig-mcp\overrides.yaml`, else `~\.config\stig-mcp\overrides.yaml` |
|
|
127
|
+
|
|
128
|
+
A checkout is a directory holding both the package and the `pyproject.toml` that declares
|
|
129
|
+
it, so an editable install counts as one. XDG is used on POSIX, including macOS. On Windows
|
|
130
|
+
with the XDG variables unset, the default is `%LOCALAPPDATA%`, because a roaming profile
|
|
131
|
+
copies `~/.local/share` at every logon and logoff, and this project's downloads can run to a
|
|
132
|
+
gigabyte; when
|
|
133
|
+
`%LOCALAPPDATA%` is set this puts the mapping overrides file inside the data directory rather
|
|
134
|
+
than beside it, since Windows has one such variable rather than XDG's separate data and config
|
|
135
|
+
locations. (With `%LOCALAPPDATA%` unset, Windows falls back to the same separate `~/.config`
|
|
136
|
+
and `~/.local/share` trees POSIX uses, so the two stay apart in that case, same as the table
|
|
137
|
+
above shows.)
|
|
138
|
+
|
|
139
|
+
**The XDG variables are read first on every platform, Windows included**, as the table's
|
|
140
|
+
Windows column shows: a Windows host with `XDG_DATA_HOME` set uses it and never reaches
|
|
141
|
+
`%LOCALAPPDATA%`, so the roaming argument above holds only where that variable is unset. The
|
|
142
|
+
order is kept so that an existing install's data directory never moves under it.
|
|
143
|
+
`STIG_MCP_DATA` and `STIG_MCP_OVERRIDES` outrank everything above and are the escape hatch
|
|
144
|
+
everywhere, for a native location or any other.
|
|
145
|
+
|
|
146
|
+
`stig-mcp-ingest` creates the data directory if it does not exist. It refuses to run when
|
|
147
|
+
`STIG_MCP_OVERRIDES` names a file that is not there, rather than silently applying no
|
|
148
|
+
overrides; a missing file at the default location is fine, because that file is optional.
|
|
149
|
+
|
|
150
|
+
## What this server fetches
|
|
151
|
+
|
|
152
|
+
- The MCP server contacts nothing unless `check_sources` or `install_knowledge_base` is
|
|
153
|
+
called. Then it sends HTTPS GET requests to `api.github.com` (this repository's release
|
|
154
|
+
listing) and `github.com` (`/jeneric/STIG-MCP/releases/download/...`), which redirects to
|
|
155
|
+
`release-assets.githubusercontent.com` or `objects.githubusercontent.com`. Any other URL, a
|
|
156
|
+
redirect included, is refused. Nothing is uploaded, and there is no telemetry.
|
|
157
|
+
`install_knowledge_base` given a file path and its SHA-256 requests nothing at all.
|
|
158
|
+
- `stig-mcp-install-kb` contacts the same hosts, and nothing at all with `--file`.
|
|
159
|
+
- `stig-mcp-fetch`, used only to build the knowledge base yourself, downloads from
|
|
160
|
+
`raw.githubusercontent.com` and `api.github.com` (MITRE ATT&CK, the CTID mapping, the NIST
|
|
161
|
+
800-53 catalog) and from `dl.dod.cyber.mil` (DISA).
|
|
162
|
+
|
|
163
|
+
[PRIVACY.md](https://github.com/jeneric/STIG-MCP/blob/main/PRIVACY.md) states what each of these requests sends and what is stored locally.
|
|
164
|
+
|
|
165
|
+
## Example prompts
|
|
166
|
+
|
|
167
|
+
With the knowledge base installed and the server wired into an agent, these are answered
|
|
168
|
+
from it:
|
|
169
|
+
|
|
170
|
+
1. `What DISA STIG steps mitigate T1078 on Windows 11?`
|
|
171
|
+
2. `Which ATT&CK techniques does APT29 use?`
|
|
172
|
+
3. `Which STIG benchmarks apply to RHEL 9?`
|
|
173
|
+
|
|
174
|
+
## Documentation
|
|
175
|
+
|
|
176
|
+
- [docs/operations.md](https://github.com/jeneric/STIG-MCP/blob/main/docs/operations.md): for whoever installs, builds and maintains the knowledge base.
|
|
177
|
+
- [docs/user-guide.md](https://github.com/jeneric/STIG-MCP/blob/main/docs/user-guide.md): for a person talking to an LLM that has this server wired in.
|
|
178
|
+
- [SECURITY.md](https://github.com/jeneric/STIG-MCP/blob/main/SECURITY.md): reporting a vulnerability, and what is in scope.
|
|
179
|
+
- [RELEASING.md](https://github.com/jeneric/STIG-MCP/blob/main/RELEASING.md): for the maintainer, publishing the package to PyPI and the MCP Registry.
|
|
180
|
+
- [PRIVACY.md](https://github.com/jeneric/STIG-MCP/blob/main/PRIVACY.md): what the server and the fetch tool contact, and what is stored locally.
|
|
181
|
+
|
|
182
|
+
## Third-party content
|
|
183
|
+
|
|
184
|
+
The knowledge base aggregates MITRE ATT&CK, CTID mapping, DISA STIG, DISA CCI
|
|
185
|
+
list, and NIST OSCAL content. See [NOTICE](https://github.com/jeneric/STIG-MCP/blob/main/NOTICE) for attribution and licensing obligations
|
|
186
|
+
and [licenses/apache-2.0.txt](https://github.com/jeneric/STIG-MCP/blob/main/licenses/apache-2.0.txt) for the Apache 2.0
|
|
187
|
+
license text that notice requires.
|
|
188
|
+
|
|
189
|
+
## Development
|
|
190
|
+
|
|
191
|
+
Developed with the assistance of Claude Code (Anthropic). All changes were reviewed and
|
|
192
|
+
tested by the maintainer.
|
|
193
|
+
|
|
194
|
+
## Tests
|
|
195
|
+
|
|
196
|
+
uv run pytest
|