[BUG] MCP array parameters still double-stringified in Notion tool calls (regression from #3023)
Status Fixed / completed
Maintainer reply None cached
Workaround ✓ Mentioned in thread ↓
Activity 5 comments · opened Feb 13, 2026 · closed Feb 27, 2026
Description
Issue #3023 (closed July 2025, fixed in v1.0.53) addressed double-stringification of parent object parameters in Notion-MCP tool calls. However, the same serialization bug persists for array parameters, specifically the children parameter in API-patch-block-children.
Steps to Reproduce
- Configure
@notionhq/notion-mcp-serverv2.1.0 in Claude Code (local stdio) - Create a Notion page (via curl or any method)
- Use Claude Code to call
mcp__notion__API-patch-block-childrenwith:
{
"block_id": "<page_id>",
"children": [
{"type": "paragraph", "paragraph": {"rich_text": [{"type": "text", "text": {"content": "Hello"}}]}}
]
}
Expected Behavior
Notion API receives children as a JSON array and creates the blocks.
Actual Behavior
Notion API receives children as a string (JSON-stringified array):
body.children should be an array, instead was "[{\"type\":\"paragraph\",...".
Environment
- Claude Code: v2.1.34
- OS: Windows 11 Pro (10.0.26200)
- @notionhq/notion-mcp-server: v2.1.0
- Notion API version: 2025-09-03
- Transport: stdio (local, not remote/web connector)
Analysis
The fix from #3023 appears to have addressed object-type parameters (like parent) but not array-type parameters (like children). The MCP transport layer still stringifies arrays before passing them to the server.
Pattern observed:
- Simple objects (
filter: {property: "object", value: "data_source"}) → WORKS - Flat nested objects (
properties: {Status: {status: {name: "Done"}}}) → WORKS - Deep nested objects (
parent: {database_id: "..."}) → Previously BROKEN, supposedly fixed - Arrays of objects (
children: [{type: "paragraph", ...}]) → STILL BROKEN
Workaround
Bypass MCP and call the Notion API directly via HTTP (Python urllib.request, curl, etc.).
Related Issues
- makenotion/notion-mcp-server#82 (open, 16 upvotes — same serialization pattern)
- makenotion/notion-mcp-server#79 (closed as "Claude's issue")
- #3023 (closed, but regression persists for array params)
5 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Root Cause Update (Feb 2026)
The root cause has been identified by @gogakoreli in #18260:
The MCP TypeScript SDK's
schemaToJson()does not resolve$refpointers.When a tool's parameter schema uses
$ref(which Notion's API schema does extensively), the type information is lost at the client layer, and the value is serialized as a string instead of being passed as the correct type.Fix submitted upstream:
dereferenceLocalRefs())This is not a duplicate of the server-side issues — it's the client-side root cause that affects ALL MCP servers using
$refin their schemas (Notion, Webflow, GitHub, custom servers).Request to Anthropic: Please either adopt the SDK fix or add client-side
$refresolution in Claude Code. This affects multiple MCP integrations across Windows, macOS, and Claude Desktop (Cowork).Related: #18260 (master issue), #22394 (Webflow), #24599 (all non-string types), #26094 (Claude Desktop Cowork)
Update: Notion Deployed Partial Fix (2026-02-24)
Notion Support (ticket #5172415) notified us that a fix was deployed. Verification reveals it's partial:
What's Fixed
API-patch-block-childrennow works correctly via MCP — thechildrenparameter schema is properly typed with$refresolution toblockObjectRequestWhat's Still Broken
API-post-pagewithchildrenparameter — still fails withbody.children should be an array or undefined, instead was stringpost-page.childrenusesitems: {"type": "string"}instead ofitems: {"$ref": "#/$defs/blockObjectRequest"}$refresolution issue described in this ticket — unresolved refs fall back tostringtypeImplication
This confirms the bug is real and affects multiple endpoints independently. The Notion team fixed
patch-block-childrenbut missedpost-page— likely because each endpoint's schema needs separate$refresolution.The upstream SDK fix (modelcontextprotocol/typescript-sdk#1563) remains the correct systemic solution, as it would resolve
$refpointers client-side for ALL endpoints at once, rather than requiring server-by-server, endpoint-by-endpoint fixes.Please do not auto-close this issue as duplicate. The evidence above demonstrates this is an active, partially-unresolved bug affecting the MCP client's JSON Schema handling.
Final Status: All Core Functionality Restored (2026-02-27)
Automated Verification Results
| Endpoint + Param | Schema | Runtime | Status |
|------------------|:------:|:-------:|--------|
|
API-post-page—parent| ✅ | ✅ | Fixed (double-serialization resolved) ||
API-post-page—properties| ✅ | ✅ | Fixed ||
API-post-page—children(block objects) | ❌string| ✅ Works | Functional fix (schema cosmetic) ||
API-patch-block-children| ✅$ref| ✅ | Fully fixed ||
API-patch-page| ✅ | ✅ | Working |Key Finding
\
API-post-page\with \children\as actual block objects (not JSON strings) works correctly despite the schema declaring \items: {\"type\": \"string\"}\. The fix was applied at the server's serialization layer — objects pass through without schema validation.Result: Single-call page + content creation is now possible. The \
curl\/\urllib\workaround from the original report is no longer needed.Remaining: Cosmetic Schema Issue
\
children\in \API-post-page\schema still uses \items: {\"type\": \"string\"}\instead of \\$ref: blockObjectRequest\. This doesn't block functionality but causes misleading documentation for tool consumers and potential validation failures in strict MCP clients.Upstream fix: modelcontextprotocol/typescript-sdk#1563 — adds \
dereferenceLocalRefs()\to \schemaToJson()\. Still an open PR, not yet merged.Cross-References
@mieubrisse/notion-mcp-server\Closing — primary functionality fully restored.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.