Protect MCP Server With Policies

Overview

Applies a security or traffic management policy to an MCP server and deploys it to a self-managed Flex Gateway, walking through the full process from identifying the target MCP server to selecting a policy, configuring it, and deploying. Supports multiple starting points depending on what the user already has set up — an API Manager instance, an Exchange asset, or just an MCP server specification.

What you'll build: A fully configured policy enforced on your MCP server instance, deployed to a Flex Gateway

Prerequisites

Before starting, ensure you have:

  1. Authentication ready

    • Valid Bearer token for Anypoint Platform. If you only have username/password, call createLogin (POST /accounts/login) from the urn:api:access-management API with body {"username":"...","password":"..."} to obtain a Bearer token first.
    • API Manager permissions: View APIs Configuration and Manage Policies scopes
  2. Organization Id

    • Call listMe (GET /accounts/api/me) from urn:api:access-management to get your organization ID
    • Extract organizationId from $.user.organization.id in the response
    • This is used to list environments, browse the policy catalog, check Exchange, etc.
  3. One of the following

    • An API instance already in API Manager for the MCP server (skip to Step 3, then Step 7)
    • An MCP server asset already in Exchange (skip to Step 2)
    • An MCP server specification that needs to be published first (start at Step 1)

Step 1: Publish MCP Server to Exchange

Publishes your MCP server specification to Exchange as a reusable asset. This makes it available for API Manager to create managed instances from it.

$ curl -X POST ${baseUrl}/assets \
  -H "Authorization: Bearer ${authToken}" \
  -H "Content-Type: application/json"
Captured Variables
groupId $.groupId
assetId $.assetId
assetVersion $.version

What happens next: Your MCP server specification is now available in Exchange. Next, you can search for it to confirm and extract the coordinates needed for API Manager.

Step 2: Find MCP Server in Exchange

Search Exchange for MCP server assets. This search is not scoped to a specific organization — it returns all MCP server assets visible to the authenticated user across all organizations.

$ curl -X GET ${baseUrl}/assets/search?types=mcp \
  -H "Authorization: Bearer ${authToken}" \
  -H "Content-Type: application/json"
Captured Variables
groupId $[*].groupId
assetId $[*].assetId
assetVersion $[*].version

What happens next: You have the Exchange coordinates (groupId, assetId, version) for the MCP server. Next, select an environment where the API instance will be created.

Step 3: List Environments

List all environments in the organization so you can confirm or select the one where your MCP server instance will live.

$ curl -X GET ${baseUrl}/organizations/{organizationId}/environments \
  -H "Authorization: Bearer ${authToken}" \
  -H "Content-Type: application/json"
Captured Variables
environmentId $.data[*].id

What happens next: With the environment selected, you can create an API instance or browse policies.

Step 4: Select Deployment Target

List available gateway targets registered in the environment. You need the target ID and gateway version before creating the API instance, because the deployment configuration is set via a PATCH after creation.

api-portal-xapi.getGatewayTargets
$ curl -X GET ${baseUrl}/apimanager/xapi/v1/organizations/{organizationId}/environments/{environmentId}/gateway-targets \
  -H "Authorization: Bearer ${authToken}" \
  -H "Content-Type: application/json"
Captured Variables
targetId $.rows[*].id
targetName $.rows[*].name
gatewayVersion

What happens next: You have a deployment target and its gateway version. Next, create the API instance and then configure its deployment target.

Step 5: Create API Manager Instance

Creates a managed API instance in API Manager from your MCP server Exchange asset. This creates the API configuration; deployment to the Flex Gateway happens in Step 6.

Important: For Flex Gateway instances, isCloudHub must be null (not false). Setting it to false causes a validation error.

$ curl -X POST ${baseUrl}/organizations/{organizationId}/environments/{environmentId}/apis \
  -H "Authorization: Bearer ${authToken}" \
  -H "Content-Type: application/json"
Captured Variables
environmentApiId $.id

What happens next: The API instance exists but is not yet deployed. Next, deploy it to the Flex Gateway target selected in Step 4.

Step 6: Deploy to Flex Gateway

Deploys the API instance to the selected Flex Gateway target. This uses the Proxies API deployment endpoint with flat top-level fields — do not use the nested target object, which requires additional fields that are not needed for self-managed Flex Gateway deployments.

$ curl -X POST ${baseUrl}/organizations/{organizationId}/environments/{environmentId}/apis/{environmentApiId}/deployments \
  -H "Authorization: Bearer ${authToken}" \
  -H "Content-Type: application/json"
Captured Variables
deploymentId $.id

Request body structure: Use flat top-level fields, not the nested target object:

{
  "type": "HY",
  "targetId": "<from Step 4>",
  "targetName": "<from Step 4>",
  "gatewayVersion": "1.0.0",
  "environmentId": "<from Step 3>",
  "overwrite": false
}

What happens next: The MCP server instance is now deployed to the Flex Gateway. Next, browse the policy catalog to select which policy to apply.

Common issues:

  • "Field environmentId is required for deployment type HY": The environmentId must be in the request body, not just the URL path parameter.
  • "Field gatewayVersion is required for deployment type HY": Use the version from the getGatewayTargets response (Step 4). Using an incorrect version causes policy implementation errors.
  • "Policy implementations cannot be set because runtime version is unknown": The gatewayVersion value doesn't match a known Flex Gateway version. Verify the version from the target's actual runtime version in Step 4.
  • 409 Conflict: The MCP server may already be deployed to this target. List existing deployments with GET .../deployments first to check.

Step 7: List MCP Server Instances

Lists MCP server instances in the selected environment by filtering with family=agentic. Use this step when you already have an API Manager instance for the MCP server and need to find its ID to apply a policy.

$ curl -X GET ${baseUrl}/organizations/{organizationId}/environments/{environmentId}/apis?family=agentic \
  -H "Authorization: Bearer ${authToken}" \
  -H "Content-Type: application/json"
Captured Variables
environmentApiId $.assets[*].apis[*].id

What happens next: You have the MCP server instance ID. Next, browse the policy catalog to select which policy to apply.

Step 8: Browse Exchange Policy Catalog

List all available policy templates from Exchange for your organization. This endpoint returns the full Exchange coordinates (groupId, assetId, assetVersion) and gateway-compatible configuration for each template — these are required when applying a policy.

Important: Use the api-portal-xapi endpoint (getExchangePolicyTemplates) instead of the generic listOrganizationsPolicytemplates endpoint. The generic endpoint does not return Exchange coordinates or gateway-specific configuration property names, which are required for the apply step.

api-portal-xapi.getExchangePolicyTemplates
$ curl -X GET ${baseUrl}/apimanager/xapi/v1/organizations/{organizationId}/exchange-policy-templates?apiInstanceId=${environmentApiId}&environmentId=${environmentId}&latest=true&includeConfiguration=true \
  -H "Authorization: Bearer ${authToken}" \
  -H "Content-Type: application/json"
Captured Variables
policyGroupId $[*].groupId
policyAssetId $[*].assetId
policyAssetVersion $[*].version
policyConfiguration $[*].configuration

What happens next: You have the policy template's Exchange coordinates and its configuration schema with the correct property names for your gateway type. Review the policyConfiguration output to understand what settings the policy accepts before applying it.

Common issues:

  • Empty list: Pass apiInstanceId and environmentId to get templates compatible with your gateway type. Without these filters, some templates may not appear.
  • Wrong config property names: Always use the configuration from this endpoint — the generic listOrganizationsPolicytemplates endpoint may return different (non-gateway-compatible) property names and defaults.

Step 9: Apply Policy to API Instance

Apply the selected policy to your MCP server instance with the appropriate configuration. Use the Exchange coordinates and configuration property names from Step 8.

$ curl -X POST ${baseUrl}/organizations/{organizationId}/environments/{environmentId}/apis/{environmentApiId}/policies \
  -H "Authorization: Bearer ${authToken}" \
  -H "Content-Type: application/json"
Captured Variables
policyId $.id

What happens next: Your MCP server is now protected with the selected policy. Since the API instance was configured with deployment information in Step 6, the policy is active and enforcing on the Flex Gateway.

