Kong / Kong/developer.konghq.com
Create a how-to for using JSON Threat policy with AI MCP Server
- Dominant language
- Ruby
- Stars
- 28
- Forks
- 121
- Avg merge
- 1d 4h
- Merged PRs (30d)
- 313
Description
We can swap the cards API MCP with a petstore MCP for easier UX:
---
title: Use JSON Threat Protection Policy to protect an AI MCP Server
permalink: /ai-gateway/use-json-threat-protection-policy/
content_type: how_to
description: Use the JSON Threat Protection Policy to reject oversized or overly complex JSON-RPC requests to an AI MCP Server
products:
- ai-gateway
works_on:
- konnect
min_version:
ai-gateway: '2.0'
entities:
- ai-mcp-server
- ai-policy
tags:
- ai
- mcp
- security
tldr:
q: How do I protect an AI MCP Server from oversized or malicious JSON-RPC payloads?
a: |
Attach the [JSON Threat Protection](/ai-gateway/policies/json-threat-protection/) Policy to an [AI MCP Server](/ai-gateway/entities/ai-mcp-server/) to reject requests that exceed configured limits on JSON depth, array size, object entries, key length, string length, and body size.
tools:
- kongctl
related_resources:
- text: AI MCP Server entity
url: /ai-gateway/entities/ai-mcp-server/
- text: JSON Threat Protection
url: /ai-gateway/policies/json-threat-protection/
cleanup:
inline:
- title: Clean up {{site.ai_gateway}} resources
include_content: cleanup/products/ai-gateway
---
## Create an AI MCP Server and attach the JSON Threat Protection Policy
Create the [JSON Threat Protection](/ai-gateway/policies/json-threat-protection/) Policy and an [AI MCP Server](/ai-gateway/entities/ai-mcp-server/) that exposes the [Deck of Cards API](https://deckofcardsapi.com/) as MCP tools, with the Policy attached:
{% entity_examples %}
ai_gateway_policies:
- ref: json-threat-protection-cards
name: json-threat-protection-cards
ai_gateway: !lookup name:ai-quickstart
type: json-threat-protection
enabled: true
global: false
config:
max_container_depth: 3
max_array_element_count: 3
max_object_entry_count: 5
max_object_entry_name_length: 20
max_string_value_length: 40
enforcement_mode: block
ai_gateway_mcp_servers:
- ref: cards-mcp
ai_gateway: !lookup name:ai-quickstart
name: cards-mcp
display_name: "Deck of Cards"
type: conversion-listener
enabled: true
policies: [ !ref json-threat-protection-cards#name ]
config:
url: https://deckofcardsapi.com
route:
paths:
- /api/deck
strip_path: false
tools:
- name: shuffle-cards
description: Shuffle a new deck of cards. Returns a deck_id to use with draw-cards.
method: GET
path: /api/deck/new/shuffle/
parameters:
- name: deck_count
in: query
required: false
schema:
type: integer
default: 1
description: Number of decks to use (default 1, blackjack typically uses 6)
- name: draw-cards
description: Draw cards from an existing deck. Requires a deck_id from shuffle-cards.
method: GET
path: "/api/deck/{deck_id}/draw/"
parameters:
- name: deck_id
in: path
required: true
schema:
type: string
description: Deck ID returned from shuffle-cards
- name: count
in: query
required: true
schema:
type: integer
default: 1
description: Number of cards to draw
{% endentity_examples %}
## Validate
### Open a session
Send an `initialize` request to the route configured on the AI MCP Server (`/api/deck`), capturing the `Mcp-Session-Id` response header into an environment variable:
```sh
SESSION_ID=$(curl -s -o /dev/null -D - -X POST http://localhost:8000/api/deck \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
--data '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {
"name": "cards-mcp-test",
"version": "1.0.0"
}
}
}' | grep -i '^mcp-session-id:' | tr -d '\r' | cut -d' ' -f2)
export SESSION_ID
echo "SESSION_ID=$SESSION_ID"
```
Complete the handshake with a `notifications/initialized` notification, carrying the session ID:
```sh
curl -i -X POST http://localhost:8000/api/deck \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H "Mcp-Session-Id: $SESSION_ID" \
--data '{"jsonrpc":"2.0","method":"notifications/initialized"}'
```
A `202 Accepted` response confirms the session is ready.
### Call a tool with valid arguments
Shuffle a new deck:
```sh
curl -X POST http://localhost:8000/api/deck \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H "Mcp-Session-Id: $SESSION_ID" \
--data '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "shuffle-cards",
"arguments": {"query_deck_count": 1}
}
}'
```
```text
event: message
data: {"result":{"content":[{"type":"text","text":"{\"success\": true, \"deck_id\": \"t8952axdsfat\", \"remaining\": 52, \"shuffled\": true}"}],"isError":false},"id":2,"jsonrpc":"2.0"}
```
{:.no-copy-code}
Draw a card using the `deck_id` from the response:
```sh
curl -X POST http://localhost:8000/api/deck \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H "Mcp-Session-Id: $SESSION_ID" \
--data '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "draw-cards",
"arguments": {"path_deck_id": "t8952axdsfat", "query_count": 1}
}
}'
```
The request succeeds and returns a drawn card.
### Call a tool with an oversized argument
Substitute an oversized value for `path_deck_id` instead of a real deck ID:
```sh
curl -i -X POST http://localhost:8000/api/deck \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H "Mcp-Session-Id: $SESSION_ID" \
--data '{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "draw-cards",
"arguments": {"path_deck_id": "deck-id-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "query_count": 1}
}
}'
```
The request fails with `400 Bad Request`, since `path_deck_id` is 88 characters long and exceeds `config.max_string_value_length`.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start from the proposed how-to at /ai-gateway/use-json-threat-protection-policy/ and review its front matter, AI MCP Server example, and validation curl commands. Verify the linked JSON Threat Protection and AI MCP Server resources, then confirm the walkthrough demonstrates valid calls and rejection of an oversized argument.
Written by the indexing model from the issue text.
Assessment
- Domain
- documentation, security
- Issue type
- Documentation
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 85/100