Metadata-Version: 2.4
Name: command-vault-mcp
Version: 0.8.0
Summary: Search and retrieve security commands, exploit scripts, and methodology from your pentest writeups and shell history. CLI + MCP server for AI assistants.
License-File: LICENSE
Requires-Python: >=3.11
Requires-Dist: mcp>=1.0.0
Requires-Dist: pydantic>=2.0
Description-Content-Type: text/markdown

# 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_history` or `~/.bash_history` with deduplication and security redaction
- **Tag filtering** — Search by `#hashtags` extracted 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](https://docs.astral.sh/uv/).

```bash
git clone https://github.com/x746b/command-vault.git
cd command-vault
uv pip install -e .
```

## Quick Start

```bash
# 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

```bash
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:

```bash
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

```bash
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

```bash
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:

```bash
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

```bash
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

```bash
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`:

```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:**

~~~markdown
# 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 vault` from the project directory, or add `~/.local/bin` to PATH after `pip install -e .`
- **"No results found"** — Check `vault stats`, run `vault index --rebuild` if 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 `uv` is in PATH, test with `uv 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](LICENSE) file.