Common issues:

  • 400 Bad Request — missing groupId/assetId/assetVersion: The apply endpoint requires full Exchange coordinates, not just a template ID. Make sure you used getExchangePolicyTemplates (Step 8) to get these values.
  • 400 Bad Request — invalid configurationData: The configuration property names differ between gateway types. Use the property names from Step 8's policyConfiguration output, not from the generic template endpoint. For example, Flex Gateway uses credentialsOriginHasHttpBasicAuthenticationHeader while the generic template uses credentialsOrigin.
  • 409 Conflict: A policy of this type may already be applied to the API instance. List existing policies first to check, or add ?allowDuplicated=true to the request URL to apply a second instance of the same policy type.
  • 403 Forbidden: You need Manage Policies permission in the target environment.

Completion Checklist

After completing all steps, verify:

  • [ ] MCP server instance is bound to the Flex Gateway target (deployment info visible in API Manager)
  • [ ] Policy appears in the API instance's policy list
  • [ ] Policy status shows as "Active"
  • [ ] MCP server requests are being evaluated against the policy rules
  • [ ] Policy configuration matches your requirements

What You've Built

Your MCP server is now protected with:

  • Policy enforcement — Selected policy is active on your MCP server instance. All incoming traffic is evaluated against policy rules.
  • Bound to Flex Gateway — API instance is created with deployment configuration targeting a self-managed Flex Gateway. The Flex Gateway picks up the configuration automatically.
  • Managed configuration — Policy settings are version-controlled in API Manager. Configuration can be updated without redeploying the MCP server.

Next Steps

  1. Test the policy

    • Send test requests to verify the policy is enforcing correctly
    • Check that authorized requests pass and unauthorized ones are blocked
  2. Add more policies

    • Run this skill again to layer additional policies (e.g., rate limiting + OAuth2)
    • Policy ordering matters — adjust priority in API Manager if needed
  3. Monitor policy activity

    • Check API Manager analytics for policy enforcement metrics
    • Set up alerts for unusual rejection patterns

Tips and Best Practices

Policy Selection

  • Rate Limiting: Use when you need to control traffic volume per client
  • OAuth 2.0: Use for token-based authentication and authorization
  • IP Allowlist/Blocklist: Use to restrict access by network origin
  • Client ID Enforcement: Use to require registered client applications

Policy Ordering

  • Authentication policies should be applied first (lowest order number)
  • Rate limiting should come after authentication
  • Transformation policies should be last

Gateway Compatibility

  • Always use getExchangePolicyTemplates with apiInstanceId to get gateway-compatible templates
  • Configuration property names and defaults vary by gateway type (Flex Gateway vs. Mule Gateway)
  • The Exchange template version may differ from the generic template version

MCP Server Discovery

  • The Exchange search in Step 2 is not org-scoped — it returns all MCP servers visible to the authenticated user
  • Use the asset name field to identify the correct MCP server when multiple results are returned
  • If you published the MCP server in Step 1, its coordinates are already available — Step 2 can be used to confirm

Troubleshooting

Policy Not Enforcing

Symptoms: Requests pass through without policy evaluation

Possible causes:

  • API instance is not deployed or is in an error state
  • Policy configuration has a permissive default that allows all traffic
  • Policy is applied but not yet propagated (wait 1-2 minutes)

Solutions:

  • Check API instance status in API Manager
  • Review policy configuration for overly permissive settings
  • Wait for propagation and retry

Policy Blocks All Requests

Symptoms: All requests return 401 or 403, even legitimate ones

Possible causes:

  • Policy configuration is too restrictive
  • Required credentials are not being sent correctly
  • Policy expects headers or parameters in a specific format

Solutions:

  • Review the policy configuration schema for required fields
  • Check that client applications are sending credentials in the expected format
  • Temporarily disable the policy to isolate the issue

400 Error When Applying Policy

Symptoms: "The policy to be created is missing at least one of the following properties related to the policy template: 'groupId', 'assetId', 'assetVersion'."

Possible causes:

  • Used the generic listOrganizationsPolicytemplates endpoint which does not return Exchange coordinates

Solutions:

  • Use getExchangePolicyTemplates from api-portal-xapi instead — this returns the full Exchange coordinates needed by the apply endpoint

MCP Server Not Found in Exchange

Symptoms: Step 2 returns an empty list

Possible causes:

  • The MCP server has not been published to Exchange yet
  • The asset type is not mcp

Solutions:

  • Start from Step 1 to publish the MCP server to Exchange first
  • Verify the asset was published with the correct type