> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentopfor.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP server

> Run opfor as an MCP server so AI assistants can drive it from chat.

Opfor can run as an MCP server, exposing its workflow as tools that any MCP-compatible assistant (Cursor, Claude Desktop, Windsurf) can call. Your assistant runs a full red-team from chat — no terminal required.

<Warning>This is different from attacking an MCP server as a *target*. Here, opfor *is* the MCP server. To test an MCP server, see [MCP mode in the CLI](/cli/overview#two-testing-modes).</Warning>

## How it works

The assistant calls three tools in sequence:

<Steps>
  <Step title="opfor_list_evaluators">
    Discover available evaluator IDs and suites. Call this first when you haven't named specific evaluators.
  </Step>

  <Step title="opfor_setup">
    Configure a target and write `opfor.config.json`. Returns the config path.
  </Step>

  <Step title="opfor_run">
    Generate attacks on the fly, run them, judge responses, and write HTML + JSON reports.
  </Step>
</Steps>

No pre-generated attack file is needed — `opfor_run` handles generation, execution, and reporting in one shot.

## Install

```bash theme={null}
git clone https://github.com/KeyValueSoftwareSystems/agent-opfor.git
cd opfor
npm install
npm run build
```

Or run directly via `npx` without cloning (see the npx tab above).

## Register the server

<Tabs>
  <Tab title="Cursor">
    Add to `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (project-scoped):

    ```json theme={null}
    {
      "mcpServers": {
        "opfor": {
          "command": "node",
          "args": ["/absolute/path/to/opfor/runners/mcp/dist/index.js"]
        }
      }
    }
    ```
  </Tab>

  <Tab title="Claude Desktop">
    Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:

    ```json theme={null}
    {
      "mcpServers": {
        "opfor": {
          "command": "node",
          "args": ["/absolute/path/to/opfor/runners/mcp/dist/index.js"]
        }
      }
    }
    ```
  </Tab>

  <Tab title="npx (recommended)">
    No clone or global install needed:

    ```json theme={null}
    {
      "mcpServers": {
        "opfor": {
          "command": "npx",
          "args": ["-y", "@keyvaluesystems/agent-opfor-mcp"]
        }
      }
    }
    ```
  </Tab>
</Tabs>

The server reads API keys from your project's `.env` automatically — no `env` block needed in the config.

## Usage

Once registered, just talk to your assistant:

```
Red team my chatbot at http://localhost:4000/chat
```

It calls `opfor_list_evaluators` → `opfor_setup` → `opfor_run` and returns a findings summary in chat, with reports saved to disk.

## Tools reference

### `opfor_list_evaluators`

No parameters. Returns every evaluator ID, severity, `standards` map, and all predefined suites.

### `opfor_setup`

Configures a run and writes `opfor.config.json`. Returns the config path to pass to `opfor_run`.

<AccordionGroup>
  <Accordion title="Target">
    | Parameter     | Type             | Required | Description                                 |
    | ------------- | ---------------- | -------- | ------------------------------------------- |
    | `target_name` | string           | Yes      | Human-readable name                         |
    | `target_kind` | `agent` \| `mcp` | Yes      | `agent` for HTTP/chatbot, `mcp` for servers |

    **Agent target** (`target_kind = "agent"`):

    | Parameter                    | Type                               | Required    | Description                                                      |
    | ---------------------------- | ---------------------------------- | ----------- | ---------------------------------------------------------------- |
    | `agent_endpoint`             | string                             | For HTTP    | URL to attack                                                    |
    | `agent_request_format`       | `auto` \| `openai` \| `json`       | No          | Defaults to `auto`                                               |
    | `agent_api_key_env`          | string                             | No          | Env var name holding the target API key (e.g. `TARGET_API_KEY`)  |
    | `agent_model`                | string                             | No          | Model name sent to the target in the `model` field               |
    | `agent_script_path`          | string                             | For scripts | Path to a local `.js`/`.py` script                               |
    | `agent_description`          | string                             | No          | What the agent does                                              |
    | `agent_session_send_in`      | `body` \| `header`                 | No          | Where the session id is sent (stateful targets)                  |
    | `agent_session_send_name`    | string                             | No          | Body dot-path or header name for the sent id                     |
    | `agent_session_receive_in`   | `body` \| `header` \| `set-cookie` | No          | Where a **server-owned** target returns its id (enables capture) |
    | `agent_session_receive_name` | string                             | No          | Response dot-path / header / cookie name holding the returned id |

    Client-owned targets set only `agent_session_send_*`; server-owned targets (the target returns its own id) also set `agent_session_receive_*`. See [session handling](/reference/sessions).

    **MCP target** (`target_kind = "mcp"`):

    | Parameter       | Type             | Required  | Description                        |
    | --------------- | ---------------- | --------- | ---------------------------------- |
    | `mcp_transport` | `stdio` \| `url` | No        | Defaults to `stdio`                |
    | `mcp_command`   | string           | For stdio | Command to start the server        |
    | `mcp_args`      | string\[]        | No        | Arguments for the command          |
    | `mcp_env`       | object           | No        | Env vars for the server process    |
    | `mcp_url`       | string           | For url   | Server URL (SSE / Streamable HTTP) |
  </Accordion>

  <Accordion title="Evaluators, LLM, and run settings">
    **Evaluator selection** (pick one):

    | Parameter       | Type      | Description                       |
    | --------------- | --------- | --------------------------------- |
    | `suite_id`      | string    | Suite ID (e.g. `owasp-mcp-top10`) |
    | `evaluator_ids` | string\[] | Specific evaluator IDs            |

    **LLM configuration:**

    | Parameter    | Type   | Required | Description                                |
    | ------------ | ------ | -------- | ------------------------------------------ |
    | `attack_llm` | object | Yes      | LLM for generating attacks                 |
    | `judge_llm`  | object | No       | LLM for judging (defaults to `attack_llm`) |

    LLM object: `{ provider, model, api_key_env, base_url? }`.

    **Run settings:**

    | Parameter           | Type                          | Description                                            |
    | ------------------- | ----------------------------- | ------------------------------------------------------ |
    | `effort`            | `adaptive` \| `comprehensive` | Defaults to `adaptive`                                 |
    | `turns`             | number (1–10)                 | Turns per attack; `1` = single-turn (default)          |
    | `attack_objective`  | string                        | Free-text mission steering every evaluator's attacks   |
    | `judge_hint`        | string                        | Free-text steering for the judge's verdict             |
    | `business_use_case` | string                        | Free-text domain/business context for the target agent |
    | `output_dir`        | string                        | Where to write the config (default `.`)                |
    | `config_path`       | string                        | Full config path (overrides `output_dir`)              |
  </Accordion>
</AccordionGroup>

### `opfor_run`

Runs the full evaluation from a config produced by `opfor_setup`.

| Parameter                    | Type                          | Required | Description                                |
| ---------------------------- | ----------------------------- | -------- | ------------------------------------------ |
| `config_path`                | string                        | Yes      | Path to the `opfor.config.json`            |
| `output_dir`                 | string                        | No       | Report directory (default: config dir)     |
| `effort_override`            | `adaptive` \| `comprehensive` | No       | Override config effort                     |
| `turns_override`             | number (1–10)                 | No       | Override config turns                      |
| `objective_override`         | string                        | No       | Override the attack objective from config  |
| `judge_hint_override`        | string                        | No       | Override the judge hint from config        |
| `business_use_case_override` | string                        | No       | Override the business use case from config |

## API key resolution

The server resolves keys in order:

1. The env var named in the LLM config's `api_key_env`
2. The provider's default env var (e.g. `OPENAI_API_KEY` for `openai`)

It loads `.env` from the working directory automatically — keys never go in the MCP config JSON.

<Card title="Providers" icon="key" href="/reference/providers">
  Supported providers and their default env vars.
</Card>
