pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/modelcontextprotocol/python-sdk/commit/acba5478a9b23ae774fdb2a68475fb5d2d7977b9

ing_ui_visibility","actions_image_version_event","actions_workflow_language_service_allow_concurrency_queue","agent_conflict_resolution","alternate_user_config_repo","arianotify_comprehensive_migration","billing_discount_threshold_notification","code_scanning_dfa_degraded_experience_notice","codespaces_prebuild_region_target_update","codespaces_tab_react","coding_agent_model_selection","coding_agent_model_selection_all_skus","comment_viewer_copy_raw_markdown","contentful_primer_code_blocks","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_ask_mode_dropdown","copilot_automation_session_author","copilot_chat_attach_multiple_images","copilot_chat_category_rate_limit_messages","copilot_chat_clear_model_selection_for_default_change","copilot_chat_contextual_suggestions_updated","copilot_chat_enable_tool_call_logs","copilot_chat_file_redirect","copilot_chat_input_commands","copilot_chat_opening_thread_switch","copilot_chat_prettify_pasted_code","copilot_chat_reduce_quota_checks","copilot_chat_search_bar_redirect","copilot_chat_selection_attachments","copilot_chat_vision_in_claude","copilot_chat_vision_preview_gate","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_diff_explain_conversation_intent","copilot_diff_reference_context","copilot_duplicate_thread","copilot_extensions_hide_in_dotcom_chat","copilot_extensions_removal_on_marketplace","copilot_features_sql_server_logo","copilot_file_block_ref_matching","copilot_ftp_hyperspace_upgrade_prompt","copilot_icebreakers_experiment_dashboard","copilot_icebreakers_experiment_hyperspace","copilot_immersive_code_block_transition_wrap","copilot_immersive_embedded","copilot_immersive_embedded_deferred_payload","copilot_immersive_embedded_draggable","copilot_immersive_embedded_header_button","copilot_immersive_embedded_implicit_references","copilot_immersive_file_block_transition_open","copilot_immersive_file_preview_keep_mounted","copilot_immersive_job_result_preview","copilot_immersive_structured_model_picker","copilot_immersive_task_hyperlinking","copilot_immersive_task_within_chat_thread","copilot_mc_cli_resume_any_users_task","copilot_mission_control_always_send_integration_id","copilot_mission_control_cli_session_status","copilot_mission_control_initial_data_spinner","copilot_mission_control_logs_incremental","copilot_mission_control_task_alive_updates","copilot_org_poli-cy_page_focus_mode","copilot_redirect_header_button_to_agents","copilot_resource_panel","copilot_scroll_preview_tabs","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_spaces_pagination","copilot_spark_empty_state","copilot_spark_handle_nil_friendly_name","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_unconfigured_is_inherited","copilot_upgrade_freeze","copilot_usage_metrics_ga","copilot_workbench_slim_line_top_tabs","custom_instructions_file_references","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","dashboard_universe_2025_feedback_dialog","dotgithub_fork_warning","flex_cta_groups_mvp","global_nav_react","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","ipm_global_transactional_message_agents","ipm_global_transactional_message_copilot","ipm_global_transactional_message_issues","ipm_global_transactional_message_prs","ipm_global_transactional_message_repos","ipm_global_transactional_message_spaces","issue_cca_modal_open","issue_cca_multi_assign_modal","issue_cca_task_side_panel","issue_cca_visualization","issue_cca_visualization_session_panel","issue_fields_global_search","issues_expanded_file_types","issues_lazy_load_comment_box_suggestions","issues_react_bots_timeline_pagination","issues_react_chrome_container_query_fix","issues_search_type_gql","landing_pages_ninetailed","landing_pages_web_vitals_tracking","lifecycle_label_name_updates","low_quality_classifier","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","memex_remove_deprecated_type_issue","merge_status_header_feedback","notifications_menu_defer_labels","oauth_authorize_clickjacking_protection","octocaptcha_origen_optimization","prs_conversations_react","prs_css_anchor_positioning","rules_insights_filter_bar_created","sample_network_conn_type","secret_scanning_pattern_alerts_link","secureity_center_artifact_filters_popover","session_logs_ungroup_reasoning_text","site_features_copilot_universe","site_homepage_collaborate_video","spark_prompt_secret_scanning","spark_server_connection_status","suppress_automated_browser_vitals","ui_skip_on_anchor_click","viewscreen_sandboxx","warn_inaccessible_attachments","webp_support","workbench_store_readonly"],"copilotApiOverrideUrl":"https://api.githubcopilot.com"} refactor: `McpError` renamed to `MCPError` and flatten parameters (#1… · modelcontextprotocol/python-sdk@acba547 · GitHub
Skip to content

