Search and retrieve security commands, exploit scripts, and methodology from your pentest writeups and shell history. CLI + MCP server for AI assistants.
Project description
Command Vault (also MCP)
"What was that certipy command I used for ESC8?" "How did I exploit that shadow credentials thing again?"
Command Vault indexes commands, scripts, and prose from your penetration testing writeups and shell history into a searchable database with full context — what tool, what technique, which box. MCP-ready for AI assistants.
Features
- Command search — FTS across commands with AND-first, bm25-ranked OR fallback for multi-word queries
- Prose search — Search methodology text, attack explanations, and forensic analysis from writeups
- Script search & retrieval — Find exploit scripts by language/library, retrieve full code by ID
- Ranked fallback — Multi-word queries try AND (precise), then fall back to bm25-ranked OR (relevant)
- Shell history — Index
~/.zsh_historyor~/.bash_historywith deduplication and security redaction - Tag filtering — Search by
#hashtagsextracted from writeup content - Smart categorization — 200+ security tools mapped to categories (recon, AD, web, privesc, etc.)
- Template generation — Auto-replaces IPs, domains, passwords with placeholders
- Multiple writeup types — Boxes, challenges, and Sherlocks with unified or legacy directory modes
Installation
Requires Python 3.11+ and uv.
git clone https://github.com/x746b/command-vault.git
cd command-vault
uv pip install -e .
Quick Start
# Set writeup directory
export WRITEUPS="$HOME/writeups"
# Index everything
vault index --rebuild
# Search commands
vault search "kerberoasting"
vault search --tool nmap --category recon
vault search --tag windows --tag ad
# Search prose/methodology
vault prose "NTLM relay"
vault prose "ADCS ESC8" --type box
CLI Reference
Commands & Scripts
vault search "certipy ESC" # AND match (both words required)
vault search "buffer overflow ROP chain" # AND first, bm25 OR fallback if no AND hits
vault search --tool bloodyAD --limit 5 # Filter by tool
vault search --category ad # Filter by category
vault search --tag windows --tag ad # Filter by tags (AND logic)
vault search --type box "ADCS" # Filter by writeup type
vault search "ESC16" --json # JSON output
vault scripts --language python # Search scripts
vault scripts --library pwn
vault scripts --list-libraries # List all libraries with counts
vault scripts "fmtstr printf" --library pwn # Find format string exploits
vault script 147 # Get full script code by ID
vault suggest "kerberoasting" # Tool suggestions grouped by category
Retrieving Full Exploit Scripts
Search returns a preview with the script ID, then use vault script <ID> to get the full code:
$ vault scripts "fmtstr printf" --library pwn
============================================================
[ID: 147] Language: python
Libraries: pwn
Source: What does the f say (pwn).md
Preview:
from pwn import *
context.arch = 'amd64'
...
$ vault script 147
# What does the f say (pwn).md
# Language: python Libraries: pwn
from pwn import *
context.arch = 'amd64'
...
glibc_base = glibc_read - 0x110180
glibc_malloc_hook = glibc_base + 0x3ebc30
for i in range(0, 8):
b = (glibc_one_gadget >> (i * 8)) & 0xff
send_printf(fmtstr_payload(8, { glibc_malloc_hook + i: b }))
...
Same via MCP — AI calls search_scripts to find IDs, then get_script for full code:
search_scripts(query="RSA sage", library="Crypto") -> [ID: 239] 10-line preview
get_script(script_id=239) -> full 193-line Sage solver
Prose Search
Search the full text of writeup methodology, not just extracted commands:
vault prose "NTLM relay" # Search writeup prose
vault prose "ADCS ESC8" --type box # Filter by writeup type
vault prose "shadow credentials" --limit 20
vault prose "GenericWrite ADCS shadow" # AND first, ranked OR fallback
Indexing
vault index --rebuild # Full reindex (required first time)
vault index --add # Index new writeups only
vault index --add --type box # Index specific type
vault index --add /path/to/writeups # Index custom directory
Shell History
vault history index ~/.zsh_history # Index (additive, safe to re-run)
vault history index ~/.zsh_history --since "2024-01-01"
vault history search "kerberoast" # Search history
vault history search --tool certipy
vault history stats # History statistics
vault history clear --confirm # Clear all
Technique Linking
Find writeups that share the same attack technique — see all your approaches side by side:
vault techniques # List all indexed techniques
vault techniques --min-count 5 # Only techniques with 5+ writeups
vault related "RBCD" # All writeups using RBCD, with tools + tags
vault related "ADCS ESC1" # All writeups using ESC1
vault related "SQL Injection" # Works with canonical names
vault enrich # Populate technique links from tags (no re-index)
Techniques are extracted from your #hashtag tags — no prose scanning, no false positives. Tags like #RBCD, #SQLi, #ESC1 are mapped to canonical names. Run vault enrich after re-indexing to update technique links.
Other
vault tools --category ad # List tools
vault categories # List categories
vault tags --min-count 5 # List tags
vault stats # Database statistics
vault maintain --all # VACUUM + ANALYZE + FTS optimize
MCP Server Setup
claude mcp add command-vault --scope user \
-e VAULT_DB=~/.local/share/command-vault/vault.db \
-e WRITEUPS=~/writeups \
-- /path/to/command-vault/.venv/bin/python -m command_vault.server
Or in ~/.claude.json / .mcp.json:
{
"mcpServers": {
"command-vault": {
"command": "/path/to/command-vault/.venv/bin/python",
"args": ["-m", "command_vault.server"],
"env": {
"VAULT_DB": "~/.local/share/command-vault/vault.db",
"WRITEUPS": "~/writeups"
}
}
}
}
Environment Variables
| Variable | Description | Default |
|---|---|---|
VAULT_DB |
Path to SQLite database | ~/.local/share/command-vault/vault.db |
WRITEUPS |
Unified writeup directory (recommended) | None |
WRITEUPS_BOXES |
Boxes directory (legacy, path-based type detection) | None |
WRITEUPS_CHALLENGES |
Challenges directory (legacy) | None |
WRITEUPS_SHERLOCKS |
Sherlocks directory (legacy) | None |
MCP Tools
| Tool | Description |
|---|---|
search_commands |
Search commands by keyword, tool, category, or tags |
search_writeup_prose |
Search methodology text and explanations from writeups |
search_scripts |
Search exploit scripts by language or library |
get_script |
Get full script code by ID (from search_scripts results) |
get_tool_examples |
Get usage examples for a specific tool |
suggest_command |
Get command suggestions for a goal |
list_tools |
List indexed tools |
list_categories |
List categories with counts |
list_tags |
List all tags with usage counts |
get_writeup_summary |
Get summary from a specific writeup |
index_writeups |
Index or re-index writeup directories |
vault_stats |
Get statistics about indexed content |
index_history |
Index shell history file |
search_history |
Search indexed shell history |
history_stats |
Get history statistics |
clear_history |
Clear indexed history (requires confirm=true) |
search_related |
Find writeups sharing a technique (e.g., "RBCD", "ADCS ESC1") |
list_techniques |
List all indexed techniques with writeup counts |
enrich |
Populate technique links from tags (no re-indexing needed) |
Writeup Format
The parser extracts commands from fenced code blocks (bash, powershell, python) and prose from paragraph text.
Supported prompts: $, user@host$, ➜ dir, PS C:\>, *Evil-WinRM*, PV >, C:\>
Example writeup:
# Machine Name
#box #windows #ad #easy
## Enumeration
We discover LDAP signing is not enforced, making NTLM relay possible.
```bash
$ nmap -sC -sV 10.10.11.100
```
```powershell
*Evil-WinRM* PS C:\Users\admin> Get-ADUser -Filter *
```
```python
#!/usr/bin/env python3
from pwn import *
# exploit code - detected as script
```
Tags (#box, #windows, #ad, #easy) are extracted and searchable. Prose paragraphs are chunked and indexed for vault prose / search_writeup_prose searches.
Troubleshooting
- "vault: command not found" — Run via
uv run vaultfrom the project directory, or add~/.local/binto PATH afterpip install -e . - "No results found" — Check
vault stats, runvault index --rebuildif counts are 0. Multi-word queries try AND first, then fall back to bm25-ranked OR if AND returns nothing. - MCP not connecting — Verify paths in MCP config, check
uvis in PATH, test withuv run command-vault - Database errors — Run
vault maintain --all. If that fails:rm ~/.local/share/command-vault/vault.db && vault index --rebuild
License
MIT License - see LICENSE file.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file command_vault_mcp-0.8.0.tar.gz.
File metadata
- Download URL: command_vault_mcp-0.8.0.tar.gz
- Upload date:
- Size: 77.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Kali GNU/Linux","version":"2026.1","id":"kali-rolling","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
144b696f5955edb84933712b45537efeb449aa42d4bf4a5afb813464734c1e6c
|
|
| MD5 |
51490ae8fa961ea99be49606be5312b0
|
|
| BLAKE2b-256 |
a8ebf962b94dd1490593f9c41fb09deb1f11961c568e7912aeb1936acdf87c23
|
File details
Details for the file command_vault_mcp-0.8.0-py3-none-any.whl.
File metadata
- Download URL: command_vault_mcp-0.8.0-py3-none-any.whl
- Upload date:
- Size: 55.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Kali GNU/Linux","version":"2026.1","id":"kali-rolling","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5fcf9685abd511fbf979366c94a70d84363a8a21cd01830bd14a7170d7cbb4e2
|
|
| MD5 |
ac84ed6454ac0b3e82e61ed39bd50830
|
|
| BLAKE2b-256 |
bf9bfd52d7b9dee3c2543375496b70d8361fd06c2007c558c61f477c7eae285b
|