Metadata-Version: 2.4
Name: cipher-mcp-scan
Version: 0.3.0
Summary: Local security scan CLI for Cipher checks
Author: Cipher
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: requests<3.0.0,>=2.31.0

# CIPHER MCP Scan

Version 0.3 adds deterministic tool-metadata quality rules while preserving the five static checks and optional `remote_oauth` behavior.

CIPHER is a local static scan for MCP-oriented codebases. It inspects a checked-out project locally and runs five focused static checks: authentication, over-privilege, CVE lookup, typosquatting, and tool poisoning.

The `tool_poisoning` check examines MCP JSON tool metadata for instruction overrides, data-exfiltration requests, dangerous URI schemes, and hidden Unicode control characters. It is always included with the four static checks; `remote_oauth` remains separate and opt-in through `--remote-url`.

Findings include stable `rule_id`, `detection_method`, evidence, confidence, remediation, line ranges, and `owasp_tags`. The scanner remains static and deterministic by default; remote OAuth is the only opt-in active probe.

## Modular API reports

The FastAPI service stores successful scan reports in `reports/` beside `modular_api.py` by default. Set `REPORTS_DIR` to use a different directory. Existing reports from the legacy `.cipher_reports/` location are not read automatically; move any files to `reports/` once if they need to remain available.

On Render, set `REPORTS_DIR` to the mount path when using a persistent disk. Without a Render persistent disk, report files are ephemeral and do not survive redeploys. This API storage is separate from the CLI's local `--output` option.


## Optional remote OAuth check

The fifth check is opt-in and runs only when an explicit remote URL is supplied. It probes OAuth well-known metadata, dynamic client registration, and a small set of redirect URI validation cases. It does not run during the normal `cipher-scan .` workflow or standard CI scans.

```bash
cipher-scan ./my-application --remote-url https://example.test/mcp --fail-on high
```

Remote connection failures are reported as low-severity transport results so static findings and the scan report are preserved. Only accepted dangerous redirect schemes produce high-severity remote findings. Use this check only against systems you are authorized to test; it is intended for lab and explicitly approved environments.

The remote OAuth probe is adapted from the concepts and minimal active probes in [remote-mcp-scanner](https://github.com/novasecuritynz/remote-mcp-scanner), copyright Nova Security, licensed under the MIT License. The reference project is not imported as a runtime dependency.

## Prior art / related tools

CIPHER's deterministic metadata rules were informed by [invariantlabs-ai/mcp-scan](https://github.com/invariantlabs-ai/mcp-scan), [yatuk/mcpradar](https://github.com/yatuk/mcpradar), [sahiloj/MCPScan](https://github.com/sahiloj/MCPScan), [alexandriashai/mcp-guardian](https://github.com/alexandriashai/mcp-guardian), and [bryand410/mcp-scrutiny](https://github.com/bryand410/mcp-scrutiny). OAuth probe concepts were compared with [novasecuritynz/remote-mcp-scanner](https://github.com/novasecuritynz/remote-mcp-scanner). No vendor source is bundled or required.

## Install

```bash
pip install cipher-mcp-scan
```

## Use CIPHER directly in the CLI

1. Install:
   ```bash
   pip install cipher-mcp-scan
   ```
2. Check it works:
   ```bash
   cipher-scan --help
   ```
3. Scan the current directory:
   ```bash
   cipher-scan . --fail-on high
   ```
4. Scan a specific project path:
   ```bash
   cipher-scan path/to/project --fail-on high
   ```
5. Report only without failing CI:
   ```bash
   cipher-scan . --fail-on none
   ```
6. Write a JSON report:
   ```bash
   cipher-scan . --fail-on high --format json --output cipher-report.json
   ```
7. Exit codes:
   - `0` = findings are below the selected threshold
   - `1` = findings are at or above the selected threshold
8. `--fail-on` values:
   - `critical`
   - `high`
   - `medium`
   - `none`

## Use CIPHER in GitHub Actions

Add a workflow in your project under `.github/workflows/` and run the scanner after checkout. This works for public and private repos because the scan is local to the checked-out code.

Point to the demo file in this repo at [examples/github-actions-cipher-scan.yml](examples/github-actions-cipher-scan.yml). You can copy that file into your repo as `.github/workflows/cipher-scan.yml`, or paste the workflow block below.

```yaml
name: CIPHER MCP Scan

on:
  pull_request:
  push:
    branches:
      - main
      - master
  workflow_dispatch:

jobs:
  cipher-scan:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Install CIPHER
        run: |
          python -m pip install --upgrade pip
          pip install cipher-mcp-scan

      - name: Run CIPHER scan
        env:
          GITHUB_STEP_SUMMARY: ${{ github.step_summary }}
        run: |
          cipher-scan . --fail-on high --summary github --output cipher-scan-report.json

      - name: Upload JSON report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: cipher-scan-report
          path: cipher-scan-report.json
          if-no-files-found: ignore
```

To use it in another repo:

1. Copy [examples/github-actions-cipher-scan.yml](examples/github-actions-cipher-scan.yml) to `.github/workflows/cipher-scan.yml`
2. Or paste the block above into that file
3. Open a PR or push to `main`/`master` to trigger the check

## Optional flags

- `--summary github` writes a markdown summary to the Actions job summary when available
- `--format text|json` changes the output style
- `--output REPORT.json` saves the machine-readable report

## Short note

v0.1 is limited to the built-in CIPHER checks. Optional third-party compare engines are future work and are not required for this package.

Longer internal notes are preserved in [README_ARCHIVE.md](README_ARCHIVE.md).

## CLI UX

The command-line tool has a short banner on `--help` / `-h` and no noisy startup banner on successful scans. Example help output includes the package name, version, example commands, and a one-line fail-on explanation.

## Local verification

Run these locally without uploading anything:

```bash
pip install -e .
cipher-scan --help
cipher-scan ./test/Cipher-demo-main --fail-on high
```

The demo path is useful for a quick smoke test because it includes intentionally vulnerable MCP sample code.

## Production smoke test

After a Render deploy, run these three requests in order:

1. `curl -sS https://<your-render-host>/health` and verify `status` is `ok`.
2. `curl -sS -X POST https://<your-render-host>/modularscan -H "Content-Type: application/json" -d '{"repo_url":"https://github.com/<owner>/<repo>"}'` and verify the five static checks remain in `checks_run`, with grouped `results` and the additive normalized `findings` envelope.
3. Repeat step 2 with `,"remote_url":"http://127.0.0.1:9"` added to the JSON body. Verify the response remains `status: "ok"`, includes `remote_oauth`, and records a low-severity transport finding without affecting static results.

Clients should poll `/health` before the first scan to accommodate Render cold starts.