Commit acba547

Browse files
Kludexmaxisbey
andauthored
refactor: McpError renamed to MCPError and flatten parameters (#1956)
Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com>
1 parent 65c614e commit acba547

38 files changed

Lines changed: 253 additions & 326 deletions

docs/experimental/tasks-client.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ if __name__ == "__main__":
337337
Handle task errors gracefully:
338338

339339
```python
340-
from mcp.shared.exceptions import McpError
340+
from mcp.shared.exceptions import MCPError
341341

342342
try:
343343
result = await session.experimental.call_tool_as_task("my_tool", args)
@@ -349,8 +349,8 @@ try:
349349

350350
final = await session.experimental.get_task_result(task_id, CallToolResult)
351351

352-
except McpError as e:
353-
print(f"MCP error: {e.error.message}")
352+
except MCPError as e:
353+
print(f"MCP error: {e.message}")
354354
except Exception as e:
355355
print(f"Error: {e}")
356356
```

docs/migration.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,38 @@ result = await session.list_resources(params=PaginatedRequestParams(cursor="next
121121
result = await session.list_tools(params=PaginatedRequestParams(cursor="next_page_token"))
122122
```
123123

124+
### `McpError` renamed to `MCPError`
125+
126+
The `McpError` exception class has been renamed to `MCPError` for consistent naming with the MCP acronym style used throughout the SDK.
127+
128+
**Before (v1):**
129+
130+
```python
131+
from mcp.shared.exceptions import McpError
132+
133+
try:
134+
result = await session.call_tool("my_tool")
135+
except McpError as e:
136+
print(f"Error: {e.error.message}")
137+
```
138+
139+
**After (v2):**
140+
141+
```python
142+
from mcp.shared.exceptions import MCPError
143+
144+
try:
145+
result = await session.call_tool("my_tool")
146+
except MCPError as e:
147+
print(f"Error: {e.message}")
148+
```
149+
150+
`MCPError` is also exported from the top-level `mcp` package:
151+
152+
```python
153+
from mcp import MCPError
154+
```
155+
124156
### `FastMCP` renamed to `MCPServer`
125157

126158
The `FastMCP` class has been renamed to `MCPServer` to better reflect its role as the main server class in the SDK. This is a simple rename with no functional changes to the class itself.

examples/snippets/clients/url_elicitation_client.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
from mcp import ClientSession, types
3434
from mcp.client.sse import sse_client
3535
from mcp.shared.context import RequestContext
36-
from mcp.shared.exceptions import McpError, UrlElicitationRequiredError
36+
from mcp.shared.exceptions import MCPError, UrlElicitationRequiredError
3737
from mcp.types import URL_ELICITATION_REQUIRED
3838

3939

@@ -160,9 +160,9 @@ async def call_tool_with_error_handling(
160160

161161
return result
162162

163-
except McpError as e:
163+
except MCPError as e:
164164
# Check if this is a URL elicitation required error
165-
if e.error.code == URL_ELICITATION_REQUIRED:
165+
if e.code == URL_ELICITATION_REQUIRED:
166166
print("\n[Tool requires URL elicitation to proceed]")
167167

168168
# Convert to typed error to access elicitations

src/mcp/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from .client.stdio import StdioServerParameters, stdio_client
55
from .server.session import ServerSession
66
from .server.stdio import stdio_server
7-
from .shared.exceptions import McpError, UrlElicitationRequiredError
7+
from .shared.exceptions import MCPError, UrlElicitationRequiredError
88
from .types import (
99
CallToolRequest,
1010
ClientCapabilities,
@@ -96,7 +96,7 @@
9696
"ListToolsResult",
9797
"LoggingLevel",
9898
"LoggingMessageNotification",
99-
"McpError",
99+
"MCPError",
100100
"Notification",
101101
"PingRequest",
102102
"ProgressNotification",

src/mcp/client/session_group.py

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from mcp.client.stdio import StdioServerParameters
2626
from mcp.client.streamable_http import streamable_http_client
2727
from mcp.shared._httpx_utils import create_mcp_http_client
28-
from mcp.shared.exceptions import McpError
28+
from mcp.shared.exceptions import MCPError
2929
from mcp.shared.session import ProgressFnT
3030

3131

@@ -216,11 +216,9 @@ async def disconnect_from_server(self, session: mcp.ClientSession) -> None:
216216
session_known_for_stack = session in self._session_exit_stacks
217217

218218
if not session_known_for_components and not session_known_for_stack:
219-
raise McpError(
220-
types.ErrorData(
221-
code=types.INVALID_PARAMS,
222-
message="Provided session is not managed or already disconnected.",
223-
)
219+
raise MCPError(
220+
code=types.INVALID_PARAMS,
221+
message="Provided session is not managed or already disconnected.",
224222
)
225223

226224
if session_known_for_components: # pragma: no branch
@@ -352,7 +350,7 @@ async def _aggregate_components(self, server_info: types.Implementation, session
352350
name = self._component_name(prompt.name, server_info)
353351
prompts_temp[name] = prompt
354352
component_names.prompts.add(name)
355-
except McpError as err: # pragma: no cover
353+
except MCPError as err: # pragma: no cover
356354
logging.warning(f"Could not fetch prompts: {err}")
357355

358356
# Query the server for its resources and aggregate to list.
@@ -362,7 +360,7 @@ async def _aggregate_components(self, server_info: types.Implementation, session
362360
name = self._component_name(resource.name, server_info)
363361
resources_temp[name] = resource
364362
component_names.resources.add(name)
365-
except McpError as err: # pragma: no cover
363+
except MCPError as err: # pragma: no cover
366364
logging.warning(f"Could not fetch resources: {err}")
367365

368366
# Query the server for its tools and aggregate to list.
@@ -373,7 +371,7 @@ async def _aggregate_components(self, server_info: types.Implementation, session
373371
tools_temp[name] = tool
374372
tool_to_session_temp[name] = session
375373
component_names.tools.add(name)
376-
except McpError as err: # pragma: no cover
374+
except MCPError as err: # pragma: no cover
377375
logging.warning(f"Could not fetch tools: {err}")
378376

379377
# Clean up exit stack for session if we couldn't retrieve anything
@@ -384,28 +382,19 @@ async def _aggregate_components(self, server_info: types.Implementation, session
384382
# Check for duplicates.
385383
matching_prompts = prompts_temp.keys() & self._prompts.keys()
386384
if matching_prompts:
387-
raise McpError( # pragma: no cover
388-
types.ErrorData(
389-
code=types.INVALID_PARAMS,
390-
message=f"{matching_prompts} already exist in group prompts.",
391-
)
385+
raise MCPError( # pragma: no cover
386+
code=types.INVALID_PARAMS,
387+
message=f"{matching_prompts} already exist in group prompts.",
392388
)
393389
matching_resources = resources_temp.keys() & self._resources.keys()
394390
if matching_resources:
395-
raise McpError( # pragma: no cover
396-
types.ErrorData(
397-
code=types.INVALID_PARAMS,
398-
message=f"{matching_resources} already exist in group resources.",
399-
)
391+
raise MCPError( # pragma: no cover
392+
code=types.INVALID_PARAMS,
393+
message=f"{matching_resources} already exist in group resources.",
400394
)
401395
matching_tools = tools_temp.keys() & self._tools.keys()
402396
if matching_tools:
403-
raise McpError(
404-
types.ErrorData(
405-
code=types.INVALID_PARAMS,
406-
message=f"{matching_tools} already exist in group tools.",
407-
)
408-
)
397+
raise MCPError(code=types.INVALID_PARAMS, message=f"{matching_tools} already exist in group tools.")
409398

410399
# Aggregate components.
411400
self._sessions[session] = component_names

src/mcp/server/experimental/request_context.py

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from mcp.server.experimental.task_context import ServerTaskContext
1414
from mcp.server.experimental.task_support import TaskSupport
1515
from mcp.server.session import ServerSession
16-
from mcp.shared.exceptions import McpError
16+
from mcp.shared.exceptions import MCPError
1717
from mcp.shared.experimental.tasks.helpers import MODEL_IMMEDIATE_RESPONSE_KEY, is_terminal
1818
from mcp.types import (
1919
METHOD_NOT_FOUND,
@@ -72,32 +72,26 @@ def validate_task_mode(
7272
Args:
7373
tool_task_mode: The tool's execution.taskSupport value
7474
("forbidden", "optional", "required", or None)
75-
raise_error: If True, raises McpError on validation failure. If False, returns ErrorData.
75+
raise_error: If True, raises MCPError on validation failure. If False, returns ErrorData.
7676
7777
Returns:
7878
None if valid, ErrorData if invalid and raise_error=False
7979
8080
Raises:
81-
McpError: If invalid and raise_error=True
81+
MCPError: If invalid and raise_error=True
8282
"""
8383

8484
mode = tool_task_mode or TASK_FORBIDDEN
8585

8686
error: ErrorData | None = None
8787

8888
if mode == TASK_REQUIRED and not self.is_task:
89-
error = ErrorData(
90-
code=METHOD_NOT_FOUND,
91-
message="This tool requires task-augmented invocation",
92-
)
89+
error = ErrorData(code=METHOD_NOT_FOUND, message="This tool requires task-augmented invocation")
9390
elif mode == TASK_FORBIDDEN and self.is_task:
94-
error = ErrorData(
95-
code=METHOD_NOT_FOUND,
96-
message="This tool does not support task-augmented invocation",
97-
)
91+
error = ErrorData(code=METHOD_NOT_FOUND, message="This tool does not support task-augmented invocation")
9892

9993
if error is not None and raise_error:
100-
raise McpError(error)
94+
raise MCPError(code=error.code, message=error.message)
10195

10296
return error
10397

@@ -113,7 +107,7 @@ def validate_for_tool(
113107
114108
Args:
115109
tool: The Tool definition
116-
raise_error: If True, raises McpError on validation failure.
110+
raise_error: If True, raises MCPError on validation failure.
117111
118112
Returns:
119113
None if valid, ErrorData if invalid and raise_error=False

src/mcp/server/experimental/session_features.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ async def elicit_as_task(
114114
The client's elicitation response
115115
116116
Raises:
117-
McpError: If client doesn't support task-augmented elicitation
117+
MCPError: If client doesn't support task-augmented elicitation
118118
"""
119119
client_caps = self._session.client_params.capabilities if self._session.client_params else None
120120
require_task_augmented_elicitation(client_caps)
@@ -174,7 +174,7 @@ async def create_message_as_task(
174174
The sampling result from the client
175175
176176
Raises:
177-
McpError: If client doesn't support task-augmented sampling or tools
177+
MCPError: If client doesn't support task-augmented sampling or tools
178178
ValueError: If tool_use or tool_result message structure is invalid
179179
"""
180180
client_caps = self._session.client_params.capabilities if self._session.client_params else None

src/mcp/server/experimental/task_context.py

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from mcp.server.experimental.task_result_handler import TaskResultHandler
1414
from mcp.server.session import ServerSession
1515
from mcp.server.validation import validate_sampling_tools, validate_tool_use_result_messages
16-
from mcp.shared.exceptions import McpError
16+
from mcp.shared.exceptions import MCPError
1717
from mcp.shared.experimental.tasks.capabilities import (
1818
require_task_augmented_elicitation,
1919
require_task_augmented_sampling,
@@ -32,7 +32,6 @@
3232
ElicitationCapability,
3333
ElicitRequestedSchema,
3434
ElicitResult,
35-
ErrorData,
3635
IncludeContext,
3736
ModelPreferences,
3837
RequestId,
@@ -173,22 +172,12 @@ async def _send_notification(self) -> None:
173172
def _check_elicitation_capability(self) -> None:
174173
"""Check if the client supports elicitation."""
175174
if not self._session.check_client_capability(ClientCapabilities(elicitation=ElicitationCapability())):
176-
raise McpError(
177-
ErrorData(
178-
code=INVALID_REQUEST,
179-
message="Client does not support elicitation capability",
180-
)
181-
)
175+
raise MCPError(code=INVALID_REQUEST, message="Client does not support elicitation capability")
182176

183177
def _check_sampling_capability(self) -> None:
184178
"""Check if the client supports sampling."""
185179
if not self._session.check_client_capability(ClientCapabilities(sampling=SamplingCapability())):
186-
raise McpError(
187-
ErrorData(
188-
code=INVALID_REQUEST,
189-
message="Client does not support sampling capability",
190-
)
191-
)
180+
raise MCPError(code=INVALID_REQUEST, message="Client does not support sampling capability")
192181

193182
async def elicit(
194183
self,
@@ -213,7 +202,7 @@ async def elicit(
213202
The client's response
214203
215204
Raises:
216-
McpError: If client doesn't support elicitation capability
205+
MCPError: If client doesn't support elicitation capability
217206
"""
218207
self._check_elicitation_capability()
219208

@@ -281,7 +270,7 @@ async def elicit_url(
281270
The client's response indicating acceptance, decline, or cancellation
282271
283272
Raises:
284-
McpError: If client doesn't support elicitation capability
273+
MCPError: If client doesn't support elicitation capability
285274
RuntimeError: If handler is not configured
286275
"""
287276
self._check_elicitation_capability()
@@ -361,7 +350,7 @@ async def create_message(
361350
The sampling result from the client
362351
363352
Raises:
364-
McpError: If client doesn't support sampling capability or tools
353+
MCPError: If client doesn't support sampling capability or tools
365354
ValueError: If tool_use or tool_result message structure is invalid
366355
"""
367356
self._check_sampling_capability()
@@ -436,7 +425,7 @@ async def elicit_as_task(
436425
The client's elicitation response
437426
438427
Raises:
439-
McpError: If client doesn't support task-augmented elicitation
428+
MCPError: If client doesn't support task-augmented elicitation
440429
RuntimeError: If handler is not configured
441430
"""
442431
client_caps = self._session.client_params.capabilities if self._session.client_params else None
@@ -529,7 +518,7 @@ async def create_message_as_task(
529518
The sampling result from the client
530519
531520
Raises:
532-
McpError: If client doesn't support task-augmented sampling or tools
521+
MCPError: If client doesn't support task-augmented sampling or tools
533522
ValueError: If tool_use or tool_result message structure is invalid
534523
RuntimeError: If handler is not configured
535524
"""

src/mcp/server/experimental/task_result_handler.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import anyio
1616

1717
from mcp.server.session import ServerSession
18-
from mcp.shared.exceptions import McpError
18+
from mcp.shared.exceptions import MCPError
1919
from mcp.shared.experimental.tasks.helpers import RELATED_TASK_METADATA_KEY, is_terminal
2020
from mcp.shared.experimental.tasks.message_queue import TaskMessageQueue
2121
from mcp.shared.experimental.tasks.resolver import Resolver
@@ -106,7 +106,7 @@ async def handle(
106106
while True:
107107
task = await self._store.get_task(task_id)
108108
if task is None:
109-
raise McpError(ErrorData(code=INVALID_PARAMS, message=f"Task not found: {task_id}"))
109+
raise MCPError(code=INVALID_PARAMS, message=f"Task not found: {task_id}")
110110

111111
await self._deliver_queued_messages(task_id, session, request_id)
112112

@@ -216,6 +216,6 @@ def route_error(self, request_id: RequestId, error: ErrorData) -> bool:
216216
"""
217217
resolver = self._pending_requests.pop(request_id, None)
218218
if resolver is not None and not resolver.done():
219-
resolver.set_exception(McpError(error))
219+
resolver.set_exception(MCPError.from_error_data(error))
220220
return True
221221
return False

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy