Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

MCP Policies API

MCP policies enforce default-deny tool allowlists on Streamable HTTP MCP servers. See MCP Interception for the runtime semantics, JSON-RPC handling, and tools/list filtering behavior.

Each policy targets a subset of the fleet by tag, scopes which requests it applies to with rules, and lists the tools an agent is allowed to call along with optional argument matchers.

Base path: /v1/policies/mcp

The MCP Policy Object

{
  "id": "mpol_01H...",
  "name": "github-mcp",
  "active": true,
  "priority": 0,
  "match_tags": ["production"],
  "rules": [
    { "host": "mcp.github.com", "paths": ["/mcp", "/mcp/*"], "methods": ["POST"] }
  ],
  "tools": [
    { "name": "search_repositories", "matchers": [] },
    {
      "name": "create_issue",
      "matchers": [
        { "path": "owner", "equals": "ironsh" },
        { "path": "repo", "in": ["iron-proxy", "tunis-v2"] }
      ]
    }
  ],
  "created_at": "2026-05-08T12:00:00Z",
  "updated_at": "2026-05-08T12:00:00Z"
}

Fields

FieldTypeDescription
idstringServer-assigned opaque ID, prefixed with mpol_.
namestringURL-safe name, unique within the organization. Must match [a-z0-9]+(-[a-z0-9]+)*.
activebooleanWhen false, the policy is stored but not delivered to proxies. Defaults to true.
priorityintegerTie-breaker when more than one policy applies. Lower wins. Required.
match_tagsstring[]Tags a proxy must carry for the policy to apply. Empty applies to every proxy.
rulesobject[]Request rules that scope which traffic the MCP interceptor handles. Same shape as network policy rules.
toolsobject[]Allowlisted tools. Tools not listed are denied.
created_atstringRFC 3339 timestamp.
updated_atstringRFC 3339 timestamp.

Tool Object

{
  "name": "create_issue",
  "matchers": [
    { "path": "owner", "equals": "ironsh" },
    { "path": "repo", "in": ["iron-proxy", "tunis-v2"] },
    { "path": "title", "matches": "^\\[bot\\]" }
  ]
}
FieldTypeDescription
namestringThe MCP tool name. Required.
matchersobject[]Argument constraints. All matchers must pass for a tools/call to be allowed. Empty allows any arguments.

Matcher Object

A matcher selects a value from params.arguments by path (dotted notation) and applies exactly one of equals, in, or matches.

FieldTypeDescription
pathstringDotted path into the tool arguments. Required.
equalsanyArgument at path must equal this value.
inany[]Argument at path must be one of these values.
matchesstringArgument at path, stringified, must match this regular expression.

Set exactly one of equals, in, matches per matcher. Sending more than one returns 422 with code validation_error.

List MCP Policies

GET /v1/policies/mcp

Returns every MCP policy in the calling organization, ordered by priority ascending.

Query Parameters

NameTypeDescription
namestringExact match on policy name.
activebooleanWhen supplied, returns only policies with that active state.
curl https://api.iron.sh/v1/policies/mcp \
  -H "Authorization: Bearer $IRON_API_KEY"

Create an MCP Policy

POST /v1/policies/mcp

Request Body

FieldTypeRequired
namestringYes
priorityintegerYes
activebooleanNo
match_tagsstring[]No
rulesobject[]No
toolsobject[]No

Example

curl https://api.iron.sh/v1/policies/mcp \
  -H "Authorization: Bearer $IRON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "linear-mcp",
    "priority": 42,
    "match_tags": ["production", "linear"],
    "rules": [
      { "host": "mcp.linear.app", "paths": ["/mcp"], "methods": ["POST"] }
    ],
    "tools": [
      {
        "name": "create_issue",
        "matchers": [
          { "path": "team", "in": ["eng", "infra"] },
          { "path": "title", "matches": "^\\[bot\\]" }
        ]
      }
    ]
  }'

Returns 201 Created with the new policy in data.

Retrieve an MCP Policy

GET /v1/policies/mcp/:id

Returns 200 OK with the policy in data, or 404 Not Found with code mcp_policy_not_found.

Update an MCP Policy

PUT /v1/policies/mcp/:id

GET the policy, modify the fields you want to change, and PUT the full representation back. Send the same fields you would on create.

Example

curl -X PUT https://api.iron.sh/v1/policies/mcp/mpol_01H... \
  -H "Authorization: Bearer $IRON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "github-mcp",
    "priority": 0,
    "active": false,
    "match_tags": ["production"],
    "rules": [
      { "host": "mcp.github.com", "paths": ["/mcp", "/mcp/*"], "methods": ["POST"] }
    ],
    "tools": [
      { "name": "search_code", "matchers": [{ "path": "repo", "equals": "console" }] }
    ]
  }'

Delete an MCP Policy

DELETE /v1/policies/mcp/:id

Returns 204 No Content. Connected proxies stop applying the policy within seconds.