Metadata-Version: 2.4
Name: goose-pentest-mcp
Version: 0.1.0
Summary: MCP extension for self-pentest workflows (Goose-compatible stdio server)
Project-URL: Homepage, https://github.com/turer73/goose-pentest-mcp
Project-URL: Repository, https://github.com/turer73/goose-pentest-mcp
Project-URL: Documentation, https://github.com/turer73/goose-pentest-mcp/blob/main/README.md
Project-URL: Issues, https://github.com/turer73/goose-pentest-mcp/issues
Author: KlipperOS
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: agent,goose,llm,mcp,pentest,security
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27.0
Requires-Dist: mcp>=1.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.7.0; extra == 'dev'
Description-Content-Type: text/markdown

# goose-pentest-mcp

A [Model Context Protocol](https://modelcontextprotocol.io) extension for
self-pentest workflows. Exposes six tools to [Goose](https://block.github.io/goose/)
(or any MCP-compatible client) so an LLM can list targets, trigger scans,
read findings, and mark them resolved — all against **your** backend.

The extension is a thin HTTP client. It does not shell out, write files,
or scan anything itself. You supply the backend; it supplies the agent
surface.

## What you need

1. A backend implementing the six endpoints in [`BACKEND_CONTRACT.md`](BACKEND_CONTRACT.md).
2. An API key your backend will accept in `X-Pentest-Key`.
3. Goose (or another MCP client) installed locally.

If you have not built a backend yet, see the **Reference implementation**
section below — there's a working FastAPI one (Apache-2.0) you can read
or adapt.

## Install

```bash
pip install goose-pentest-mcp
# or, if you use uv:
uvx goose-pentest-mcp
```

To install from source (or hack on it):

```bash
git clone https://github.com/turer73/goose-pentest-mcp.git
cd goose-pentest-mcp
pip install -e .
```

## Configure Goose

Edit `~/.config/goose/config.yaml`:

```yaml
extensions:
  pentest:
    type: stdio
    name: pentest
    display_name: "Self-Pentest"
    description: "List targets, trigger scans, manage findings"
    enabled: true
    bundled: false
    timeout: 600
    cmd: python
    args:
      - -m
      - goose_pentest_mcp.server
    env_keys:
      - PENTEST_API_KEY
    envs:
      PENTEST_API_BASE: "https://your-backend.example.com/api/v1/security"
```

Then export the key from your shell rc:

```bash
export PENTEST_API_KEY="$(cat ~/.secrets/pentest-key)"
```

`config.yaml` may end up holding (or revealing the path to) live secrets;
`chmod 600 ~/.config/goose/config.yaml` is the minimum hygiene. If
`restic` / `borg` / `rclone` covers `~/.config/`, those backups carry the
key — rotate after first install if backups already ran.

## Tools

| Tool                       | Verb + path                                |
| -------------------------- | ------------------------------------------ |
| `pentest_list_targets`     | `GET  /pentest/targets`                    |
| `pentest_run_scan`         | `POST /pentest/run`                        |
| `pentest_get_run`          | `GET  /pentest/runs/{job_id}`              |
| `pentest_recent_findings`  | `GET  /pentest/findings`                   |
| `pentest_get_finding`      | `GET  /pentest/findings/{id}`              |
| `pentest_resolve_finding`  | `PUT  /pentest/findings/{id}/resolve`      |

Full request/response shapes: see [`BACKEND_CONTRACT.md`](BACKEND_CONTRACT.md).

## Blast radius

The extension's surface is exactly the six endpoints above. It cannot:
- shell out (no `exec` / `command` tool)
- read or write files outside the HTTP contract
- escape the API perimeter your backend enforces

So an LLM with access to this extension can do at most what an
authenticated client with your API key could do. The **whitelist** is
enforced on the backend (not in this extension), so a scan request for
an off-list domain returns HTTP 400 — the LLM sees the error and adjusts.

If you co-install an extension that *does* shell out (e.g. `developer`),
the above guarantee no longer holds for that combined surface. Choose
deliberately.

## First smoke test

```text
You: list my pentest targets
Goose: [calls pentest_list_targets] → example.com, shop.example.com, ...

You: any open findings on shop.example.com?
Goose: [calls pentest_recent_findings(project="shop.example.com")] → ...
```

If `pentest_list_targets` returns `{"error": true, "status_code": 401}`,
`PENTEST_API_KEY` isn't reaching the subprocess — check `env_keys:` and
your shell export. Connection errors mean `PENTEST_API_BASE` is wrong or
the backend is unreachable.

## Reference implementation

[`linux-ai-server`](https://github.com/turer73/claude-server) hosts a
FastAPI implementation of the full backend contract under
`/api/v1/security/pentest/*` (Apache-2.0). It serves all six endpoints
out of the box — point `PENTEST_API_BASE` at it and it works without an
adapter:

```text
PENTEST_API_BASE=https://your-host/api/v1/security
```

Files of interest:
- `app/api/security.py` — endpoints + `X-Pentest-Key` auth (legacy
  `X-Memory-Key` also accepted for in-place migration)
- `automation/self-pentest.sh` — example scan script the backend spawns

## License

Apache-2.0. See `LICENSE`.
