> ## Documentation Index
> Fetch the complete documentation index at: https://portkey-docs-docs-prisma-airs-kickstart.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Guardrails

> Apply security and compliance guardrails to MCP tool calls — regex filters, content validation, webhook checks, JSON schema enforcement, and more.

When AI agents invoke tools through MCP servers, sensitive data can flow in both directions — tool inputs may contain PII or restricted content, and tool outputs may return confidential data. MCP Guardrails let you intercept and enforce policies on `tools/call` requests at two stages:

| Stage      | What it covers                          |
| ---------- | --------------------------------------- |
| **Input**  | The arguments sent *to* the MCP tool    |
| **Output** | The result returned *from* the MCP tool |

You can apply guardrails at the **workspace level** (default for all MCP servers in a workspace) or at the **server level** (targeting specific MCP servers and even individual tools).

***

## How It Works

MCP guardrails use the same policy engine as LLM guardrails, with the `target` field set to `mcp_tools`. This keeps MCP and LLM guardrails separate — existing LLM guardrails are unaffected.

Each guardrail consists of **checks** (the validation rules) and **actions** (what happens when a check fails). You then **map** the guardrail to one or more MCP servers, choosing whether it runs on tool inputs, outputs, or both.

When both workspace-level and server-level guardrails are configured, server-level guardrails are applied **in addition to** workspace defaults.

***

## Supported Checks

The following guardrail checks are available for MCP tool calls (`target: "mcp_tools"`):

| Check ID                           | Name                              | Description                                                            |
| ---------------------------------- | --------------------------------- | ---------------------------------------------------------------------- |
| `default.regexMatch`               | Regex Match                       | Match patterns in tool inputs or outputs                               |
| `default.regexReplace`             | Regex Replace                     | Match and replace patterns in tool data                                |
| `default.contains`                 | Contains                          | Check if content contains any, all, or none of specified words/phrases |
| `default.endsWith`                 | Ends With                         | Check if content ends with a specific string                           |
| `default.webhook`                  | Webhook                           | Send tool call data to an external service for custom validation       |
| `default.jsonSchema`               | JSON Schema                       | Validate tool input/output against a JSON schema                       |
| `default.jsonKeys`                 | JSON Keys                         | Check for required keys in JSON tool data                              |
| `default.sentenceCount`            | Sentence Count                    | Enforce sentence count ranges                                          |
| `default.wordCount`                | Word Count                        | Enforce word count ranges                                              |
| `default.characterCount`           | Character Count                   | Enforce character count ranges                                         |
| `default.containsCode`             | Contains Code                     | Detect code (SQL, Python, TypeScript, etc.) in tool data               |
| `default.validUrls`                | Valid URLs                        | Validate that all URLs in tool data are well-formed                    |
| `default.isAllLowerCase`           | Lowercase Check                   | Check if content is all lowercase                                      |
| `default.alluppercase`             | Uppercase Check                   | Check if content is all uppercase                                      |
| `default.notNull`                  | Not Null                          | Ensure tool output is not null, undefined, or empty                    |
| `default.requiredMetadataKeys`     | Required Metadata Keys            | Check that metadata contains all required keys                         |
| `default.requiredMetadataKeyPairs` | Required Metadata Key-Value Pairs | Check for specific key-value pairs in metadata                         |
| `default.requestParametersCheck`   | Request Parameters Check          | Validate request parameters                                            |

<Note>
  LLM-specific checks (PII detection, content moderation, language checks, and third-party provider checks like Patronus, Azure, Bedrock, etc.) are not available for MCP tool calls. Use the checks listed above for MCP guardrails.
</Note>

***

## Key Concepts

### Target

Every guardrail has a `target` field:

| Target      | Description                                              |
| ----------- | -------------------------------------------------------- |
| `llm`       | Applied to LLM API requests (default, existing behavior) |
| `mcp_tools` | Applied to MCP tool calls                                |

When creating a guardrail for MCP, set `target` to `"mcp_tools"`.

### Run On

Each MCP server mapping includes a `run_on` field that controls *when* the guardrail executes:

| Value    | Description                                                             |
| -------- | ----------------------------------------------------------------------- |
| `input`  | Run the guardrail on tool call **arguments** (before the tool executes) |
| `output` | Run the guardrail on tool call **results** (after the tool executes)    |

You can set `run_on` to `["input"]`, `["output"]`, or `["input", "output"]` for both.

### Capability Scoping

By default, a guardrail mapping applies to **all tools** on an MCP server. To narrow the scope to specific tools, pass `mcp_integration_capability_ids` — an array of tool capability UUIDs. The guardrail will only run on calls to those specific tools.

