Skip to content

Python: fix(python): treat any MCP ping JSON-RPC error as unsupported, not just -32601 - #7656

Open
Diego Casati (dcasati) wants to merge 1 commit into
microsoft:mainfrom
dcasati:fix/mcp-ping-treat-any-jsonrpc-error-as-unsupported
Open

Python: fix(python): treat any MCP ping JSON-RPC error as unsupported, not just -32601#7656
Diego Casati (dcasati) wants to merge 1 commit into
microsoft:mainfrom
dcasati:fix/mcp-ping-treat-any-jsonrpc-error-as-unsupported

Conversation

@dcasati

Copy link
Copy Markdown

Hi,

MCPTool._ensure_connected() used a periodic ping as a connection health check.

When the server rejected ping with an McpError, the code only treated error code -32601 ("Method not found", the JSON-RPC-spec-correct code for an unimplemented method) as "ping unsupported, keep using this connection". Any other error code fell through to a reconnect attempt.

It seems like some real-world MCP servers (like the Microsoft Fabric's Data Agent MCP endpoint) reject an unsupported ping with a different code (-32600 "Invalid Request") instead. Since that server only implements initialize, notifications/initialized, tools/list, and tools/call, every single tool call triggered this same failed-ping path, and instead of just disabling future pings, the client attempted an unnecessary reconnect. That reconnect can itself fail in ways unrelated to the original (harmless) ping rejection, breaking an otherwise fully working MCP tool.

Any well-formed JSON-RPC error response to ping - regardless of its specific error code - already proves the connection is alive: the server received the request and replied. It just means the server doesn't support (or accept) the optional ping method.

This change treats any McpError from send_ping() the same way: disable future pings and continue using the existing connection, without attempting a reconnect. Only non-McpError exceptions (timeouts, transport/connection failures) -- where we genuinely don't know if the server is still reachable -- still trigger a reconnect, unchanged from before.

Added a regression test (nonstandard error code -32600) alongside the existing -32601 test to cover this.

Motivation & Context

Description & Review Guide

  • What are the major changes?
  • What is the impact of these changes?
  • What do you want reviewers to focus on?

Related Issue

Fixes #

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR is linked to an issue and there is no other open PR for this issue (see Related Issue above).
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.

…st -32601

MCPTool._ensure_connected() used a periodic `ping` as a connection health
check. When the server rejected `ping` with an McpError, the code only
treated error code -32601 ("Method not found", the JSON-RPC-spec-correct
code for an unimplemented method) as "ping unsupported, keep using this
connection". Any other error code fell through to a reconnect attempt.

Some real-world MCP servers -- e.g. Microsoft Fabric's Data Agent MCP
endpoint -- reject an unsupported `ping` with a different code (-32600
"Invalid Request") instead. Since that server only implements initialize,
notifications/initialized, tools/list, and tools/call, every single tool
call triggered this same failed-ping path, and instead of just disabling
future pings, the client attempted an unnecessary reconnect. That reconnect
can itself fail in ways unrelated to the original (harmless) ping
rejection, breaking an otherwise fully working MCP tool.

Any well-formed JSON-RPC error response to ping -- regardless of its
specific error code -- already proves the connection is alive: the server
received the request and replied. It just means the server doesn't
support (or accept) the optional ping method. This change treats any
McpError from send_ping() the same way: disable future pings and continue
using the existing connection, without attempting a reconnect. Only
non-McpError exceptions (timeouts, transport/connection failures) --
where we genuinely don't know if the server is still reachable -- still
trigger a reconnect, unchanged from before.

Added a regression test (nonstandard error code -32600) alongside the
existing -32601 test to cover this.
Copilot AI balanced review requested due to automatic review settings August 13, 2026 20:53
@agent-framework-automation agent-framework-automation Bot added the python Usage: [Issues, PRs], Target: Python label Aug 13, 2026
@github-actions github-actions Bot changed the title fix(python): treat any MCP ping JSON-RPC error as unsupported, not just -32601 Python: fix(python): treat any MCP ping JSON-RPC error as unsupported, not just -32601 Aug 13, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates MCP connection health checks to treat any JSON-RPC ping error as evidence of a live connection.

Changes:

  • Disables future pings after any McpError.
  • Retains reconnect behavior for transport and other non-MCP failures.
  • Adds regression coverage for error code -32600.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
python/packages/core/agent_framework/_mcp.py Broadens unsupported-ping handling.
python/packages/core/tests/core/test_mcp.py Tests nonstandard ping error handling.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

@github-actions

Copy link
Copy Markdown
Contributor

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/core/agent_framework
   _mcp.py138611092%254, 260, 369, 388, 609, 688–689, 803, 828, 879, 994, 997, 1007, 1011, 1058–1059, 1064, 1071–1072, 1079, 1084–1085, 1092–1093, 1097, 1102–1103, 1112, 1119–1120, 1138, 1151, 1175–1176, 1195–1198, 1200–1201, 1205, 1231, 1265–1267, 1269, 1323–1325, 1384–1385, 1668, 1709–1710, 1723, 1726, 1735–1736, 1741–1742, 1748, 1802–1803, 1823–1824, 1833–1834, 1839–1840, 1846, 1939, 1942, 1969, 2029–2031, 2036, 2040–2041, 2143, 2150, 2152, 2223, 2238–2239, 2246–2247, 2252–2253, 2258, 2262, 2277, 2339, 2522, 2524, 2546, 2548–2551, 2564–2565, 2609, 2671, 3110–3111, 3156, 3376–3377, 3395
TOTAL45957425390% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
9358 36 💤 0 ❌ 0 🔥 2m 8s ⏱️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants