Metadata-Version: 2.5
Name: plexicus-mcp
Version: 0.3.0
Summary: Plexicus AppSec MCP server — security findings, scans and AI remediations in your IDE
Project-URL: Homepage, https://plexicus.ai
Project-URL: Documentation, https://docs.plexicus.ai
Project-URL: Source, https://github.com/plexicus/plexicus-mcp
Project-URL: Support, https://app.plexicus.ai
Author-email: Plexicus <info@plexicus.com>
License-Expression: MIT
License-File: LICENSE
Keywords: appsec,claude,cursor,mcp,plexicus,sast,security
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Requires-Dist: keyring>=24; platform_system == 'Darwin' or platform_system == 'Windows' or platform_system == 'Linux'
Requires-Dist: mcp<2,>=1.2
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Provides-Extra: keyring
Requires-Dist: keyring>=24; extra == 'keyring'
Description-Content-Type: text/markdown

# plexicus-mcp

MCP (Model Context Protocol) server for [Plexicus](https://plexicus.ai), the AI-powered
AppSec platform. It brings your security findings,
scans and AI-generated remediations directly into Claude Code, Cursor, VS Code, Windsurf or
any MCP-compatible client — so your coding agent can find, understand and fix vulnerabilities
without leaving the IDE.

## Requirements

- Python **3.10 or newer** (CI runs 3.10 and 3.12; 3.11 and 3.13 are supported).
- A Plexicus account (you sign in with `plexicus-mcp login`).

## Install

Your MCP client starts the server for you, so the simplest route is to let it run the package
on demand (no manual install):

```bash
uvx plexicus-mcp --version     # uv   (https://docs.astral.sh/uv/)
pipx run plexicus-mcp --version # pipx
```

or install it permanently:

```bash
pip install plexicus-mcp       # provides the `plexicus-mcp` command
plexicus-mcp --version
```

## Sign in

```bash
uvx plexicus-mcp login            # opens your browser, you approve on the Plexicus consent page
uvx plexicus-mcp login --device   # SSH, containers, no browser: prints a short code to enter at
                                  # https://app.plexicus.ai/activate
uvx plexicus-mcp logout           # revokes the token on the server and deletes the local copy
```

(Installed with pip? Drop `uvx` and run `plexicus-mcp login`.) `login` is chosen
automatically as the device flow when no browser can be opened. No password and no token is
ever typed or pasted: the browser authorises a request bound to this machine (PKCE on
`127.0.0.1`, ports 9100-9199, waits up to 120 seconds) and the server issues a personal API
token that acts with your own role. Tokens last 90 days by default (you can choose 1-365 days
on the consent page); you can list and revoke them in **Settings -> API Tokens**.
`login --scope "read remediate scan support"` records the scopes you want on the token (default
`read`; scopes are shown on the consent page and not enforced yet).

### Where the token is stored

1. **OS keychain** through the [`keyring`](https://pypi.org/project/keyring/) library: macOS
   Keychain, Windows Credential Manager, Secret Service / KWallet on Linux. `keyring` is
   installed by default on those platforms (`pip install "plexicus-mcp[keyring]"` forces it).
2. **Fallback file** `credentials.json` (mode 0600, directory 0700) under the platform config
   directory (`~/Library/Application Support/plexicus-mcp`, `%APPDATA%\plexicus-mcp`,
   `$XDG_CONFIG_HOME/plexicus-mcp` or `~/.config/plexicus-mcp`) when no keyring backend exists
   (typically a headless Linux box). `login` prints a warning when it falls back.

Token resolution when the server starts: `PLEXICUS_API_TOKEN` (CI only, see below) -> keychain
or fallback file -> an error that tells you to run `plexicus-mcp login`. The environment
variable is never written to disk. If it is set it wins over a stored login, so unset it for
interactive use.

### CI and other non-interactive use

Set `PLEXICUS_API_TOKEN` to a personal API token created for that job (**Settings -> API
Tokens**, short expiry) from your CI system's secret store. Do not put it in a file you
commit. The Plexalyzer / CI scanner token is not accepted here. When stdout is a terminal the
server logs a one-line stderr warning that an environment token is in use.

The API base URL defaults to `https://api.app.plexicus.ai` and is restricted: it must be
`https` and end with `.plexicus.ai` (for example `https://api.balmis.plexicus.ai` for the EU
region, `https://api.staging.plexicus.ai`). Anything else is refused so that a project config
cannot redirect your token to another host; see **Configuration** for the two opt-ins.

## Add the server to your client

Run `plexicus-mcp login` once (above); the configs below carry no token. Formats checked
against each tool's documentation on 2026-10-13.

### Claude Code

```bash
claude mcp add --transport stdio plexicus -- uvx plexicus-mcp
```

Add `--scope user` to make it available in all your projects, or `--scope project` to write a
shared `.mcp.json`. Run `/mcp` inside Claude Code or `claude mcp get plexicus` to check it.
A project `.mcp.json` equivalent:

```json
{
  "mcpServers": {
    "plexicus": { "type": "stdio", "command": "uvx", "args": ["plexicus-mcp"] }
  }
}
```

### Cursor

Put this in `~/.cursor/mcp.json` (all projects) or `.cursor/mcp.json` (one project):

```json
{
  "mcpServers": {
    "plexicus": { "type": "stdio", "command": "uvx", "args": ["plexicus-mcp"] }
  }
}
```

### VS Code

Create `.vscode/mcp.json` in the workspace, or run **MCP: Open User Configuration** from the
Command Palette. VS Code uses a top-level `servers` key and requires `type`:

```json
{
  "servers": {
    "plexicus": { "type": "stdio", "command": "uvx", "args": ["plexicus-mcp"] }
  }
}
```

### Windsurf

Open the Cascade panel, its **...** menu, then **Open MCP config file** in the MCPs section
(the file lives under the Windsurf/Devin config directory, so use the action rather than a
hardcoded path), and add:

```json
{
  "mcpServers": {
    "plexicus": { "command": "uvx", "args": ["plexicus-mcp"] }
  }
}
```

No `uv`? Use `"command": "pipx", "args": ["run", "plexicus-mcp"]`, or install with pip and use
`"command": "plexicus-mcp"` with no args. Other MCP clients: any client that can launch a
stdio server works the same way.

For CI, add an `env` block with the variable referenced from your secret store, e.g. in Claude
Code `.mcp.json`: `"env": { "PLEXICUS_API_TOKEN": "${PLEXICUS_API_TOKEN}" }` (Cursor and
Windsurf: `${env:PLEXICUS_API_TOKEN}`).

## Configuration

| Variable | Default | Description |
|---|---|---|
| `PLEXICUS_API_TOKEN` | - | **CI / non-interactive use only.** Personal API token; overrides the stored login; never written to disk |
| `PLEXICUS_API_URL` | `https://api.app.plexicus.ai` | API base URL; must be `https` and end with `.plexicus.ai` |
| `PLEXICUS_ALLOW_CUSTOM_API_URL` | unset | `1` allows another `https` host (self-hosted); a warning says the token is sent to that host |
| `PLEXICUS_ALLOW_INSECURE_LOCALHOST` | unset | `1` allows `http(s)://localhost` / `127.0.0.1` (platform development) |
| `PLEXICUS_APP_URL` | derived (`api.` removed) | Web-app URL for the browser login on custom hosts |
| `PLEXICUS_CONFIG_DIR` | platform default | Directory of the fallback credentials file |

Redirects to another host are never followed with the Authorization header, and tokens are
redacted from error messages.

## What it exposes

**Tools**

| Tool | Description |
|---|---|
| `get_current_repository` | Map the workspace git remote to its Plexicus repository |
| `list_repositories` / `get_repository` | Browse registered repositories (server-side name/URL search) with finding counts per severity |
| `list_findings` / `get_finding` | Query findings (severity, pipeline status, CWE, text search, pagination); `finding_type` is `app` (default), `scm` or `pentest` |
| `request_scan` / `get_scan_status` | Launch a scan (`app` or `sbom`) and follow its derived state (running, stalled, completed, failed ...) |
| `generate_remediation` / `get_remediation` | Ask the AI remediation engine for a fix and fetch it (a not-yet-ready remediation is reported as `ready: false`, not an error) |
| `get_security_posture` | Account-wide severity totals and worst repositories |
| `get_credits` | Remaining AI credits and Pentest Units, period, reset date and whether limits are enforced |
| `list_pentests` / `get_pentest` | Read-only AI pentest list and status: target, mode, status, dates, severity counts, report available |
| `create_support_ticket` | Open an in-app support ticket (asks you for confirmation first, never include secrets, 3 per session) |

Severities are `critical`, `high`, `medium`, `low`, `informational` (`info` is accepted as an
alias). Scans and remediations consume credits on your account; the tools never display model,
provider, token or cost details. Results are projections of the API objects through an
allowlist (`src/plexicus_mcp/public.py`), so internal fields never reach your IDE.

Not offered: cloud-account and container-registry connections (discontinued platform
features). Pentest logs, reports and credentials are never exposed. The credits, pentests and
support tools need a platform version that serves the client API contract v1; on an older
server they answer "not available on this server" and everything else keeps working.

**Prompts** — `fix_finding`, `triage_findings`, `security_review`: guided workflows the agent
can follow end-to-end (read finding → generate remediation → apply diff → verify).

**Resources** — `plexicus://repositories` and `plexicus://repositories/{id}/findings` as JSON.

Every tool returns `{"markdown": ..., "data": ...}`: a human-readable digest plus the raw API
payload for follow-up automation.

## Example session

> *"What critical security issues does this repo have?"* — the agent calls
> `get_current_repository`, then `list_findings(severity="critical")`.
>
> *"Fix the SQL injection one"* — the agent uses the `fix_finding` prompt: reads the finding,
> requests an AI remediation, applies the diff to your workspace and runs the tests.

## Support

Questions or problems: open a ticket from inside the Plexicus app (https://app.plexicus.ai) or
ask your agent to use `create_support_ticket`. In-app tickets are the support channel for this
package.

## Development

```bash
pip install -e ".[dev]"
pytest
ruff check .
```

`mcp` is pinned `<2`: mcp 2.x removed `mcp.server.fastmcp`. Moving to 2.x needs a migration of
`server.py` (`FastMCP` -> `MCPServer`).

The API contract is covered by fixtures in `tests/fixtures/` (shaped like the real responses,
see its README). When a platform release changes `/repositories`, `/findings`, `/remediations`,
`/scan-runs` or `/repository-scans`, refresh the fixtures and `public.py` together.

Release procedure: see `RELEASING.md`. Licence: MIT (`LICENSE`).
