fix(agentgateway): guard mcp list_tools null responses#226
Open
tiagoek wants to merge 14 commits into
Open
Conversation
When MCP instrumentation returns None from list_tools(), skip the fragment with a clear warning instead of raising AttributeError on result.tools.
8c36868 to
83c5dae
Compare
Required for src/ change CI version check; ruff format on new tests.
Unwrap opentelemetry-instrumentation-mcp at the end of auto_instrument() so list_tools is not silently broken by @dont_throw wrappers. Log a user_token hint when LoB system-token tool listing returns HTTP 403. Bump version to 0.35.2.
…to_instrument unwrap
Contributor
Author
SDK Module Review
Findings (1)
1 finding(s): 1 posted as inline comment(s) on the affected lines, 0 not tied to a code line (listed above). Generated by sdk-review-skill · v1 |
LucasAlvesSoares
requested changes
Jul 15, 2026
Remove reflection-based OpenTelemetry MCP unwrap from SDK init per review. Keep Agent Gateway None guards, HTTP 403 hints, and document agent-side unwrap as an optional workaround until upstream instrumentation fixes land.
tiagoek
commented
Jul 15, 2026
| ) | ||
| # intentional: fragment failure must not abort remaining fragments | ||
| # (HTTPStatusError: 403 → warning + continue; other status → exception log + skip) | ||
| except httpx.HTTPStatusError as exc: |
Contributor
Author
There was a problem hiding this comment.
[FLAG] PY-EL-02
except block does not end with raise — swallowing? Add re-raise or comment justifying suppression
Document intentional HTTPStatusError swallow when skipping a failed MCP fragment.
| result = await session.list_tools() | ||
|
|
||
| if result is None or result.tools is None: | ||
| logger.warning( |
Contributor
There was a problem hiding this comment.
Why review OTel instrumentation?
| if exc.response.status_code == 403: | ||
| logger.warning( | ||
| "HTTP 403 listing tools from fragment '%s' with system token — " | ||
| "MCP list_tools may require a user-scoped token; use Phase 2 flow " |
Contributor
There was a problem hiding this comment.
What is phase 2 flow?
| ) | ||
| # intentional: fragment failure must not abort remaining fragments | ||
| # (HTTPStatusError: 403 → warning + continue; other status → exception log + skip) | ||
| except httpx.HTTPStatusError as exc: # sdk-review: ignore[el-02] |
Contributor
There was a problem hiding this comment.
Comments of sdk-review in the code is not nice
| ) | ||
| # intentional: fragment failure must not abort remaining fragments | ||
| # (unexpected errors → exception log + skip) | ||
| except Exception: |
Contributor
There was a problem hiding this comment.
This should still be executed if all fragments fail to load. And who requested this behaviour?
| from litellm import completion | ||
| # LLM calls are now automatically traced | ||
| ``` | ||
| If OpenTelemetry MCP instrumentation (`opentelemetry-instrumentation-mcp`) swallows protocol errors and `list_tools()` returns `None`, the Agent Gateway SDK logs a warning and skips that fragment instead of crashing (SDK 0.35.2+). Removing instrumentation is not recommended. Until upstream fixes land, agents may keep an application-side unwrap after `auto_instrument()` (see Agent Gateway user guide — OpenTelemetry and MCP). |
Contributor
There was a problem hiding this comment.
list_tools doesn't exist, it's list_mcp_tools
Replace internal Phase 2 wording with user_token/list_mcp_tools hints, remove sdk-review inline suppression, warn when all fragments fail, soften customer None-guard log, and align user guides with public API naming. Bump version to 0.35.3.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Hardens Agent Gateway MCP tool discovery for LoB and customer flows when OpenTelemetry MCP instrumentation or auth mismatches produce empty or null tool lists.
Changes:
Defensive
list_toolshandling (LoB + customer) — Inlist_server_tools()/_list_server_tools(), ifsession.list_tools()returnsNoneortoolsisNone(often whenopentelemetry-instrumentation-mcpswallows errors via@dont_throw), the SDK logs a warning and returns an empty list for that fragment so discovery continues with other fragments. AvoidsAttributeError: 'NoneType' object has no attribute 'tools'.LoB HTTP 403 diagnostic hint — When system-token tool listing fails with HTTP 403 in the LoB flow, log guidance to use user-scoped discovery (
user_tokenonlist_mcp_tools()) where the landscape requires it.Version bump —
0.35.2.Documentation — Troubleshooting notes in the Agent Gateway and telemetry user guides (null tool lists, dual-path
user_tokenanti-pattern, optional agent-side MCP OTel unwrap until upstream fixes; SDK does not strip instrumentation inauto_instrument()).Out of scope / not fixed by this PR:
user_tokenon some call sites — agent-side ContextVar / dual-path auth fixes, not SDK behavior changes.auto_instrument()— removed after review; agents may keep documentedmain.pyunwrap workarounds without disabling telemetry globally.agent_memoryOAuth in CI — unrelated to this change set.Jira: N/A
Related Issue
N/A (SDK hardening from internal community-support triage; no public GitHub issue in this repo)
Type of Change
Please check the relevant option:
How to Test
uv run pytest tests/agentgateway/unit/test_lob.py -vuv run pytest tests/core/unit/telemetry/test_auto_instrument.py -vlist_tools()returningNoneyields[]with a warning; HTTP 403 on system-token listing logs auser_tokenhint.Checklist
Before submitting your PR, please review and check the following:
Breaking Changes
None.
Additional Notes
user_tokenon everylist_mcp_tools()call that needs user-scoped tools (see user guide Troubleshooting).list_toolssymptoms are addressed by the None guard; optional agent-side unwrap remains documented for cases where instrumentation still returns null payloads.