server: skip duplicate response on CancelledError#1153
server: skip duplicate response on CancelledError#1153ihrpr merged 9 commits intomodelcontextprotocol:mainfrom
Conversation
When a tool call is cancelled, RequestResponder.cancel() sends an error response. Previously, _handle_request would try to send another error response, causing "Request already responded to" assertion. This fix catches CancelledError and returns early, preventing the duplicate response. Fixes modelcontextprotocol#1152
ihrpr
left a comment
There was a problem hiding this comment.
Thanks for woking on the fix! Left some comments
tests/server/test_cancel_handling.py
Outdated
There was a problem hiding this comment.
There is a lot of mocking happening. I'd suggest to use test_integration or leverage create_connected_server_and_client_session and test with CancelledNotification
There was a problem hiding this comment.
Fixed, thanks for the directions!
- Use anyio.get_cancelled_exc_class() instead of asyncio.CancelledError for proper backend compatibility (supports both asyncio and trio) - Rewrote cancel handling tests to use integration testing pattern with create_connected_server_and_client_session instead of mocking - Tests now properly send CancelledNotification messages through real client-server communication - Added proper type annotations and fixed type issues in tests Addresses review feedback about using anyio idioms and integration testing. Reported-by: @ihrpr
89075b0 to
a5a112a
Compare
ihrpr
left a comment
There was a problem hiding this comment.
Thanks for the quick turnaround, I think we can remove test_cancelled_request_no_double_response test. wdyt?
tests/server/test_cancel_handling.py
Outdated
|
|
||
|
|
||
| @pytest.mark.anyio | ||
| async def test_cancelled_request_no_double_response(): |
There was a problem hiding this comment.
why do we need this test? it doesn't look like it's testing much and test_server_remains_functional_after_cancel looks complete to cover the fix?
ihrpr
left a comment
There was a problem hiding this comment.
Thank you
(I removed the test mentioned in comments as test_server_remains_functional_after_cancel already covers the change)
* Add regression test for stateless request memory cleanup (modelcontextprotocol#1140) * Implement RFC9728 - Support WWW-Authenticate header by MCP client (modelcontextprotocol#1071) * Add streamable HTTP starlette example to Python SDK docs (modelcontextprotocol#1111) * fix markdown error in README in main (modelcontextprotocol#1147) * README - replace code snippets with examples - add lowlevel to snippets (modelcontextprotocol#1150) * README - replace code snippets with examples - streamable http (modelcontextprotocol#1155) * chore: don't allow users to create issues outside the templates (modelcontextprotocol#1163) * Tests(cli): Add coverage for helper functions (modelcontextprotocol#635) * Docs: Update CallToolResult parsing in README (modelcontextprotocol#812) Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> * docs: add pre-commit install guide on CONTRIBUTING.md (modelcontextprotocol#995) Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> * fix flaky fix-test_streamablehttp_client_resumption test (modelcontextprotocol#1166) * README - replace code snippets with examples -- auth examples (modelcontextprotocol#1164) * Support falling back to OIDC metadata for auth (modelcontextprotocol#1061) * Add CODEOWNERS file for sdk (modelcontextprotocol#1169) * fix flaky test test_88_random_error (modelcontextprotocol#1171) * Make sure `RequestId` is not coerced as `int` (modelcontextprotocol#1178) * Fix: Replace threading.Lock with anyio.Lock for Ray deployment compatibility (modelcontextprotocol#1151) * fix: fix OAuth flow request object handling (modelcontextprotocol#1174) * update codeowners group (modelcontextprotocol#1191) * fix: perform auth server metadata discovery fallbacks on any 4xx (modelcontextprotocol#1193) * server: skip duplicate response on CancelledError (modelcontextprotocol#1153) Co-authored-by: ihrpr <inna@anthropic.com> * Unpack settings in FastMCP (modelcontextprotocol#1198) * chore: Remove unused prompt_manager.py file (modelcontextprotocol#1229) Co-authored-by: Tapan Chugh <tapanc@cs.washington.edu> * Improved supported for ProtectedResourceMetadata (modelcontextprotocol#1235) Co-authored-by: Paul Carleton <paulcarletonjr@gmail.com> * chore: Remove unused variable notification_options (modelcontextprotocol#1238) * Improve README around the Context object (modelcontextprotocol#1203) * fix: allow to pass `list[str]` to `token_endpoint_auth_signing_alg_values_supported` (modelcontextprotocol#1226) * Remove strict validation on `response_modes_supported` member of `OAuthMetadata` (modelcontextprotocol#1243) * Add pyright strict mode on the whole project (modelcontextprotocol#1254) * Consistent casing for default headers Accept and Content-Type (modelcontextprotocol#1263) * Update dependencies and fix type issues (modelcontextprotocol#1268) Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com> * fix: prevent async generator cleanup errors in StreamableHTTP transport (modelcontextprotocol#1271) Co-authored-by: David Soria Parra <167242713+dsp-ant@users.noreply.github.com> * chore: uncomment .idea/ in .gitignore (modelcontextprotocol#1287) Co-authored-by: Claude <noreply@anthropic.com> * docs: clarify streamable_http_path configuration when mounting servers (modelcontextprotocol#1172) * feat: Add CORS configuration for browser-based MCP clients (modelcontextprotocol#1059) Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com> Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> * Added Audio to FastMCP (modelcontextprotocol#1130) * fix: avoid uncessary retries in OAuth authenticated requests (modelcontextprotocol#1206) Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> * Add PATHEXT to default STDIO env vars in windows (modelcontextprotocol#1256) * fix: error too many values to unpack (expected 2) (modelcontextprotocol#1279) Signed-off-by: San Nguyen <vinhsannguyen91@gmail.com> Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * SDK Parity: Avoid Parsing Server Response for non-JsonRPCMessage Requests (modelcontextprotocol#1290) * types: Setting default value for method: Literal (modelcontextprotocol#1292) * changes structured temperature to not deadly (modelcontextprotocol#1328) * Update simple-resource example to use non-deprecated read_resource return type (modelcontextprotocol#1331) Co-authored-by: Claude <noreply@anthropic.com> * docs: Update README to include link to API docs for modelcontextprotocol#1329 (modelcontextprotocol#1330) * Allow ping requests before initialization (modelcontextprotocol#1312) * Python lint: Ruff rules for pylint and code complexity (modelcontextprotocol#525) * Fix context injection for resources and prompts (modelcontextprotocol#1336) * fix(fastmcp): propagate mimeType in resource template list (modelcontextprotocol#1186) Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * fix: allow elicitations accepted without content (modelcontextprotocol#1285) Co-authored-by: Olivier Schiavo <olivier.schiavo@wengo.com> * Use --frozen in pre-commit config (modelcontextprotocol#1375) * Return HTTP 403 for invalid Origin headers (modelcontextprotocol#1353) * Add test for ProtectedResourceMetadataParsing (modelcontextprotocol#1236) Co-authored-by: Paul Carleton <paulcarletonjr@gmail.com> Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * Fastmcp logging progress example (modelcontextprotocol#1270) Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * feat: add paginated list decorators for prompts, resources, and tools (modelcontextprotocol#1286) Co-authored-by: Claude <noreply@anthropic.com> * Remove "unconditionally" from conditional description (modelcontextprotocol#1289) * Use streamable-http consistently in examples (modelcontextprotocol#1389) * feat: Add SDK support for SEP-1034 default values in elicitation schemas (modelcontextprotocol#1337) Co-authored-by: Tapan Chugh <tapanc@cs.washington.edu> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * Implementation of SEP 973 - Additional metadata + icons support (modelcontextprotocol#1357) * Merge upstream/main with custom filtering --------- Signed-off-by: San Nguyen <vinhsannguyen91@gmail.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> Co-authored-by: yurikunash <143175350+yurikunash@users.noreply.github.com> Co-authored-by: Pamela Fox <pamela.fox@gmail.com> Co-authored-by: Inna Harper <inna.hrpr@gmail.com> Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com> Co-authored-by: Ian Davenport <49379192+davenpi@users.noreply.github.com> Co-authored-by: Dagang Wei <functicons@gmail.com> Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> Co-authored-by: Stanley Law <stanleylkal@gmail.com> Co-authored-by: Luca Chang <131398524+LucaButBoring@users.noreply.github.com> Co-authored-by: leweng <leweng@nvidia.com> Co-authored-by: Clare Liguori <liguori@amazon.com> Co-authored-by: lukacf <luka@peltarion.com> Co-authored-by: ihrpr <inna@anthropic.com> Co-authored-by: Tapan Chugh <chugh.tapan@gmail.com> Co-authored-by: Tapan Chugh <tapanc@cs.washington.edu> Co-authored-by: Yann Jouanin <4557670+yannj-fr@users.noreply.github.com> Co-authored-by: Paul Carleton <paulcarletonjr@gmail.com> Co-authored-by: Sreenath Somarajapuram <somarajapuram@gmail.com> Co-authored-by: Omer Korner <omerkorner@gmail.com> Co-authored-by: joesavage-silabs <159480754+joesavage-silabs@users.noreply.github.com> Co-authored-by: Gregory L <gregory.linford@mistral.ai> Co-authored-by: David Soria Parra <167242713+dsp-ant@users.noreply.github.com> Co-authored-by: Moustapha Ebnou <155577789+mous222@users.noreply.github.com> Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Jerome <jerome@anthropic.com> Co-authored-by: xavier <84836280+dragonier23@users.noreply.github.com> Co-authored-by: keurcien <keurcien.luu@gmail.com> Co-authored-by: Tim Esler <tim.esler@gmail.com> Co-authored-by: San Nguyen <22189661+sandangel@users.noreply.github.com> Co-authored-by: Justin Wang <89049861+justin-yi-wang@users.noreply.github.com> Co-authored-by: jess <jessachandler@gmail.com> Co-authored-by: Peter Alexander <pja@anthropic.com> Co-authored-by: Reid Geyer <12072650+reidg44@users.noreply.github.com> Co-authored-by: Eleftheria Stein-Kousathana <eleftheria.kousathana@gmail.com> Co-authored-by: Christian Clauss <cclauss@me.com> Co-authored-by: pchoudhury22 <pchoudhury22@apple.com> Co-authored-by: owengo <owengo@users.noreply.github.com> Co-authored-by: Olivier Schiavo <olivier.schiavo@wengo.com> Co-authored-by: Steve Billings <billings.steve@gmail.com> Co-authored-by: Mike Salvatore <mike.s.salvatore@gmail.com>
* Add regression test for stateless request memory cleanup (modelcontextprotocol#1140) * Implement RFC9728 - Support WWW-Authenticate header by MCP client (modelcontextprotocol#1071) * Add streamable HTTP starlette example to Python SDK docs (modelcontextprotocol#1111) * fix markdown error in README in main (modelcontextprotocol#1147) * README - replace code snippets with examples - add lowlevel to snippets (modelcontextprotocol#1150) * README - replace code snippets with examples - streamable http (modelcontextprotocol#1155) * chore: don't allow users to create issues outside the templates (modelcontextprotocol#1163) * Tests(cli): Add coverage for helper functions (modelcontextprotocol#635) * Docs: Update CallToolResult parsing in README (modelcontextprotocol#812) Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> * docs: add pre-commit install guide on CONTRIBUTING.md (modelcontextprotocol#995) Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> * fix flaky fix-test_streamablehttp_client_resumption test (modelcontextprotocol#1166) * README - replace code snippets with examples -- auth examples (modelcontextprotocol#1164) * Support falling back to OIDC metadata for auth (modelcontextprotocol#1061) * Add CODEOWNERS file for sdk (modelcontextprotocol#1169) * fix flaky test test_88_random_error (modelcontextprotocol#1171) * Make sure `RequestId` is not coerced as `int` (modelcontextprotocol#1178) * Fix: Replace threading.Lock with anyio.Lock for Ray deployment compatibility (modelcontextprotocol#1151) * fix: fix OAuth flow request object handling (modelcontextprotocol#1174) * update codeowners group (modelcontextprotocol#1191) * fix: perform auth server metadata discovery fallbacks on any 4xx (modelcontextprotocol#1193) * server: skip duplicate response on CancelledError (modelcontextprotocol#1153) Co-authored-by: ihrpr <inna@anthropic.com> * Unpack settings in FastMCP (modelcontextprotocol#1198) * chore: Remove unused prompt_manager.py file (modelcontextprotocol#1229) Co-authored-by: Tapan Chugh <tapanc@cs.washington.edu> * Improved supported for ProtectedResourceMetadata (modelcontextprotocol#1235) Co-authored-by: Paul Carleton <paulcarletonjr@gmail.com> * chore: Remove unused variable notification_options (modelcontextprotocol#1238) * Improve README around the Context object (modelcontextprotocol#1203) * fix: allow to pass `list[str]` to `token_endpoint_auth_signing_alg_values_supported` (modelcontextprotocol#1226) * Remove strict validation on `response_modes_supported` member of `OAuthMetadata` (modelcontextprotocol#1243) * Add pyright strict mode on the whole project (modelcontextprotocol#1254) * Consistent casing for default headers Accept and Content-Type (modelcontextprotocol#1263) * Update dependencies and fix type issues (modelcontextprotocol#1268) Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com> * fix: prevent async generator cleanup errors in StreamableHTTP transport (modelcontextprotocol#1271) Co-authored-by: David Soria Parra <167242713+dsp-ant@users.noreply.github.com> * chore: uncomment .idea/ in .gitignore (modelcontextprotocol#1287) Co-authored-by: Claude <noreply@anthropic.com> * docs: clarify streamable_http_path configuration when mounting servers (modelcontextprotocol#1172) * feat: Add CORS configuration for browser-based MCP clients (modelcontextprotocol#1059) Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com> Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> * Added Audio to FastMCP (modelcontextprotocol#1130) * fix: avoid uncessary retries in OAuth authenticated requests (modelcontextprotocol#1206) Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> * Add PATHEXT to default STDIO env vars in windows (modelcontextprotocol#1256) * fix: error too many values to unpack (expected 2) (modelcontextprotocol#1279) Signed-off-by: San Nguyen <vinhsannguyen91@gmail.com> Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * SDK Parity: Avoid Parsing Server Response for non-JsonRPCMessage Requests (modelcontextprotocol#1290) * types: Setting default value for method: Literal (modelcontextprotocol#1292) * changes structured temperature to not deadly (modelcontextprotocol#1328) * Update simple-resource example to use non-deprecated read_resource return type (modelcontextprotocol#1331) Co-authored-by: Claude <noreply@anthropic.com> * docs: Update README to include link to API docs for modelcontextprotocol#1329 (modelcontextprotocol#1330) * Allow ping requests before initialization (modelcontextprotocol#1312) * Python lint: Ruff rules for pylint and code complexity (modelcontextprotocol#525) * Fix context injection for resources and prompts (modelcontextprotocol#1336) * fix(fastmcp): propagate mimeType in resource template list (modelcontextprotocol#1186) Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * fix: allow elicitations accepted without content (modelcontextprotocol#1285) Co-authored-by: Olivier Schiavo <olivier.schiavo@wengo.com> * Use --frozen in pre-commit config (modelcontextprotocol#1375) * Return HTTP 403 for invalid Origin headers (modelcontextprotocol#1353) * Add test for ProtectedResourceMetadataParsing (modelcontextprotocol#1236) Co-authored-by: Paul Carleton <paulcarletonjr@gmail.com> Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * Fastmcp logging progress example (modelcontextprotocol#1270) Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * feat: add paginated list decorators for prompts, resources, and tools (modelcontextprotocol#1286) Co-authored-by: Claude <noreply@anthropic.com> * Remove "unconditionally" from conditional description (modelcontextprotocol#1289) * Use streamable-http consistently in examples (modelcontextprotocol#1389) * feat: Add SDK support for SEP-1034 default values in elicitation schemas (modelcontextprotocol#1337) Co-authored-by: Tapan Chugh <tapanc@cs.washington.edu> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * Implementation of SEP 973 - Additional metadata + icons support (modelcontextprotocol#1357) * Add error log for client stdio (modelcontextprotocol#924) Co-authored-by: Your Name <youremail@yourdomain.com> Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * Accept additional response_types values from OAuth servers (modelcontextprotocol#1323) * Issue 1379 patch - Fix MCP server OAuth not working with Visual Studio Code and others with extra grant_types (modelcontextprotocol#1380) * Add comprehensive Unicode tests for streamable HTTP transport (modelcontextprotocol#1381) * Update Icon.sizes to use string array format (modelcontextprotocol#1411) * Delete CODEOWNERS to eliminate notification overload (modelcontextprotocol#1413) * fix: fix the system message in simple-chatbot example (modelcontextprotocol#1394) * fix: improve misleading warning for progress callback exceptions (modelcontextprotocol#775) * fix: catch and rethrow SSEError during SSE connection establishment (modelcontextprotocol#975) Co-authored-by: zhangchuanhui <zhangchal@digitalchina.com> Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> * Add icons support for ResourceTemplate (modelcontextprotocol#1412) * Add documentation structure (modelcontextprotocol#1425) * Add documentation about testing (modelcontextprotocol#1426) * Improve OAuth protected resource metadata URL construction per RFC 9728 (modelcontextprotocol#1407) * feat: add ability to remove tools (modelcontextprotocol#1322) Co-authored-by: David Soria Parra <167242713+dsp-ant@users.noreply.github.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> * Update README to link to Python SDK documentation (modelcontextprotocol#1430) * fix: update CLAUDE.md to remove auto-addition of reviewers. (modelcontextprotocol#1431) * [client] Implement MCP OAuth scope selection and step-up authorization (modelcontextprotocol#1324) * Handles message type Exception in lowlevel/server.py _handle_message function. Mentioned as TODO on line 528. (modelcontextprotocol#786) Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * Fix workspace configuration error with structured_output_lowlevel.py (modelcontextprotocol#1471) Co-authored-by: lorenss-m <saeclmusic@gmail.com> * fix: Remove unnecessary constructor from ResourceServerSettings (modelcontextprotocol#1424) Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * feat: add resource annotations support to FastMCP (modelcontextprotocol#1468) * fix: send params as empty object for list methods without cursor (modelcontextprotocol#1453) * fix: Set the Server session initialization state immediately after respond… (modelcontextprotocol#1478) Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com> * feat: add tool metadata in FastMCP.tool decorator (modelcontextprotocol#1463) Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com> * Make client examples workspaces to reflect package code (modelcontextprotocol#1466) * Expose RequestParams._meta in ClientSession.call_tool (modelcontextprotocol#1231) Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * Allow CallToolResult to be returned directly to support _meta field for OpenAI Apps (modelcontextprotocol#1459) Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com> * fix: uv CVE-2025-62518 astral-tokio-tar issue GHSA-j5gw-2vrg-8fgx (modelcontextprotocol#1505) * fix: use proper dependency resolution in CI (modelcontextprotocol#1507) * Upgrade GitHub Actions (modelcontextprotocol#1473) * test: use errno.ENOENT for command not found assertion (modelcontextprotocol#1498) * Replace deprecated dev-dependencies with dependency-groups (modelcontextprotocol#1488) Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * update uv to 0.9.5 (modelcontextprotocol#1510) * Relax Accept header requirement for JSON-only responses (modelcontextprotocol#1500) * fix: replace deprecated dev-dependencies in examples/clients (modelcontextprotocol#1518) * fix: Update spec links to new modelcontextprotocol.io location (modelcontextprotocol#1491) * fix: Replace fixed sleep with active server readiness check in SSE tests (modelcontextprotocol#1526) * fix: Replace arbitrary sleeps with active server readiness checks in tests (modelcontextprotocol#1527) Co-authored-by: Claude <noreply@anthropic.com> * Fix flaky timeout test in test_88_random_error (modelcontextprotocol#1525) * fix: Replace remaining manual server polling with wait_for_server helper (modelcontextprotocol#1529) * Implement RFC 7523 JWT flows (modelcontextprotocol#1247) Co-authored-by: Yann Jouanin <yann.jouanin@valueandco.com> * Fix pyright error and replace wildcard import with explicit imports (modelcontextprotocol#1532) * Fix auth client example URL handling for oauth provider (modelcontextprotocol#1549) * docs: use article "an" before "MCP" instead of "a" (modelcontextprotocol#1558) * Update Starlette to 0.49.1 in uv.lock (modelcontextprotocol#1559) * Fix typo in `ClientSessionGroup` doc string (modelcontextprotocol#1572) * Implement SEP-985: OAuth Protected Resource Metadata discovery fallback (modelcontextprotocol#1548) Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Paul Carleton <paulc@anthropic.com> * Add --frozen flag to uv run commands in Claude config (modelcontextprotocol#1583) * Add get_server_capabilities() to ClientSession (modelcontextprotocol#1588) * Add everything-server for comprehensive MCP conformance testing (modelcontextprotocol#1587) * Get baseline 100% clean coverage (modelcontextprotocol#1553) * Add end-of-file-fixer pre-commit hook (modelcontextprotocol#1610) * Add coverage baseline commit to git-blame-ignore (modelcontextprotocol#1613) * Add SEP-1034 conformance test support to everything-server (modelcontextprotocol#1604) Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com> * refactor: extract OAuth helper functions and simplify provider state (modelcontextprotocol#1586) * Add client_id_metadata_document_supported to OAuthMetadata (modelcontextprotocol#1603) * Fix OAuth discovery fallback and URL ordering (modelcontextprotocol#1624) * Refactor `func_metadata()` implementation (modelcontextprotocol#1496) * Fix CI highest resolution test to actually test highest versions (modelcontextprotocol#1609) * feat: Pass through and expose additional parameters in `ClientSessionGroup.call_tool` and `.connect_to_server` (modelcontextprotocol#1576) * fix get_client_metadata_scopes on 401 (modelcontextprotocol#1631) Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com> * chore: Lazy import `jsonschema` library (modelcontextprotocol#1596) Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com> * docs: Update examples to use stateless HTTP with JSON responses (modelcontextprotocol#1499) * Add tests for JSON Schema 2020-12 field preservation (SEP-1613) (modelcontextprotocol#1649) * Add client_secret_basic authentication support (modelcontextprotocol#1334) Co-authored-by: Paul Carleton <paulc@anthropic.com> * Implement SEP-1577 - Sampling With Tools (modelcontextprotocol#1594) Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> Co-authored-by: Claude <noreply@anthropic.com> * SEP-1330: Elicitation Enum Schema Improvements and Standards Compliance (modelcontextprotocol#1246) Co-authored-by: Tapan Chugh <tapanc@cs.washington.edu> Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * [auth][conformance] add conformance auth client (modelcontextprotocol#1640) Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * Implement SEP-986: Tool name validation (modelcontextprotocol#1655) * fix: url for spec (modelcontextprotocol#1659) * feat: implement SEP-991 URL-based client ID (CIMD) support (modelcontextprotocol#1652) Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * Update doc string on custom_route (modelcontextprotocol#1660) * Implement SEP-1036: URL mode elicitation for secure out-of-band interactions (modelcontextprotocol#1580) Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> * Skip empty SSE data to avoid parsing errors (modelcontextprotocol#1670) * SEP-1686: Tasks (modelcontextprotocol#1645) * Add on_session_created callback option (modelcontextprotocol#1710) * Add SSE polling support (SEP-1699) (modelcontextprotocol#1654) * Support client_credentials flow with JWT and Basic auth (modelcontextprotocol#1663) Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> * feat: backwards-compatible create_message overloads for SEP-1577 (modelcontextprotocol#1713) * Merge commit from fork * Auto-enable DNS rebinding protection for localhost servers When a FastMCP server is created with host="127.0.0.1" or "localhost" and no explicit transport_security is provided, automatically enable DNS rebinding protection. Both 127.0.0.1 and localhost are allowed as valid hosts/origins since clients may use either to connect. * Add tests for auto DNS rebinding protection on localhost Tests verify that: - Protection auto-enables for host=127.0.0.1 - Protection auto-enables for host=localhost - Both 127.0.0.1 and localhost are in allowed hosts/origins - Protection does NOT auto-enable for other hosts (e.g., 0.0.0.0) - Explicit transport_security settings are not overridden * Add IPv6 localhost (::1) support for DNS rebinding protection Extend auto-enable DNS rebinding protection to also cover IPv6 localhost. When host="::1", protection is now auto-enabled with appropriate allowed hosts ([::1]:*) and origins (http://[::1]:*). * Fix import ordering in test file * chore: update LATEST_PROTOCOL_VERSION to 2025-11-25 (modelcontextprotocol#1715) * fix: add lifespan context manager to StreamableHTTP mounting examples (modelcontextprotocol#1669) Co-authored-by: TheMailmans <tyler@example.com> Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com> * fix: handle ClosedResourceError in StreamableHTTP message router (modelcontextprotocol#1384) Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com> Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com> * fix: skip priming events and close_sse_stream for old protocol versions (modelcontextprotocol#1719) * refactor(auth): remove unused _register_client method (modelcontextprotocol#1748) * [MCP-266] Add tests for Gumloop server extensions * Fix uv workspace config for gumloop-mcp package name * Sync with upstream MCP SDK and fix merge conflicts * Fix tool cache timing and missing properties check in server.py * Fix coverage and add proper type annotations for Gumloop extensions * Version up * Skip README code example tests (Gumloop README has no code snippets) * Support gumloop and mcp outptuschema * Add publish tools to dev dependencies and update README for uv --------- Signed-off-by: San Nguyen <vinhsannguyen91@gmail.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com> Co-authored-by: yurikunash <143175350+yurikunash@users.noreply.github.com> Co-authored-by: Pamela Fox <pamela.fox@gmail.com> Co-authored-by: Inna Harper <inna.hrpr@gmail.com> Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com> Co-authored-by: Ian Davenport <49379192+davenpi@users.noreply.github.com> Co-authored-by: Dagang Wei <functicons@gmail.com> Co-authored-by: Felix Weinberger <fweinberger@anthropic.com> Co-authored-by: Stanley Law <stanleylkal@gmail.com> Co-authored-by: Luca Chang <131398524+LucaButBoring@users.noreply.github.com> Co-authored-by: leweng <leweng@nvidia.com> Co-authored-by: Clare Liguori <liguori@amazon.com> Co-authored-by: lukacf <luka@peltarion.com> Co-authored-by: ihrpr <inna@anthropic.com> Co-authored-by: Tapan Chugh <chugh.tapan@gmail.com> Co-authored-by: Tapan Chugh <tapanc@cs.washington.edu> Co-authored-by: Yann Jouanin <4557670+yannj-fr@users.noreply.github.com> Co-authored-by: Paul Carleton <paulcarletonjr@gmail.com> Co-authored-by: Sreenath Somarajapuram <somarajapuram@gmail.com> Co-authored-by: Omer Korner <omerkorner@gmail.com> Co-authored-by: joesavage-silabs <159480754+joesavage-silabs@users.noreply.github.com> Co-authored-by: Gregory L <gregory.linford@mistral.ai> Co-authored-by: David Soria Parra <167242713+dsp-ant@users.noreply.github.com> Co-authored-by: Moustapha Ebnou <155577789+mous222@users.noreply.github.com> Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Jerome <jerome@anthropic.com> Co-authored-by: xavier <84836280+dragonier23@users.noreply.github.com> Co-authored-by: keurcien <keurcien.luu@gmail.com> Co-authored-by: Tim Esler <tim.esler@gmail.com> Co-authored-by: San Nguyen <22189661+sandangel@users.noreply.github.com> Co-authored-by: Justin Wang <89049861+justin-yi-wang@users.noreply.github.com> Co-authored-by: jess <jessachandler@gmail.com> Co-authored-by: Peter Alexander <pja@anthropic.com> Co-authored-by: Reid Geyer <12072650+reidg44@users.noreply.github.com> Co-authored-by: Eleftheria Stein-Kousathana <eleftheria.kousathana@gmail.com> Co-authored-by: Christian Clauss <cclauss@me.com> Co-authored-by: pchoudhury22 <pchoudhury22@apple.com> Co-authored-by: owengo <owengo@users.noreply.github.com> Co-authored-by: Olivier Schiavo <olivier.schiavo@wengo.com> Co-authored-by: Steve Billings <billings.steve@gmail.com> Co-authored-by: Mike Salvatore <mike.s.salvatore@gmail.com> Co-authored-by: pengwa <pengwa@microsoft.com> Co-authored-by: Your Name <youremail@yourdomain.com> Co-authored-by: Jon Shea <jonshea@jonshea.com> Co-authored-by: automaton82 <terrence.sheflin@gmail.com> Co-authored-by: Yukuan Jia <jiayukuan@huawei.com> Co-authored-by: Lorenzo <lorenzo_cesconeto@hotmail.com> Co-authored-by: ZhangChuanhui <57099533+zhangch-ss@users.noreply.github.com> Co-authored-by: zhangchuanhui <zhangchal@digitalchina.com> Co-authored-by: Marcus Shu <46469249+shulkx@users.noreply.github.com> Co-authored-by: Brandon Wu <49291449+brandonspark@users.noreply.github.com> Co-authored-by: Dogacan Colak <dogacancolak@gmail.com> Co-authored-by: AishwaryaKalloli <30429206+AishwaryaKalloli@users.noreply.github.com> Co-authored-by: lorenss-m <saeclmusic@gmail.com> Co-authored-by: Rocky Haotian Du <2712479005@qq.com> Co-authored-by: Fenn Bailey <fennb@users.noreply.github.com> Co-authored-by: daamitt <147169947+daamitt@users.noreply.github.com> Co-authored-by: Mat Leonard <137834585+mat-octave@users.noreply.github.com> Co-authored-by: Samuel Felipe Chenatti <samuel.chenatti@gmail.com> Co-authored-by: Brandon Shar <6599653+BrandonShar@users.noreply.github.com> Co-authored-by: mingo007 <maoqiming1@huawei.com> Co-authored-by: adam jones <domdomegg+git@gmail.com> Co-authored-by: Yann Jouanin <yann.jouanin@valueandco.com> Co-authored-by: Koichi ITO <koic.ito@gmail.com> Co-authored-by: Cole Murray <colemurray.cs@gmail.com> Co-authored-by: inaku <63503085+inaku-Gyan@users.noreply.github.com> Co-authored-by: Chris Coutinho <12901868+cbcoutinho@users.noreply.github.com> Co-authored-by: Paul Carleton <paulc@anthropic.com> Co-authored-by: Camila Rondinini <camila@anthropic.com> Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com> Co-authored-by: Andrii Blyzniuk <bliznyuk.andrey@gmail.com> Co-authored-by: Liang Wu <18244712+wuliang229@users.noreply.github.com> Co-authored-by: adam jones <adamj+git@anthropic.com> Co-authored-by: Olivier Chafik <ochafik@anthropic.com> Co-authored-by: Tyler Mailman <themailmaninbox@gmail.com> Co-authored-by: TheMailmans <tyler@example.com> Co-authored-by: Edison <Edison.A.N@hotmail.com> Co-authored-by: dvlpjrs <dvlp.jrs@gmail.com>
When the transport closes (stdin EOF, client disconnect) while a request handler is still running, server.run()'s task group joins on the handler instead of cancelling it. The handler eventually finishes, tries to send its response through a write stream that _receive_loop already closed, and server.run() crashes with ClosedResourceError wrapped in a triple-nested ExceptionGroup. The fix cancels the task group when the incoming_messages loop ends. Handlers receive CancelledError and can clean up in finally blocks. The existing CancelledError catch in _handle_request (added for CancelledNotification handling in #1153) now distinguishes the two cancellation sources: responder.cancel() already sent an error response and we skip the duplicate; transport-close cancellation is re-raised so the task group swallows it. Github-Issue: #526
When a client cancels a long-running MCP request, there's a race condition between the cancellation and normal response paths: 1. Client cancels request → RequestResponder.cancel() sends error response and sets _completed = True 2. Middleware catches CancelledError and returns a ToolResult 3. MCP SDK tries to call message.respond(response) 4. Crash: assert not self._completed fails Fix: Re-raise CancelledError instead of returning a result, allowing the MCP SDK's cancellation handler to properly manage the response lifecycle. See: modelcontextprotocol/python-sdk#1153 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
#411) * Fix MCP server crash on request cancellation When a client cancels a long-running MCP request, there's a race condition between the cancellation and normal response paths: 1. Client cancels request → RequestResponder.cancel() sends error response and sets _completed = True 2. Middleware catches CancelledError and returns a ToolResult 3. MCP SDK tries to call message.respond(response) 4. Crash: assert not self._completed fails Fix: Re-raise CancelledError instead of returning a result, allowing the MCP SDK's cancellation handler to properly manage the response lifecycle. See: modelcontextprotocol/python-sdk#1153 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add structured_content to error responses for MCP SDK validation When tools have an outputSchema (auto-generated from return type like Dict[str, Any]), MCP SDK requires structured_content in all responses. The middleware was returning ToolResult without structured_content for error cases (timeout, exceptions), causing validation errors: "Output validation error: outputSchema defined but no structured output returned" Fix: Include structured_content with the same error data in all error responses. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix structured_content not populated for tools with return type annotations FastMCP auto-generates outputSchema from return type annotations (e.g., -> Dict[str, Any]) but doesn't populate structured_content in ToolResult. MCP SDK validation then fails: "outputSchema defined but no structured output" Fix: Intercept successful results and populate structured_content from JSON text content when missing. Only modifies results when: 1. structured_content is missing 2. There's exactly one TextContent item 3. The text is valid JSON that parses to a dict 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix(mcp): apply async wrapper on all platforms to prevent cancellation crashes The asyncio.to_thread() wrapper was only applied on Windows, but it's needed on ALL platforms to enable proper cancellation handling. Without this fix, when a sync tool runs longer than the client timeout: 1. Client sends cancellation 2. Sync tool blocks event loop, can't receive CancelledError 3. Tool eventually returns, but MCP SDK already responded to cancel 4. AssertionError: "Request already responded to" → server crashes This was discovered when uploading 7,375 files triggered a timeout, crashing the MCP server on macOS. Extends the fix from PR #411 which added CancelledError handling in middleware - that fix only works when cancellation can propagate, which requires async execution via to_thread(). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix: don't set structured_content on error responses Setting structured_content causes MCP SDK to validate it against the tool's outputSchema. For error responses, the error dict {"error": True, ...} doesn't match the expected return type (e.g., Union[str, List[Dict]]), causing "Output validation error: 'result' is a required property". Fix: Only set structured_content for successful responses, not errors. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Quentin Ambard <quentin.ambard@databricks.com> Co-authored-by: Claude <noreply@anthropic.com>
…#374) * Enhance AI/BI dashboard skill with comprehensive widget specs Added missing documentation from production dashboard generation: 1-widget-specifications.md: - Combo charts (bar + line on same widget) with version 1 - Counter number formatting (currency, percent, plain number) - Widget name max length (60 characters) - Color scale restrictions (no scheme/colorRamp/mappings) - Quantitative color encoding for gradient effects - Bar chart group vs stacked decision criteria with examples 2-filters.md: - Date range picker complete example - Multi-dataset filter binding (one query per dataset) - Global filter performance note (auto WHERE clause) SKILL.md: - ORDER BY guidance for time series and rankings 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add TOP-N + Other bucketing guidance for high-cardinality dimensions When a dimension has too many values (50+ stores, products, etc.), charts become unreadable. Added guidance to: - Check cardinality via get_table_details before charting - Use TOP-N + "Other" SQL pattern to bucket low-value items - Aggregate to higher abstraction level as alternative - Use table widgets for high-cardinality data 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Remove async deploy_dashboard function for consistency The codebase doesn't use async anywhere else, so remove the unused async version of deploy_dashboard and keep only the synchronous one. - Remove asyncio import - Remove async deploy_dashboard function (was using asyncio.to_thread) - Rename deploy_dashboard_sync to deploy_dashboard - Update exports in __init__.py 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add genie_space_id parameter to dashboard creation Allow linking a Genie space to a dashboard by passing genie_space_id. This enables the "Ask Genie" button on the dashboard UI. The Genie space config is injected into the serialized_dashboard JSON under uiSettings.genieSpace with isEnabled=true and enablementMode=ENABLED. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add catalog and schema parameters to dashboard creation Allow setting default catalog and schema for dashboard datasets via the dataset_catalog and dataset_schema API parameters. These defaults apply to unqualified table names in SQL queries. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add comprehensive date range filtering documentation - Document field-based filtering (automatic IN_RANGE on date fields) - Document parameter-based filtering (:date_range.min/max in SQL) - Show how to combine both approaches in one filter - Add guidance on when NOT to apply date filtering (MRR, all-time totals) - Update SKILL.md tools table with new genie_space_id, catalog, schema params 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Restructure AI/BI dashboard skill with improved organization - Split widget specs into basic (1-widget-specifications.md) and advanced (2-advanced-widget-specifications.md) files - Add area chart, scatter plot, combo chart, and choropleth map documentation - Rename files for consistent numbering (3-filters, 4-examples, 5-troubleshooting) - Remove duplicate information across files (versions, naming rules, etc.) - Add widget display formatting guidance (currency, percentage, displayName) - Simplify SKILL.md quality checklist with link to version table - Shorten verbose examples while preserving all critical information - Clarify query naming convention for charts vs filters 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add back critical behavioral instructions for text widgets and filters * Restore important behavioral instructions removed during restructure - Counter: full Pattern 2 example with CRITICAL field name matching note - Table: disaggregated:true guidance and bold emphasis - Line/Bar: x,y,color encodings and disaggregated guidance - Pie: 3-8 category limit for readability * Restore detailed guidance that was removed during restructure - 5-troubleshooting.md: Restore full troubleshooting content with version guidance, filter debugging, and detailed error explanations - SKILL.md: Restore full 10-item quality checklist - SKILL.md: Restore standard dashboard structure example - SKILL.md: Restore cardinality guidance table (with softer 'suggested' language) * Optimize MCP tool docstrings for token efficiency - Reduce docstring verbosity across all 18 tool files (~89% reduction) - Keep all functional information while being concise - Add skill references to complex tools (dashboards, vector search, genie, jobs, pipelines, lakebase, unity catalog, serving, apps, agent bricks) - Maintain human readability with bullet points and structure - Preserve critical warnings (ASK USER FIRST, CONFIRM WITH USER) - Keep return format hints for AI parsing Net reduction: 1,843 lines across 18 files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add parameter context for ambiguous docstring params - agent_bricks.py: Add context for description, instructions, volume_path, examples - genie.py: Add context for table_identifiers, description, sample_questions, serialized_space - jobs.py: Add context for tasks, job_clusters, environments, schedule, git_source - lakebase.py: Add context for source_branch, ttl_seconds, is_protected, autoscaling params, and sync source/target table names - pipelines.py: Add context for root_path, workspace_file_paths, extra_settings, full_refresh 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Consolidate MCP tools from 77 to 44 (43% reduction) Tool consolidations: - pipelines.py: 10→2 (manage_pipeline, manage_pipeline_run) - volume_files.py: 6→1 (manage_volume_files) - aibi_dashboards.py: 4→1 (manage_dashboard) - vector_search.py: 8→4 (manage_vs_endpoint, manage_vs_index, query_vs_index, manage_vs_data) - genie.py: 5→2 (manage_genie, ask_genie) - serving.py: 3→1 (manage_serving_endpoint) - apps.py: 3→1 (manage_app) - file.py: 2→1 (manage_workspace_files) - sql.py: 6→5 (manage_warehouse replaces list/get_best) - lakebase.py: 8→4 (manage_lakebase_database, manage_lakebase_branch, manage_lakebase_sync, generate_lakebase_credential) Key patterns: - All consolidated tools use an action parameter - Each action has required params documented in docstring - Error messages specify which params are required - Hot paths (query_vs_index, ask_genie) kept separate for clarity - All skills updated with action tables and examples 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add integration test infrastructure and fix tool bugs Test infrastructure: - Add comprehensive integration tests for all MCP tools - Add test runner script with parallel execution support - Add fixtures for workspace, catalog, and resource cleanup - Add test resources (PDFs, SQL files, app configs) Bug fixes in databricks-tools-core: - Fix workspace file upload for directories - Fix job notebook path handling - Fix vector search index operations - Fix apps API responses - Fix dashboard widget handling - Fix agent bricks manager listing Bug fixes in MCP server tools: - Add quota skip handling for apps test - Fix genie space operations - Fix lakebase database operations - Fix compute cluster lifecycle handling - Fix dashboard operations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Change manage_dashboard to use file path instead of inline JSON - Replace serialized_dashboard param with dashboard_file_path - Tool reads JSON from local file for easier iterative development - Update SKILL.md with new workflow documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Update dashboard tests for file-based approach - Change simple_dashboard_json fixture to simple_dashboard_file - Update all manage_dashboard calls to use dashboard_file_path - Add tempfile imports and tmp_path usage for update test 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix deploy_app to correctly handle SDK Wait[AppDeployment] return type The Databricks SDK's w.apps.deploy() returns a Wait[AppDeployment] object, not an AppDeployment directly. The previous code passed the Wait object to _deployment_to_dict(), which caused getattr() to return None for all attributes since the Wait object doesn't have them. This fix uses wait_obj.response to get the actual AppDeployment object before converting it to a dictionary. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix deploy_app to correctly handle SDK Wait[AppDeployment] return type The Databricks SDK's w.apps.deploy() returns a Wait[AppDeployment] object, not an AppDeployment directly. The previous code passed the Wait object to _deployment_to_dict(), which caused getattr() to return None for all attributes since the Wait object doesn't have them. This fix uses wait_obj.response to get the actual AppDeployment object before converting it to a dictionary. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Clarify MCP tool usage in Genie skill documentation - Add tools summary table at top of MCP Tools section - Change code blocks from python syntax to plain text - Add "# MCP Tool: <name>" comments to clarify these are tool calls, not Python code - Move Supporting Tools table to main tools table 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix typo in aibi_dashboards.py docstring Remove garbage characters from widget documentation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix genie tools to use SDK methods instead of manager - Use w.genie.trash_space() in _delete_genie_resource - Add _find_space_by_name() using SDK's list_spaces with pagination - Use w.genie.update_space() and w.genie.create_space() for space management - Use w.genie.get_space() with include_serialized_space in _get_genie_space - Fix validation to allow space_id for updates without display_name 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Improve integration test reliability and timeout handling - Add per-suite timeout in run_tests.py (10 min default, configurable) - Improve apps test with better cleanup and assertions - Add skip logic for quota-exceeded scenarios 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Improve Unity Catalog tool docstrings with comprehensive parameter documentation Add detailed parameter documentation to all 9 Unity Catalog MCP tools: - manage_uc_objects: Document parameters by object_type (catalog/schema/volume/function) - manage_uc_grants: Add privilege lists per securable type - manage_uc_storage: Detail credential and external_location parameters - manage_uc_connections: Document connection_type options and create_foreign_catalog - manage_uc_tags: Detail set_tags/unset_tags/query parameters - manage_uc_security_policies: Document row filter and column mask parameters - manage_uc_monitors: Detail monitor creation and refresh parameters - manage_uc_sharing: Document share/recipient/provider resource types - manage_metric_views: Detail dimension/measure format and query parameters 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add CRITICAL validation steps to dashboard tool docstring Add clear instructions requiring users to: 0. Review the databricks-aibi-dashboards skill for widget JSON structure 1. Call get_table_stats_and_schema() for table schemas 2. Call execute_sql() to test EVERY query before use This prevents widgets from showing errors due to untested queries. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add design best practices section and use relative file paths - Add Design Best Practices section for default dashboard behaviors - Change /tmp paths to ./ for less opinionated examples - Update parent_path example to use {user_email} placeholder 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Improve AI/BI dashboard skill documentation with comprehensive examples - Replace basic NYC taxi examples with complete Sales Analytics dashboard - Add critical widget version requirements table to SKILL.md - Add data validation guidance to verify dashboards tell intended story - Document key patterns: page types, KPI formatting, filter binding, layout grid 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add skill reading requirement to dashboard MCP tool docstring Require agent to read 4-examples.md before creating dashboards, and if unfamiliar, read full skill documentation first. Valid JSON is critical. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix MCP server crash on request cancellation When a client cancels a long-running MCP request, there's a race condition between the cancellation and normal response paths: 1. Client cancels request → RequestResponder.cancel() sends error response and sets _completed = True 2. Middleware catches CancelledError and returns a ToolResult 3. MCP SDK tries to call message.respond(response) 4. Crash: assert not self._completed fails Fix: Re-raise CancelledError instead of returning a result, allowing the MCP SDK's cancellation handler to properly manage the response lifecycle. See: modelcontextprotocol/python-sdk#1153 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add structured_content to error responses for MCP SDK validation When tools have an outputSchema (auto-generated from return type like Dict[str, Any]), MCP SDK requires structured_content in all responses. The middleware was returning ToolResult without structured_content for error cases (timeout, exceptions), causing validation errors: "Output validation error: outputSchema defined but no structured output returned" Fix: Include structured_content with the same error data in all error responses. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Migrate KA operations to Python SDK and fix name lookup issues - Migrate ka_create, ka_get, ka_sync_sources to use Python SDK - Keep ka_update using raw API 2.1 due to SDK FieldMask bug (converts snake_case to camelCase but API expects snake_case) - Fix find_by_name to sanitize names (spaces→underscores) before lookup - Fix ka_create_or_update to lookup by name when no tile_id provided, preventing ALREADY_EXISTS errors on repeated calls - Update MCP tool layer to use new flat response format - Map SDK state values (ACTIVE, CREATING, FAILED) to endpoint_status - Add integration test for updating existing KA via create_or_update 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix knowledge source description requirement and test ordering - Provide default description for knowledge sources when not specified (API requires non-empty knowledge_source.description) - Move KA update test to after endpoint is ONLINE (update requires ACTIVE state) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix structured_content not populated for tools with return type annotations FastMCP auto-generates outputSchema from return type annotations (e.g., -> Dict[str, Any]) but doesn't populate structured_content in ToolResult. MCP SDK validation then fails: "outputSchema defined but no structured output" Fix: Intercept successful results and populate structured_content from JSON text content when missing. Only modifies results when: 1. structured_content is missing 2. There's exactly one TextContent item 3. The text is valid JSON that parses to a dict 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix(mcp): apply async wrapper on all platforms to prevent cancellation crashes The asyncio.to_thread() wrapper was only applied on Windows, but it's needed on ALL platforms to enable proper cancellation handling. Without this fix, when a sync tool runs longer than the client timeout: 1. Client sends cancellation 2. Sync tool blocks event loop, can't receive CancelledError 3. Tool eventually returns, but MCP SDK already responded to cancel 4. AssertionError: "Request already responded to" → server crashes This was discovered when uploading 7,375 files triggered a timeout, crashing the MCP server on macOS. Extends the fix from PR #411 which added CancelledError handling in middleware - that fix only works when cancellation can propagate, which requires async execution via to_thread(). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix: don't set structured_content on error responses Setting structured_content causes MCP SDK to validate it against the tool's outputSchema. For error responses, the error dict {"error": True, ...} doesn't match the expected return type (e.g., Union[str, List[Dict]]), causing "Output validation error: 'result' is a required property". Fix: Only set structured_content for successful responses, not errors. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Improve dashboard skill structure based on error analysis - Add JSON skeleton section to SKILL.md showing required structure - Add Genie note clarifying it's not a widget (use genie_space_id param) - Move Key Patterns to top of 4-examples.md for discoverability - Clarify example is reference only - adapt to user's actual requirements - Add structural errors table to 5-troubleshooting.md Root cause fixes: - queryLines must be array, not "query": "string" - Widgets must be inline in layout[].widget, not separate array - pageType required on every page 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Quentin Ambard <quentin.ambard@databricks.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: calreynolds <calrey98@gmail.com>
* Enhance AI/BI dashboard skill with comprehensive widget specs Added missing documentation from production dashboard generation: 1-widget-specifications.md: - Combo charts (bar + line on same widget) with version 1 - Counter number formatting (currency, percent, plain number) - Widget name max length (60 characters) - Color scale restrictions (no scheme/colorRamp/mappings) - Quantitative color encoding for gradient effects - Bar chart group vs stacked decision criteria with examples 2-filters.md: - Date range picker complete example - Multi-dataset filter binding (one query per dataset) - Global filter performance note (auto WHERE clause) SKILL.md: - ORDER BY guidance for time series and rankings 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add TOP-N + Other bucketing guidance for high-cardinality dimensions When a dimension has too many values (50+ stores, products, etc.), charts become unreadable. Added guidance to: - Check cardinality via get_table_details before charting - Use TOP-N + "Other" SQL pattern to bucket low-value items - Aggregate to higher abstraction level as alternative - Use table widgets for high-cardinality data 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Remove async deploy_dashboard function for consistency The codebase doesn't use async anywhere else, so remove the unused async version of deploy_dashboard and keep only the synchronous one. - Remove asyncio import - Remove async deploy_dashboard function (was using asyncio.to_thread) - Rename deploy_dashboard_sync to deploy_dashboard - Update exports in __init__.py 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add genie_space_id parameter to dashboard creation Allow linking a Genie space to a dashboard by passing genie_space_id. This enables the "Ask Genie" button on the dashboard UI. The Genie space config is injected into the serialized_dashboard JSON under uiSettings.genieSpace with isEnabled=true and enablementMode=ENABLED. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add catalog and schema parameters to dashboard creation Allow setting default catalog and schema for dashboard datasets via the dataset_catalog and dataset_schema API parameters. These defaults apply to unqualified table names in SQL queries. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add comprehensive date range filtering documentation - Document field-based filtering (automatic IN_RANGE on date fields) - Document parameter-based filtering (:date_range.min/max in SQL) - Show how to combine both approaches in one filter - Add guidance on when NOT to apply date filtering (MRR, all-time totals) - Update SKILL.md tools table with new genie_space_id, catalog, schema params 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Restructure AI/BI dashboard skill with improved organization - Split widget specs into basic (1-widget-specifications.md) and advanced (2-advanced-widget-specifications.md) files - Add area chart, scatter plot, combo chart, and choropleth map documentation - Rename files for consistent numbering (3-filters, 4-examples, 5-troubleshooting) - Remove duplicate information across files (versions, naming rules, etc.) - Add widget display formatting guidance (currency, percentage, displayName) - Simplify SKILL.md quality checklist with link to version table - Shorten verbose examples while preserving all critical information - Clarify query naming convention for charts vs filters 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add back critical behavioral instructions for text widgets and filters * Restore important behavioral instructions removed during restructure - Counter: full Pattern 2 example with CRITICAL field name matching note - Table: disaggregated:true guidance and bold emphasis - Line/Bar: x,y,color encodings and disaggregated guidance - Pie: 3-8 category limit for readability * Restore detailed guidance that was removed during restructure - 5-troubleshooting.md: Restore full troubleshooting content with version guidance, filter debugging, and detailed error explanations - SKILL.md: Restore full 10-item quality checklist - SKILL.md: Restore standard dashboard structure example - SKILL.md: Restore cardinality guidance table (with softer 'suggested' language) * Optimize MCP tool docstrings for token efficiency - Reduce docstring verbosity across all 18 tool files (~89% reduction) - Keep all functional information while being concise - Add skill references to complex tools (dashboards, vector search, genie, jobs, pipelines, lakebase, unity catalog, serving, apps, agent bricks) - Maintain human readability with bullet points and structure - Preserve critical warnings (ASK USER FIRST, CONFIRM WITH USER) - Keep return format hints for AI parsing Net reduction: 1,843 lines across 18 files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add parameter context for ambiguous docstring params - agent_bricks.py: Add context for description, instructions, volume_path, examples - genie.py: Add context for table_identifiers, description, sample_questions, serialized_space - jobs.py: Add context for tasks, job_clusters, environments, schedule, git_source - lakebase.py: Add context for source_branch, ttl_seconds, is_protected, autoscaling params, and sync source/target table names - pipelines.py: Add context for root_path, workspace_file_paths, extra_settings, full_refresh 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Consolidate MCP tools from 77 to 44 (43% reduction) Tool consolidations: - pipelines.py: 10→2 (manage_pipeline, manage_pipeline_run) - volume_files.py: 6→1 (manage_volume_files) - aibi_dashboards.py: 4→1 (manage_dashboard) - vector_search.py: 8→4 (manage_vs_endpoint, manage_vs_index, query_vs_index, manage_vs_data) - genie.py: 5→2 (manage_genie, ask_genie) - serving.py: 3→1 (manage_serving_endpoint) - apps.py: 3→1 (manage_app) - file.py: 2→1 (manage_workspace_files) - sql.py: 6→5 (manage_warehouse replaces list/get_best) - lakebase.py: 8→4 (manage_lakebase_database, manage_lakebase_branch, manage_lakebase_sync, generate_lakebase_credential) Key patterns: - All consolidated tools use an action parameter - Each action has required params documented in docstring - Error messages specify which params are required - Hot paths (query_vs_index, ask_genie) kept separate for clarity - All skills updated with action tables and examples 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add integration test infrastructure and fix tool bugs Test infrastructure: - Add comprehensive integration tests for all MCP tools - Add test runner script with parallel execution support - Add fixtures for workspace, catalog, and resource cleanup - Add test resources (PDFs, SQL files, app configs) Bug fixes in databricks-tools-core: - Fix workspace file upload for directories - Fix job notebook path handling - Fix vector search index operations - Fix apps API responses - Fix dashboard widget handling - Fix agent bricks manager listing Bug fixes in MCP server tools: - Add quota skip handling for apps test - Fix genie space operations - Fix lakebase database operations - Fix compute cluster lifecycle handling - Fix dashboard operations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Change manage_dashboard to use file path instead of inline JSON - Replace serialized_dashboard param with dashboard_file_path - Tool reads JSON from local file for easier iterative development - Update SKILL.md with new workflow documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Update dashboard tests for file-based approach - Change simple_dashboard_json fixture to simple_dashboard_file - Update all manage_dashboard calls to use dashboard_file_path - Add tempfile imports and tmp_path usage for update test 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix deploy_app to correctly handle SDK Wait[AppDeployment] return type The Databricks SDK's w.apps.deploy() returns a Wait[AppDeployment] object, not an AppDeployment directly. The previous code passed the Wait object to _deployment_to_dict(), which caused getattr() to return None for all attributes since the Wait object doesn't have them. This fix uses wait_obj.response to get the actual AppDeployment object before converting it to a dictionary. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix deploy_app to correctly handle SDK Wait[AppDeployment] return type The Databricks SDK's w.apps.deploy() returns a Wait[AppDeployment] object, not an AppDeployment directly. The previous code passed the Wait object to _deployment_to_dict(), which caused getattr() to return None for all attributes since the Wait object doesn't have them. This fix uses wait_obj.response to get the actual AppDeployment object before converting it to a dictionary. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Clarify MCP tool usage in Genie skill documentation - Add tools summary table at top of MCP Tools section - Change code blocks from python syntax to plain text - Add "# MCP Tool: <name>" comments to clarify these are tool calls, not Python code - Move Supporting Tools table to main tools table 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix typo in aibi_dashboards.py docstring Remove garbage characters from widget documentation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix genie tools to use SDK methods instead of manager - Use w.genie.trash_space() in _delete_genie_resource - Add _find_space_by_name() using SDK's list_spaces with pagination - Use w.genie.update_space() and w.genie.create_space() for space management - Use w.genie.get_space() with include_serialized_space in _get_genie_space - Fix validation to allow space_id for updates without display_name 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Improve integration test reliability and timeout handling - Add per-suite timeout in run_tests.py (10 min default, configurable) - Improve apps test with better cleanup and assertions - Add skip logic for quota-exceeded scenarios 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Improve Unity Catalog tool docstrings with comprehensive parameter documentation Add detailed parameter documentation to all 9 Unity Catalog MCP tools: - manage_uc_objects: Document parameters by object_type (catalog/schema/volume/function) - manage_uc_grants: Add privilege lists per securable type - manage_uc_storage: Detail credential and external_location parameters - manage_uc_connections: Document connection_type options and create_foreign_catalog - manage_uc_tags: Detail set_tags/unset_tags/query parameters - manage_uc_security_policies: Document row filter and column mask parameters - manage_uc_monitors: Detail monitor creation and refresh parameters - manage_uc_sharing: Document share/recipient/provider resource types - manage_metric_views: Detail dimension/measure format and query parameters 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add CRITICAL validation steps to dashboard tool docstring Add clear instructions requiring users to: 0. Review the databricks-aibi-dashboards skill for widget JSON structure 1. Call get_table_stats_and_schema() for table schemas 2. Call execute_sql() to test EVERY query before use This prevents widgets from showing errors due to untested queries. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add design best practices section and use relative file paths - Add Design Best Practices section for default dashboard behaviors - Change /tmp paths to ./ for less opinionated examples - Update parent_path example to use {user_email} placeholder 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Improve code execution and synthetic data gen skills Execution compute skill: - Split into 3 clear execution modes: Databricks Connect (default), Serverless Job, Interactive Cluster - Add decision matrix for choosing execution mode - Add job_extra_params for custom dependencies in serverless jobs - Create dedicated reference files for each mode Synthetic data gen skill: - Emphasize business story: problem → impact → analysis → solution - Add guidance to propose compelling stories by default - Consolidate reference files (6 → 2) - Add critical rules for data coherence and Databricks value - Clarify when to read reference files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add performance rules for synthetic data generation - Add Critical Rule #12: No Python loops or .collect() - Add Performance Rules section with anti-pattern table - Emphasize Spark parallelism over driver-side iteration 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Clarify parquet path is folder with table name 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Improve AI/BI dashboard skill documentation with comprehensive examples - Replace basic NYC taxi examples with complete Sales Analytics dashboard - Add critical widget version requirements table to SKILL.md - Add data validation guidance to verify dashboards tell intended story - Document key patterns: page types, KPI formatting, filter binding, layout grid 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add skill reading requirement to dashboard MCP tool docstring Require agent to read 4-examples.md before creating dashboards, and if unfamiliar, read full skill documentation first. Valid JSON is critical. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Emphasize Databricks Connect serverless, add setup requirements - Rule #10: Use Databricks Connect Serverless by default (avoid execute_code) - Setup: Use uv, require Python 3.12 and databricks-connect>=16.4 - Common issues: Add DatabricksEnv ImportError and Python version fixes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix MCP server crash on request cancellation When a client cancels a long-running MCP request, there's a race condition between the cancellation and normal response paths: 1. Client cancels request → RequestResponder.cancel() sends error response and sets _completed = True 2. Middleware catches CancelledError and returns a ToolResult 3. MCP SDK tries to call message.respond(response) 4. Crash: assert not self._completed fails Fix: Re-raise CancelledError instead of returning a result, allowing the MCP SDK's cancellation handler to properly manage the response lifecycle. See: modelcontextprotocol/python-sdk#1153 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add structured_content to error responses for MCP SDK validation When tools have an outputSchema (auto-generated from return type like Dict[str, Any]), MCP SDK requires structured_content in all responses. The middleware was returning ToolResult without structured_content for error cases (timeout, exceptions), causing validation errors: "Output validation error: outputSchema defined but no structured output returned" Fix: Include structured_content with the same error data in all error responses. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Migrate KA operations to Python SDK and fix name lookup issues - Migrate ka_create, ka_get, ka_sync_sources to use Python SDK - Keep ka_update using raw API 2.1 due to SDK FieldMask bug (converts snake_case to camelCase but API expects snake_case) - Fix find_by_name to sanitize names (spaces→underscores) before lookup - Fix ka_create_or_update to lookup by name when no tile_id provided, preventing ALREADY_EXISTS errors on repeated calls - Update MCP tool layer to use new flat response format - Map SDK state values (ACTIVE, CREATING, FAILED) to endpoint_status - Add integration test for updating existing KA via create_or_update 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix knowledge source description requirement and test ordering - Provide default description for knowledge sources when not specified (API requires non-empty knowledge_source.description) - Move KA update test to after endpoint is ONLINE (update requires ACTIVE state) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix structured_content not populated for tools with return type annotations FastMCP auto-generates outputSchema from return type annotations (e.g., -> Dict[str, Any]) but doesn't populate structured_content in ToolResult. MCP SDK validation then fails: "outputSchema defined but no structured output" Fix: Intercept successful results and populate structured_content from JSON text content when missing. Only modifies results when: 1. structured_content is missing 2. There's exactly one TextContent item 3. The text is valid JSON that parses to a dict 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix(mcp): apply async wrapper on all platforms to prevent cancellation crashes The asyncio.to_thread() wrapper was only applied on Windows, but it's needed on ALL platforms to enable proper cancellation handling. Without this fix, when a sync tool runs longer than the client timeout: 1. Client sends cancellation 2. Sync tool blocks event loop, can't receive CancelledError 3. Tool eventually returns, but MCP SDK already responded to cancel 4. AssertionError: "Request already responded to" → server crashes This was discovered when uploading 7,375 files triggered a timeout, crashing the MCP server on macOS. Extends the fix from PR #411 which added CancelledError handling in middleware - that fix only works when cancellation can propagate, which requires async execution via to_thread(). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix: don't set structured_content on error responses Setting structured_content causes MCP SDK to validate it against the tool's outputSchema. For error responses, the error dict {"error": True, ...} doesn't match the expected return type (e.g., Union[str, List[Dict]]), causing "Output validation error: 'result' is a required property". Fix: Only set structured_content for successful responses, not errors. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Improve dashboard skill structure based on error analysis - Add JSON skeleton section to SKILL.md showing required structure - Add Genie note clarifying it's not a widget (use genie_space_id param) - Move Key Patterns to top of 4-examples.md for discoverability - Clarify example is reference only - adapt to user's actual requirements - Add structural errors table to 5-troubleshooting.md Root cause fixes: - queryLines must be array, not "query": "string" - Widgets must be inline in layout[].widget, not separate array - pageType required on every page 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Quentin Ambard <quentin.ambard@databricks.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: calreynolds <calrey98@gmail.com>
When clients cancel long-running tool calls, the server crashes with an assertion error and becomes unresponsive. This PR fixes the issue by preventing duplicate responses.
Problem
Solution
Catch CancelledError in _handle_request and return early without sending a second response.
Testing
Added test that cancels a tool call and verifies the server remains responsive.
Fixes #1152
Related: PrefectHQ/fastmcp#508, PrefectHQ/fastmcp#823