Skip to content

ref(mcp): Separate tool, prompt and resource patches#6726

Draft
alexander-alderman-webb wants to merge 5 commits into
masterfrom
webb/mcp/seperate-handlers
Draft

ref(mcp): Separate tool, prompt and resource patches#6726
alexander-alderman-webb wants to merge 5 commits into
masterfrom
webb/mcp/seperate-handlers

Conversation

@alexander-alderman-webb

Copy link
Copy Markdown
Contributor

Description

Issues

Reminders

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Codecov Results 📊

90048 passed | ⏭️ 6298 skipped | Total: 96346 | Pass Rate: 93.46% | Execution Time: 313m 29s

📊 Comparison with Base Branch

Metric Change
Total Tests
Passed Tests
Failed Tests
Skipped Tests

✨ No test changes detected

All tests are passing successfully.

❌ Patch coverage is 69.51%. Project has 2477 uncovered lines.
❌ Project coverage is 89.65%. Comparing base (base) to head (head).

Files with missing lines (1)
File Patch % Lines
sentry_sdk/integrations/mcp.py 69.51% ⚠️ 50 Missing and 9 partials
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
- Coverage    89.77%    89.65%    -0.12%
==========================================
  Files          192       192         —
  Lines        23824     23923       +99
  Branches      8226      8250       +24
==========================================
+ Hits         21386     21446       +60
- Misses        2438      2477       +39
- Partials      1349      1354        +5

Generated by Codecov Action

Comment thread sentry_sdk/integrations/mcp.py
Comment thread sentry_sdk/integrations/mcp.py

@sentry-warden sentry-warden Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

handler_name may be unbound in _extract_handler_data_from_args for tool and prompt types

In _extract_handler_data_from_args (mcp.py ~line 423), if original_args is empty and original_kwargs.get("name") is falsy, handler_name is never assigned for handler_type == "tool" or "prompt", causing an UnboundLocalError when it is referenced at return handler_name, arguments (tool) or arguments = {"name": handler_name, ...} (prompt). Add an else: handler_name = "unknown" fallback in both branches.

Evidence
  • _extract_handler_data_from_args lines 422-446: both tool and prompt branches assign handler_name only under if original_args: or elif original_kwargs.get("name"):, with no else clause.
  • For the prompt branch, handler_name is immediately used on the very next line: arguments = {"name": handler_name, **(arguments or {})}, so an UnboundLocalError is raised before return.
  • For the tool branch, handler_name is used in the shared return handler_name, arguments at line ~455.
  • _prepare_handler_data reaches _extract_handler_data_from_args when both params is None and _is_v2_context(original_args) is False (e.g., empty original_args in a v2 kwargs-only call).
  • The resource branch correctly initialises handler_name = "unknown" before any conditional, confirming the fix pattern is known.

Identified by Warden find-bugs

@sentry-warden sentry-warden Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

UnboundLocalError when tool/prompt handler called with no args and no kwargs name

In _extract_handler_data_from_args, handler_name is only assigned inside if original_args: / elif original_kwargs.get("name"): branches for the "tool" and "prompt" types; if both conditions are false, handler_name is never set. The prompt branch then immediately dereferences it at arguments = {"name": handler_name, ...}, raising UnboundLocalError at runtime.

Evidence
  • _extract_handler_data_from_args (mcp.py ~line 407) handles "tool" and "prompt" with if original_args: handler_name = ... / elif original_kwargs.get("name"): handler_name = ... — no else clause and no default value.
  • For "prompt", line 446 unconditionally reads handler_name in arguments = {"name": handler_name, **(arguments or {})} before the function returns.
  • For "tool", the unbound name would surface at return handler_name, arguments.
  • The "resource" branch correctly defaults to handler_name = "unknown" first, so only tool and prompt are affected.
  • _prepare_handler_data calls this function on the non-v2 code path (line 486) without any guard against empty args.

Identified by Warden code-review

@sentry-warden sentry-warden Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

UnboundLocalError when original_args is empty and original_kwargs has no 'name' key in _extract_handler_data_from_args

For handler_type == 'tool' and handler_type == 'prompt', handler_name is assigned only inside if/elif branches with no else fallback; if both conditions are falsy the variable is unbound and will raise UnboundLocalError — for 'prompt' the crash occurs immediately at arguments = {'name': handler_name, ...} inside the function.

Evidence
  • _extract_handler_data_from_args (mcp.py ~line 421): if original_args: handler_name = ... / elif original_kwargs.get('name'): handler_name = ... — no else clause for either the 'tool' or 'prompt' branch.
  • The 'resource' branch correctly initialises handler_name = 'unknown' before the conditionals, showing the pattern is inconsistent.
  • For 'prompt', handler_name is dereferenced immediately within the same function at arguments = {'name': handler_name, ...} (line ~445), so an empty call with no positional args and no kwargs 'name' crashes before returning.
  • _prepare_handler_data calls this function via the else branch when params is None and _is_v2_context is False, so v1 stdio callers with missing arguments hit this path.

Identified by Warden find-bugs

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant