Kong / Kong/developer.konghq.com

Create a how-to for using JSON Threat policy with AI MCP Server

Open Beginner friendly
#6,805 0 comments 0 reactions 0 assignees View on GitHub
internal priority: low
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.