Skip to content

feat(mcp): add support for MCP elicitation -32042 error handling#1745

Merged
mkmeral merged 7 commits intostrands-agents:mainfrom
Christian-kam:main
Mar 30, 2026
Merged

feat(mcp): add support for MCP elicitation -32042 error handling#1745
mkmeral merged 7 commits intostrands-agents:mainfrom
Christian-kam:main

Conversation

@Christian-kam
Copy link
Copy Markdown
Contributor

Description

When an MCP server like AgentCore Gateway returns a -32042 (URLElicitationRequiredError) on tools/call, the
MCP Python SDK raises McpError. The current MCPClient._handle_tool_execution_error
catches it and returns a generic error string, losing the authorization URL(s) embedded in
error.data.elicitations. This breaks OAuth consent flows that rely on URL mode elicitation
(e.g., AgentCore Gateway 3LO, or any MCP server using the 2025-11-25 spec).

This PR modifies _handle_tool_execution_error to detect McpError with code -32042,
parse the error data using the MCP SDK's ElicitationRequiredErrorData model, and include
the authorization URL(s) in the tool result text with a URL_ELICITATION_REQUIRED prefix.
The LLM can then present the URL to the user and retry the tool call after consent completes.

Changes

File: strands/tools/mcp/mcp_client.py

  • Added imports: McpError from mcp.shared.exceptions, ElicitationRequiredErrorData from mcp.types
  • Modified MCPClient._handle_tool_execution_error: added a check at the top of the method for -32042 errors, parses ElicitationRequiredErrorData, extracts URL(s) and message(s), and returns them in the tool result. Falls through to original behavior for all non-32042 errors.

How the two elicitation paths work together

The MCP 2025-11-25 spec defines two ways a server can request user authorization:

Path Mechanism Handled by
Server-initiated Server sends elicitation/create request to client elicitation_callback on MCPClient (existing, unchanged)
Error-based Server returns -32042 error on tools/call _handle_tool_execution_error (this PR)

Both paths can coexist. The elicitation_callback handles case 1 via the MCP Python SDK's
ClientSession. This PR handles case 2, where the error is raised as McpError and caught
by call_tool_async/call_tool_sync.

Related Issues

Closes #1742

Specifically addresses the "URL Mode Elicitation" item under Major Changes in the MCP 2025-11-25 spec:

Documentation PR

N/A

Type of Change

New feature

Testing

Unit tests

Test case Input Expected output
-32042 with valid ElicitationRequiredErrorData McpError(ErrorData(code=-32042, data={"elicitations": [{"mode": "url", "url": "https://...", "message": "Please authorize"}]})) MCPToolResult with URL_ELICITATION_REQUIRED and the URL
-32042 with multiple URLs Same as above with 2+ elicitations All URLs included, newline-separated
-32042 with malformed data McpError(ErrorData(code=-32042, data="invalid")) Falls through to "Tool execution failed: ..."
-32042 with no URLs in elicitations McpError(ErrorData(code=-32042, data={"elicitations": [{"mode": "url"}]})) Falls through to "Tool execution failed: ..."
Different McpError code McpError(ErrorData(code=-32600, ...)) Falls through to "Tool execution failed: ..." (no change)
Non-McpError exception RuntimeError("connection lost") Falls through to "Tool execution failed: ..." (no change)

Integration test

Tested with AgentCore Gateway using LinkedIn as a 3LO OAuth target:

  1. Agent calls LinkedInAuthCode___getUserInfo
  2. Gateway returns -32042 with authorization URL
  3. LLM receives the URL in the tool result and presents it to the user
  4. User completes OAuth consent in browser
  5. Agent retries the tool call — succeeds and returns LinkedIn user data
  • I ran hatch run prepare

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@Christian-kam
Copy link
Copy Markdown
Contributor Author

@yonib05 Could you review my PR? It addresses the URLElicitationRequiredError (code -32042) point raised in your issue See #1659.

@Jarryd-rk
Copy link
Copy Markdown

Bumping. This is a pretty important feature for 3LO or return of control for MCP tools.

@mkmeral
Copy link
Copy Markdown
Contributor

mkmeral commented Mar 17, 2026

/strands review and check if this is the only code that we need to keep track from mcp

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Comment thread tests/strands/tools/mcp/test_mcp_client.py
@github-actions
Copy link
Copy Markdown

MCP Elicitation Tracking Assessment

Regarding the question of whether this is the only code needed to track from MCP for elicitation:

Yes, this PR covers the essential error-based elicitation path. Per the MCP 2025-11-25 spec, there are two elicitation mechanisms:

Path Mechanism Status
Server-initiated elicitation/create request ✅ Already handled via elicitation_callback
Error-based -32042 error on tools/call This PR

The implementation follows a valid "manual retry" approach where the LLM receives URLs and instructs the user to complete authorization, then retry.

Future enhancement opportunity (not blocking):
The MCP spec also defines notifications/elicitation/complete which servers MAY send after the user completes authorization. Supporting this notification would enable automatic retry instead of manual retry. From the spec:

Clients MAY wait for this notification to automatically retry requests that received a URLElicitationRequiredError... SHOULD still provide manual controls that let the user retry or cancel

This could be added as a follow-up enhancement if automatic retry is desired.

