Summary
When an APIM-MCP server (created from an OpenAPI-imported REST API) receives
tools/call with a JSON object arguments payload, the gateway forwards
only one field's raw value as the backend HTTP body — not the assembled
JSON object. The result is a last-write-wins byte-string body, which
backends correctly reject as malformed JSON.
This appears related to but distinct from the empty-body bug fixed in
release-service-2026-03
("Resolved issue where MCP POST request bodies were not forwarded to backend APIs").
Symptoms in our case are non-empty but scalar / partial.
Environment
- APIM instance: Developer SKU,
platformVersion: stv2.1, releaseChannel: Preview
- Region:
eastus
- API Version used for management:
2024-06-01-preview
- MCP server: created from OpenAPI 3.1 import (FastAPI-generated spec)
- Backend: FastAPI behind ngrok (verified working when called directly)
- No custom policies attached to the MCP server (default
<base/> only)
- Date observed: 2026-05-08 (~2 months after the March 2026 release notes fix)
Reproduction
OpenAPI snippet (operation finance_customer_create):
"POST /governed/customers": {
"operationId": "finance_customer_create",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CreateCustomerRequest" }
}
}
}
}
Schema
"CreateCustomerRequest": {
"type": "object",
"required": ["name", "email"],
"properties": {
"name": { "type": "string" },
"email": { "type": "string" },
"tier": { "type": "string", "default": "bronze" }
}
}
Call:
curl -X POST https://<apim>.azure-api.net/governed-mcp/mcp \
-H "Ocp-Apim-Subscription-Key: ***" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"financeCustomerCreate",
"arguments":{"name":"AAA","email":"BBB","tier":"CCC"}}}'
Backend (verified via the ngrok request inspector) receives:
POST /governed/customers
Content-Type: application/json
Content-Length: 3
Body: CCC
Expected:
POST /governed/customers
Content-Type: application/json
Body: {"name":"AAA","email":"BBB","tier":"CCC"}
Hypothesis
The fix in release-service-2026-03 for the empty-body case may have replaced
"don't forward anything" with "forward each property in turn into a single
body buffer", overwriting prior content with each property and ending on the
last one. This would explain why public reports between Jul 2025 (Q&A
[4371821](vscode-file://vscode-app/c:/Users/leepete/AppData/Local/Programs/Microsoft%20VS%20Code/034f571df5/resources/app/out/vs/code/electron-browser/workbench/workbench.html)) and Oct 2025
(Q&A [5597117](vscode-file://vscode-app/c:/Users/leepete/AppData/Local/Programs/Microsoft%20VS%20Code/034f571df5/resources/app/out/vs/code/electron-browser/workbench/workbench.html)) showed
zero-length bodies, while our post-March-2026 instance shows
short scalar bodies.
Workaround tested (does not work)
Attaching the unwrap policy from
[Q&A 5597117](vscode-file://vscode-app/c:/Users/leepete/AppData/Local/Programs/Microsoft%20VS%20Code/034f571df5/resources/app/out/vs/code/electron-browser/workbench/workbench.html):
… at the MCP-server policy level breaks even tools/list and GET ops with
500s. APIM-MCP's own JSON-RPC parser appears to consume the same body stream
upstream of the policy chain.
Ask
Has the release-service-2026-03 fix landed for Developer SKU / stv2.1 /
eastus yet? Is there a way to verify the deployed gateway build for an
instance via ARM?
Is the schema shape (typed $ref, multiple required, one property with
default) the trigger?
Is there a known workaround that works on v1-tier MCP servers today, or is
the right action to wait / migrate to a v2 SKU?
Summary
When an APIM-MCP server (created from an OpenAPI-imported REST API) receives
tools/callwith a JSON objectargumentspayload, the gateway forwardsonly one field's raw value as the backend HTTP body — not the assembled
JSON object. The result is a
last-write-winsbyte-string body, whichbackends correctly reject as malformed JSON.
This appears related to but distinct from the empty-body bug fixed in
release-service-2026-03("Resolved issue where MCP POST request bodies were not forwarded to backend APIs").
Symptoms in our case are non-empty but scalar / partial.
Environment
platformVersion: stv2.1,releaseChannel: Previeweastus2024-06-01-preview<base/>only)Reproduction
OpenAPI snippet (operation
finance_customer_create):