threatkb
README.md
# threatkb
threatkb answers questions about the MITRE ATT&CK knowledge base
from a dataset file you keep on your own machine: look a technique
up by its ATT&CK id or by an approximate name, pull the full record
for a technique (platforms, kill-chain phases, references,
sub-techniques, mitigations, detections), list the mitigations or
detections tied to a technique, and list the tactics the dataset
knows about. One binary serves a command-line interface and a
stdio MCP server.
There is no bundled dataset and no network service behind this
tool. You point it at a STIX bundle in the
`enterprise-attack.json` shape (the layout MITRE publishes for the
enterprise matrix) with the `THREATKB_DATA_FILE` environment
variable. When the variable is unset or the file cannot be read,
the query commands fail with an error naming the missing dataset
instead of guessing — threatkb never invents ATT&CK data.
`threatkb info` still answers in that state and reports
`dataset_loaded: false` with the reason.
## Install
```bash
THREATKB_DATA_FILE=/path/to/enterprise-attack.json npx @reneturcios/threatkb tactics
```
Or run the container image:
```bash
docker run -i -e THREATKB_DATA_FILE=/data/enterprise-attack.json \
-v /path/to/data:/data ghcr.io/cloudcorprecords/threatkb
```
The container defaults to the MCP server (see below). Pass CLI
arguments to use it as a CLI instead.
## CLI
```bash
export THREATKB_DATA_FILE=/path/to/enterprise-attack.json
threatkb query --id T1059
threatkb query --name "command and scripting"
threatkb full --id T1059
threatkb full --name PowerShell
threatkb mitigations T1059
threatkb detections T1059
threatkb tactics
threatkb info
threatkb --version
```
Results print as JSON. Technique searches return
`{results: [...], count: N}`; mitigation and detection queries
return `{technique_id, results: [...], count: N}` for the one
technique asked about, and an unknown technique id is an error.
Exit codes: `0` on success, `1` when a query fails (including a
missing dataset), `2` for usage errors.
Lookup rules: an id lookup is exact and case-insensitive
(`t1059` finds `T1059`). A name lookup is fuzzy — exact name
first, then names starting with the query, then names containing
it, then names containing every word of the query.
## MCP server
One bin serves both faces. The `mcp` subcommand starts a stdio MCP
server:
```bash
npx -y @reneturcios/threatkb mcp
```
MCP client configuration:
```json
{
"mcpServers": {
"threatkb": {
"command": "npx",
"args": ["-y", "@reneturcios/threatkb", "mcp"],
"env": {
"THREATKB_DATA_FILE": "/path/to/enterprise-attack.json"
}
}
}
}
```
### Tools
| Tool | Input | What it returns |
| --- | --- | --- |
| `query_technique` | `technique_id` or `tech_name` (one required in practice) | Matching technique summaries as `{results, count}`. |
| `search_technique_full` | `technique_id` or `tech_name` | The same matches with full detail: platforms, kill-chain phases, references, sub-techniques, mitigations, detections. |
| `query_mitigations` | `technique_id` (required) | Mitigations linked to that technique. |
| `query_detections` | `technique_id` (required) | Detections linked to that technique. |
| `list_tactics` | (none) | Every tactic in the dataset as `{results, count}`. |
| `server_info` | (none) | Server name, version, dataset path, whether the dataset loaded, and object counts when it did. |
### How the STIX dataset is read
threatkb indexes a deliberately simplified slice of the STIX
model, documented here so the limits are clear:
- Techniques are `attack-pattern` objects; the ATT&CK id comes
from the `external_references` entry with source name
`mitre-attack`. Tactics come from a technique's
`kill_chain_phases` phase names.
- Tactics are `x-mitre-tactic` objects (with `x_mitre_shortname`).
- Mitigations are `course-of-action` objects linked to a
technique by a `mitigates` relationship.
- Detections are `detects` relationships pointing at the
technique; the relationship's source (usually an
`x-mitre-data-component`) is resolved, including its data
source name when linked. A technique's `x_mitre_detection`
guidance text is also returned as a detection entry.
- Sub-techniques are recognised by `x_mitre_is_subtechnique` or a
dotted id; the parent comes from a `subtechnique-of`
relationship when present, otherwise from the id prefix.
Revocation/deprecation flags, analytics, data-source coverage
scoring, and group/software attribution are out of scope.
## Development
```bash
npm install
npm run build # tsc -> dist/
npm test # node test runner over test/*.test.ts, on a hand-written STIX fixture, no real dataset needed
npm run dev # run the CLI from source via tsx
```
## License
MIT — see `LICENSE`.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues