> For the complete documentation index, see [llms.txt](https://herd-security.gitbook.io/herd-security-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://herd-security.gitbook.io/herd-security-docs/api-documentation/mcp-server.md).

# MCP Server

Connect Claude, Cursor, or any MCP client to Herd: OAuth sign-in with your normal Herd login, read-only reporting tools, and draft-training creation that never publishes or assigns anything.

Herd speaks the **Model Context Protocol (MCP)**, so an AI assistant you already work in (Claude, Cursor, Claude Code, or any other MCP client) can read your organization's training, compliance, and phishing-simulation reporting and create **draft** trainings without leaving that tool. This is the same tool set HerdAI uses in the web chat, exposed over a standard interface.

{% hint style="info" %}
Not a developer? [Connect Your AI Assistant to Herd](/herd-security-docs/herdai/herdai/connect-your-ai-assistant.md) walks through setup in Claude Desktop, Cursor, and Claude Code step by step.
{% endhint %}

{% hint style="info" %}
The connection is read plus draft create-and-edit only. Nothing reachable over MCP can publish a training, assign anything, launch a campaign, or send a message to a learner. Those actions stay in Herd, behind the same review and approval steps as always.
{% endhint %}

## Endpoint

```
https://api.herdsecurity.io/mcp
```

The transport is **Streamable HTTP**: the client sends JSON-RPC 2.0 messages with `POST` and Herd answers as JSON or as server-sent events, depending on the client's `Accept` header. A `GET /mcp` with `Accept: text/event-stream` opens a server-to-client stream, on which Herd sends `notifications/tools/list_changed` when a change to your permissions changes the tools you can use; without that header, `GET` returns `405`. Most clients only need the URL; they discover everything else automatically.

## Connecting a client

Herd is the OAuth 2.0 authorization server for its MCP endpoint, with PKCE and dynamic client registration, so no client secret and no pre-registration are needed. A client that supports remote MCP servers with OAuth walks through this flow on its own:

1. The client fetches the discovery documents at `/.well-known/oauth-protected-resource` and `/.well-known/oauth-authorization-server` on the API origin.
2. It registers itself at `POST /mcp/oauth/register` and receives a `client_id`. Registration is open by design: a client record is just an identity, and every token still needs a person to approve it.
3. It opens `GET /mcp/oauth/authorize` in your browser (PKCE `S256` is required).
4. You sign in to Herd the way you always do: your organization's own login, including SSO if that's how your organization signs in.
5. Herd shows a consent screen naming the client and listing what it will be able to do. Click **Allow connection** to approve, or **Cancel**. Approving binds the connection to you and to your organization.
6. The browser returns to the client with a one-time code, which the client exchanges at `POST /mcp/oauth/token` for an access token and a refresh token.

Once connected, the client calls tools on your behalf. Every call is scoped to your organization and filtered by your own Herd permissions: a tool you couldn't use in HerdAI isn't offered over MCP either.

{% hint style="warning" %}
**Only approve connections you started yourself.** The consent screen shows where Herd will send the credentials: a loopback address for an app running on your computer (Claude Code, and current versions of Cursor), a private-use scheme such as `cursor://` for an app installed on your computer, or a server on the internet (Claude Desktop and claude.ai connect through `claude.ai`). For a server on the internet the screen shows a warning, and you should cancel unless you recognise that address. Anyone can register a client under any name, so the name alone is not proof of who is asking.
{% endhint %}

### Scopes

| Scope                 | What it allows                                                                   |
| --------------------- | -------------------------------------------------------------------------------- |
| `herd:read`           | Read your organization's training, compliance, and phishing-simulation reporting |
| `herd:training:draft` | Create and edit draft trainings — it cannot publish or assign anything           |

A client that asks for no scopes gets both.

### Token lifetimes

* Access tokens last **1 hour**; the client refreshes them silently with its refresh token.
* Refresh tokens rotate on every use and expire **30 days** after the connection was last used, so an idle connection lapses on its own. Reconnect through the same flow to continue.
* A pending consent request stays open for **10 minutes**; after that, start the connection again from the client.

MCP tokens are separate from [API keys](/herd-security-docs/api-documentation/authentication.md). They don't authenticate against `/api/v1`, and an API key doesn't authenticate against `/mcp`.

## What the client can do

The tools are a curated subset of HerdAI's, so an MCP client and the in-app assistant answer the same question the same way.

**Read tools** (`herd:read`):

* **General-purpose data access**: `query_data`, `aggregate_data`, plus `list_tables`, `get_table_schema`, and `get_sample_data` to explore what's available. These run against an allowlist of Herd tables, always scoped to your organization, and are how you answer questions like "all the phishing failures from last week" or "who completed which trainings this month".
* **Training and track completion**: `list_trainings`, `search_trainings`, `search_tracks`, `get_training`, `get_training_completers`, `get_incomplete_assignments`, `get_training_assignment_status_breakdown`, `get_training_effectiveness`, `get_training_impact`, `get_user_training_status`.
* **Compliance and policies**: `get_compliance_metrics`, `list_policies`.
* **Organization-level reporting**: `get_organization_summary`, `get_user_engagement`, `get_user_completion_rankings`, `get_team_analysis`, `get_risk_assessment`, `get_metric_definitions`.
* **People and groups**: `search_users`, `list_groups`.
* **Phishing results**: `get_phishing_results`, `list_phishing_campaigns`, `get_campaign_recipients`.

**Draft tools** (`herd:training:draft`):

* `preview_training` generates a training and saves it as a **draft**. It appears under **Trainings → Drafts** in Herd, where you can edit it, **Add to Library**, or discard it, exactly like a draft created in the web chat. Submitting for review happens on the library training in Herd, not over MCP.
* `update_training_draft` edits a draft in place — its title, description, tags, the wait-for-reply setting, or removing a step — without regenerating it. It requires the `draftId` of the draft to edit.

Ask your client for the tool list (`tools/list`) to see the descriptions and parameters; they're identical to HerdAI's own tool definitions and update together.

## Typical uses

* Draft a training in the editor where you already have your other MCP connections (Slack, Drive, Confluence), pulling in context from those sources, then push the result into Herd as a draft for review.
* Run an assistant over your own repositories or data lake, mine patterns, and turn what it finds into a draft training.
* Pull reporting into a notebook or an internal agent: "everyone who failed a simulation last week", "trainings completed this quarter by department".

## Limits

MCP calls go through the same permission checks and organization scoping as HerdAI. Draft-training generation counts against your per-user hourly AI-generation quota, the same one Herd's in-app AI generation uses, so a client that has used it up is told how long to wait rather than being given a second allowance.

`preview_training` without a `draftId` always creates a **new** draft and never changes an existing one. To refine a draft, pass the `draftId` returned by an earlier call and it is revised in place; every `preview_training` result returns that id. `update_training_draft` and adding steps both **require** a `draftId` over MCP and are refused without one, since there is no implicit draft to edit or append to.

Each connected client still gets one durable Herd conversation per user, so drafts accumulate under **Trainings → Drafts** rather than replacing each other.