***

## Workflow

### Step 1: Create an MCP Guardrail

Create a guardrail with `target: "mcp_tools"`. Unlike LLM guardrails, `checks` and `actions` are optional at creation time — you can configure them later.

```bash cURL theme={null}
curl -X POST "https://api.portkey.ai/v1/guardrails" \
  -H "x-portkey-api-key: $PORTKEY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "MCP Tool Content Filter",
    "target": "mcp_tools",
    "checks": [
      {
        "id": "default.regexMatch",
        "parameters": {
          "rule": "(?i)(password|secret|api_key)",
          "onFail": "deny"
        }
      },
      {
        "id": "default.contains",
        "parameters": {
          "words": ["DROP TABLE", "DELETE FROM"],
          "operator": "none",
          "onFail": "deny"
        }
      }
    ],
    "actions": {
      "on_fail": "deny"
    }
  }'
```

**Response:**

```json theme={null}
{
  "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "slug": "pg-mcp-tool-content-filter-a1b2c3",
  "version_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "created_at": "2025-09-03T00:00:00.000Z",
  "created_by": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

### Step 2: Map the Guardrail to MCP Servers

Attach the guardrail to one or more MCP servers. You can use either the **bulk sync** endpoint (replace all mappings at once) or the **single upsert** endpoint.

#### Bulk Sync (Recommended)

This is a declarative, idempotent operation — it replaces the full set of MCP server mappings for the guardrail.

```bash cURL theme={null}
curl -X PUT "https://api.portkey.ai/v1/guardrails/{guardrailId}/mcp-servers" \
  -H "x-portkey-api-key: $PORTKEY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mcp_servers": {
      "<mcp-server-id-1>": {
        "run_on": ["input", "output"]
      },
      "<mcp-server-id-2>": {
        "run_on": ["input"],
        "mcp_integration_capability_ids": ["<capability-id>"]
      }
    }
  }'
```

**Response:**

```json theme={null}
{
  "changed": true,
  "added": 2,
  "updated": 0,
  "removed": 0
}
```

#### Single Server Upsert

Map or update a guardrail for a single MCP server:

```bash cURL theme={null}
curl -X PUT "https://api.portkey.ai/v1/guardrails/{guardrailId}/mcp-servers/{mcpServerId}" \
  -H "x-portkey-api-key: $PORTKEY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "run_on": ["input", "output"],
    "mcp_integration_capability_ids": ["<capability-id-1>", "<capability-id-2>"]
  }'