Comment thread src/strands/tools/mcp/mcp_client.py Outdated
@mkmeral
Copy link
Copy Markdown
Contributor

mkmeral commented Mar 18, 2026

/strands review

Comment thread src/strands/tools/mcp/mcp_client.py
Comment thread tests/strands/tools/mcp/test_mcp_client.py Outdated
@github-actions
Copy link
Copy Markdown

Assessment: Request Changes

The PR has critical issues that will cause failures:

Blocking Issues
  1. Missing import json: The implementation uses json.dumps() but json is not imported, causing NameError at runtime.

  2. Test/Implementation mismatch: The recent commit changed the output format to "MCP Elicitation required:" but tests still assert "URL_ELICITATION_REQUIRED" and "retry this tool call" which will fail.

Please fix these issues before this can be merged. See inline comments for details.

@mkmeral
Copy link
Copy Markdown
Contributor

mkmeral commented Mar 19, 2026

/strands review

@github-actions
Copy link
Copy Markdown

Assessment: Approve ✅

The previously flagged issues have been addressed:

Issues Fixed
Issue Status
Missing import json ✅ Fixed
Test/Implementation mismatch ✅ Fixed - tests updated to match new format
Test Coverage

All scenarios from the PR test matrix are now covered:

  • -32042 with valid elicitation data
  • -32042 with multiple elicitations
  • -32042 with empty URL
  • -32042 with malformed data (fallback)
  • ✅ Different McpError code (fallback)
  • ✅ Async path coverage

Implementation correctly handles MCP -32042 URL elicitation errors per the MCP 2025-11-25 spec. The "generic elicitation" format works well since it preserves all elicitation data (including elicitationId) for potential future use with notifications/elicitation/complete.

Good work on the fixes! 👍

@Christian-kam Christian-kam changed the title feat(mcp): add support for MCP elicitation -32042 error handling feat(mcp): add support for MCP elicitation -32042 error handling Mar 19, 2026
@mangelino
Copy link
Copy Markdown

Ensure this feature gets also implemented in the Typescript SDK

Christian-kam and others added 7 commits March 30, 2026 18:58
Add handling for MCP elicitation required errors (error code -32042) in
MCPClient. When an MCP tool requires user authorization via URL, the
client now parses the elicitation data and returns a user-friendly error
message with clear instructions and the authorization URL(s).

The implementation gracefully falls back to generic error handling if the
elicitation data cannot be parsed, ensuring robustness.

Changes:
- Enhanced _handle_tool_execution_error to detect and parse elicitation errors
- Added imports for ElicitationRequiredErrorData and McpError
- Added comprehensive test coverage for various elicitation scenarios
- Follows structured logging and error handling patterns
Add handling for MCP elicitation required errors (error code -32042) in
MCPClient. When an MCP tool requires user authorization via URL, the
client now parses the elicitation data and returns a user-friendly error
message with clear instructions and the authorization URL(s).

The implementation gracefully falls back to generic error handling if the
elicitation data cannot be parsed, ensuring robustness.

Changes:
- Enhanced _handle_tool_execution_error to detect and parse elicitation errors
- Added imports for ElicitationRequiredErrorData and McpError
- Added comprehensive test coverage for various elicitation scenarios
- Follows structured logging and error handling patterns
1. -32042 with no URLs in elicitations → "Falls through to generic error"
2. Different McpError code (e.g., -32600) → "Falls through to generic error"
more generic elicitation. Error data could carry any elicitation type eg. url or form
updated the test
@github-actions github-actions bot added size/m and removed size/m labels Mar 30, 2026
@mkmeral mkmeral merged commit e2b6036 into strands-agents:main Mar 30, 2026
18 of 20 checks passed
@mkmeral
Copy link
Copy Markdown
Contributor

mkmeral commented Mar 30, 2026

@agent-of-mkmeral see what is the current state of the TS SDK, and if we should create a ticket/issue there as a feature request for this feature. If so create an issue

@agent-of-mkmeral
Copy link
Copy Markdown
Contributor

@mkmeral I checked the current state of the TypeScript SDK. Here's the summary:

TypeScript SDK — MCP Elicitation Status

Feature Python SDK TypeScript SDK
Server-initiated elicitation (elicitation/create) elicitation_callback ❌ Not implemented (tracked: sdk-typescript#232, sdk-typescript#480)
Error-based -32042 URL elicitation This PR Not implemented

The TS SDK currently has zero elicitation support. When an MCP server returns -32042, the error is caught by a generic createErrorResult() handler in McpTool.stream() which just wraps it as "Error: ..." — the authorization URL(s) in the error data are lost.

Existing TS SDK issues

  • sdk-typescript#232 — "Add MCP Elicitation Support" → covers server-initiated callback path only
  • sdk-typescript#480 — "Interrupts - MCP Elicitation" → also callback path only

Neither tracks the error-based -32042 path.

✅ Created new issue

I've created a feature request in the TS SDK with full implementation details, test matrix, and reference to this PR:

👉 strands-agents/sdk-typescript#760feat(mcp): Add support for MCP -32042 error-based URL elicitation handling

cc @mangelino

kpx-dev pushed a commit to kpx-dev/sdk-python that referenced this pull request Mar 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Handle MCP 2025-11-25 URL mode elicitation (-32042) in MCPClient

5 participants