```

**Response:**

```json theme={null}
{
  "map_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

### Step 3: Verify the Configuration

List all MCP server mappings for a guardrail:

```bash cURL theme={null}
curl "https://api.portkey.ai/v1/guardrails/{guardrailId}/mcp-servers" \
  -H "x-portkey-api-key: $PORTKEY_API_KEY"
```

**Response:**

```json theme={null}
[
  {
    "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "guardrail_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "mcp_server_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "run_on": ["input", "output"],
    "capability_ids": ["xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"]
  }
]
```

### Workspace-Level Defaults

You can set MCP guardrails as workspace defaults so they apply to all MCP servers in a workspace. Configure `mcp_input_guardrails` and `mcp_output_guardrails` in your workspace settings.

***

## Blocked Request Response

When a guardrail blocks an MCP tool call, the gateway returns an MCP-compliant JSON-RPC error:

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32446,
    "message": "Request blocked by guardrail",
    "data": {
      "guardrail_id": "default.regexMatch",
      "reason": "Input matched restricted pattern"
    }
  }
}
```

***

## API Reference

### Create Guardrail

Create a new guardrail. Set `target` to `"mcp_tools"` for MCP guardrails.

```
POST /v1/guardrails
```

| Field     | Type   | Required    | Description                                         |
| --------- | ------ | ----------- | --------------------------------------------------- |
| `name`    | string | Yes         | Display name for the guardrail                      |
| `target`  | string | No          | `"llm"` (default) or `"mcp_tools"`                  |
| `checks`  | array  | Conditional | Required for `llm` target; optional for `mcp_tools` |
| `actions` | object | Conditional | Required for `llm` target; optional for `mcp_tools` |

***

### List Guardrails

Retrieve guardrails with optional filtering by target.

```
GET /v1/guardrails
```

| Parameter      | Type    | Required | Description                                      |
| -------------- | ------- | -------- | ------------------------------------------------ |
| `target`       | string  | No       | Comma-separated: `"llm"`, `"mcp_tools"`, or both |
| `page_size`    | integer | No       | Results per page (default: 100)                  |
| `current_page` | integer | No       | Page number (default: 0)                         |
| `search`       | string  | No       | Search guardrails by name                        |
| `id`           | string  | No       | Comma-separated guardrail IDs                    |

***

### Get Guardrail

Retrieve a single guardrail by ID or slug. For `mcp_tools` target guardrails, the response includes `mcp_server_mappings`.

```
GET /v1/guardrails/{guardrailId}
```

| Parameter     | Type   | Description                                           |
| ------------- | ------ | ----------------------------------------------------- |
| `guardrailId` | string | Guardrail UUID or slug (e.g., `pg-pii-filter-a1b2c3`) |

<Note>
  `mcp_server_mappings` is only included in the response when `target` is `"mcp_tools"`.
</Note>

***

### Update Guardrail

Update a guardrail's name, checks, or actions.

```
PUT /v1/guardrails/{guardrailId}
```

| Field     | Type   | Description                   |
| --------- | ------ | ----------------------------- |
| `name`    | string | Updated display name          |
| `checks`  | array  | Updated checks configuration  |
| `actions` | object | Updated actions configuration |

***

### Delete Guardrail

Archive a guardrail. This also removes all MCP server mappings.

```
DELETE /v1/guardrails/{guardrailId}
```

<Warning>
  A guardrail cannot be deleted if it is currently used in workspace or organisation defaults (including `mcp_input_guardrails` and `mcp_output_guardrails`). Remove it from defaults first.
</Warning>

***

### Bulk Sync MCP Server Mappings

Declaratively sync all MCP server mappings for a guardrail. This replaces the entire set — servers not included in the request body are removed.

```
PUT /v1/guardrails/{guardrailId}/mcp-servers
```

**Request Body:**

| Field                                          | Type      | Required | Description                                                                          |
| ---------------------------------------------- | --------- | -------- | ------------------------------------------------------------------------------------ |
| `mcp_servers`                                  | object    | Yes      | Map of MCP server UUID → config                                                      |
| `mcp_servers.*.run_on`                         | string\[] | No       | `["input"]`, `["output"]`, or `["input", "output"]` (default: `["input", "output"]`) |
| `mcp_servers.*.mcp_integration_capability_ids` | string\[] | No       | Scope to specific tool capabilities                                                  |

**Validation rules:**

* The guardrail must have `target: "mcp_tools"`
* All MCP server IDs must be valid UUIDs
* `run_on` must be a non-empty array containing `"input"` and/or `"output"`
* All `mcp_integration_capability_ids` must exist in the database

***

### Upsert Single MCP Server Mapping

Create or update a guardrail mapping for a single MCP server.

```
PUT /v1/guardrails/{guardrailId}/mcp-servers/{mcpServerId}
```

| Field                            | Type      | Required | Description                                                                          |
| -------------------------------- | --------- | -------- | ------------------------------------------------------------------------------------ |
| `run_on`                         | string\[] | No       | `["input"]`, `["output"]`, or `["input", "output"]` (default: `["input", "output"]`) |
| `mcp_integration_capability_ids` | string\[] | No       | Scope to specific tool capabilities                                                  |

***

### List MCP Server Mappings

List all MCP server mappings for a guardrail.

```
GET /v1/guardrails/{guardrailId}/mcp-servers
```

***

## Error Responses

| Status | Code                | Description                                     |
| ------ | ------------------- | ----------------------------------------------- |
| `400`  | `validation_failed` | Invalid request body or parameters              |
| `401`  | `unauthorized`      | Missing or invalid API key                      |
| `403`  | `forbidden`         | Insufficient permissions or feature not enabled |
| `404`  | `not_found`         | Guardrail, MCP server, or capability not found  |
| `500`  | `server_error`      | Internal server error                           |

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Guardrail Checks" icon="shield-check" href="/product/guardrails/list-of-guardrail-checks">
    Full list of available guardrail checks and parameters.
  </Card>

  <Card title="Rate Limits" icon="gauge" href="/product/mcp-gateway/rate-limits">
    Throttle MCP tool call requests and token consumption.
  </Card>

  <Card title="Observability" icon="chart-mixed" href="/product/mcp-gateway/observability">
    Monitor MCP tool call logs and usage analytics.
  </Card>

  <Card title="Access Control" icon="users" href="/product/mcp-gateway/access-control">
    Control which workspaces and users can access MCP servers.
  </Card>
</CardGroup>

***

<Card title="Portkey is now PRISMA AIRS AI Gateway. See it in action." href="https://www.paloaltonetworks.in/ai-security/ai-gateway?utm_source=portkey&utm_medium=referral&utm_campaign=prisma_airs&utm_content=docs_nav#contact" icon="arrow-up-right-from-square">
  Contact Us
</Card>
