Skip to content

refactor(mcp): upgrade SDK2 while preserving legacy gateway behavior - #41718

Merged
joshua-berri merged 26 commits into
mainfrom
litellm_mcp_dependency_gate_7737
Sep 19, 2026
Merged

joshua-berri merged 26 commits into
mainfrom
litellm_mcp_dependency_gate_7737

Conversation

@joshua-berri

@joshua-berri joshua-berri commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

  • litellm[proxy] pins mcp<2, so operators cannot install MCP SDK 2
  • SDK 2 renames the APIs the gateway and its clients are built on
  • Existing MCP clients must keep the same responses after the upgrade
  • Repeated suites and background discovery inflated test latency

How it solves it:

  • Raise the MCP extras to SDK 2 and port the gateway to its APIs
  • Keep error statuses, progress tokens, sampling ids, and REST wire fields
  • Answer modern-only MCP-Protocol-Version headers with HTTP 400 for now
  • Prove an unchanged SDK 1 LangChain client from an isolated environment
  • Run the MCP integration suite once inside the existing unit test matrix

This finishes LIT-7737 as the dependency upgrade plus the minimum legacy parity work. The HTTPX2 transport and auth, signing, and server-import changes are required compatibility work; the remaining LIT-7738, LIT-7739, and LIT-7740 functionality keeps its planned order, and LIT-3467 and LIT-4506 keep their independent test ownership. The Phase 0 release, rollback demonstration, and LIT-7754 canary observation remain required before modern behavior is enabled

Review-driven changes on this branch: .github/workflows/test-mcp.yml is gone and the existing unit test matrix runs tests/mcp_tests once as mcp-integration with the shared runner and coverage upload, the only job that installs the isolated SDK 1 peer, inside the existing dependency setup allowance. HTTP 404 responses now reach the SDK's own protocol handling, with regressions for an expired session, a JSON-RPC error carried by HTTP 404, an initial HTTP 404, and a fresh operation on a new session, and no automatic replay of tool side effects. Cisco inspection serializes image, audio, and embedded-resource fields with MCP wire aliases for direct SDK results and logging wrappers. Configuration-only tests no longer launch background upstream discovery, shared request-context fixtures replace repeated helpers, and the new dependency matrix runs install and import checks without multiplying the full suites by Python version, skipping its expensive steps for unrelated backend, UI, or docs changes while keeping check reporting. Main was merged at 6718fd6 without conflicts

User Flow

Before: an operator who needs MCP SDK 2 in the gateway's Python environment cannot install it, so they stay on SDK 1

  1. They run uv pip install 'litellm[proxy]==1.101.0' 'mcp>=2.2,<3'
  2. The install stops with No solution found when resolving dependencies: litellm[proxy]==1.101.0 depends on mcp>=1.28.1,<2.0, and nothing is installed
  3. They keep SDK 1 and start the proxy with their MCP servers configured
  4. Their MCP client sends POST https://litellm-domain/mcp with an initialize body naming "protocolVersion": "2025-06-18" and gets HTTP 200 with "protocolVersion": "2025-06-18"
  5. The client sends tools/list then tools/call for math_stdio-add with {"a": 3, "b": 4} on the same route and gets the tool list and {"content":[{"type":"text","text":"7"}],"structuredContent":{"result":7},"isError":false}
  6. A client that adds the header MCP-Protocol-Version: 2026-07-28 to that POST gets HTTP 200, the header ignored, and the same legacy session as before

After: the same operator installs SDK 2 and every existing client gets the same responses it got before

  1. They run uv pip install 'litellm[proxy]' 'mcp>=2.2,<3'
  2. The install resolves and pulls in mcp 2.2, httpx2, and pydantic 2.12 or newer
  3. They start the proxy with the same MCP servers configured
  4. Their MCP client sends the same POST https://litellm-domain/mcp initialize body and gets HTTP 200 with "protocolVersion": "2025-06-18"
  5. The same tools/list and tools/call return the same tool list and the same {"content":[{"type":"text","text":"7"}],"structuredContent":{"result":7},"isError":false}, and an SDK 1 LangChain client running in another environment lists and calls the tools unchanged
  6. A client that adds the header MCP-Protocol-Version: 2026-07-28 now gets HTTP 400 with JSON-RPC error -32600 Unsupported MCP-Protocol-Version 2026-07-28; supported: 2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25, until modern MCP behavior ships in a later phase

Relevant issues

Includes the Python 3.14 dependency-floor prerequisites from #41706, which is closed in favor of this PR. The agreed overlap and remaining acceptance are recorded in LIT-7737, LIT-7738, LIT-7739, and LIT-7740

Affected release

Linear ticket

Resolves LIT-7737

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have added meaningful tests
  • The handful of test files covering my change pass locally, e.g. uv run pytest tests/test_litellm/<your_test_file>.py -v. Leave the suites (make test-unit-*, make test-unit) to CI: it finishes in ~15 minutes where a laptop takes an hour or more
  • My PR passes all required CI/CD checks (e.g., lint, schema.d.ts sync check, etc.)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review (Greptile reviews automatically once the PR is opened; only comment @greptileai to re-request a review after pushing changes)

Delays in PR merge?

If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).

Screenshots / Proof of Fix

QA run at 78e1103, verdict PASS: the merge base cannot install MCP SDK 2 next to the proxy and this PR can, while Claude Code, an unchanged SDK 1 LangChain client, a stock SDK 2 client, and raw curl get the same results on both legs

Each leg is one proxy booted from a source checkout with 2 uvicorn workers and no database, in front of the same two upstream MCP servers: an SDK 1 (mcp==1.28.1) math server over stdio, and the same server over streamable HTTP started with MCP_ADD_OFFSET=100, so add(3,4) is 7 over stdio and 107 over HTTP. Before is the merge base 6718fd6 with mcp 1.28.1 on http://127.0.0.1:58904. After is this PR's head with mcp 2.2.0, httpx2 2.13.0, and pydantic 2.13.4 on http://127.0.0.1:58906. sk-1234 is a local fixture key and no LLM call is involved

Proxy config for both legs, where only the upstream port differs (58905 before, 58907 after):

general_settings:
  master_key: sk-1234
litellm_settings:
  drop_params: true
mcp_servers:
  math_stdio:
    transport: stdio
    command: <sdk1 venv>/bin/python
    args: [<scratch>/upstream_server.py]
    allow_all_keys: true
  math_streamable_http:
    transport: http
    url: http://127.0.0.1:<upstream port>/mcp
    allow_all_keys: true
MCP_ADD_OFFSET=100 <sdk1 venv>/bin/python upstream_server.py --transport http --host 127.0.0.1 --port <upstream port>
.venv/bin/python litellm/proxy/proxy_cli.py --config <leg>.yaml --host 127.0.0.1 --port <port> --num_workers 2

upstream_server.py is a copy of the merge base's tests/mcp_tests/mcp_server.py. Set P to the leg's URL and define:

rpc() { curl -sS -w '\nHTTP %{http_code}\n' "$P/mcp" -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' -H "MCP-Protocol-Version: $1" -H 'Authorization: Bearer sk-1234' -d "$2"; }

The SDK 1 LangChain client, run from an isolated mcp==1.28.1 plus langchain-mcp-adapters==0.2.1 environment:

import asyncio
import json
import sys

from langchain_mcp_adapters.tools import load_mcp_tools
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client


async def main() -> None:
    async with streamablehttp_client(sys.argv[1] + "/mcp", headers={"Authorization": "Bearer sk-1234"}) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            tools = await load_mcp_tools(session)
            print("tools:", sorted(tool.name for tool in tools))
            results = {}
            for name in ("math_stdio-add", "math_streamable_http-add"):
                tool = next(tool for tool in tools if tool.name == name)
                results[name] = await tool.ainvoke({"a": 3, "b": 4})
            print(json.dumps(results))


asyncio.run(main())

The stock SDK 2 client, run from an mcp==2.2.0 environment:

import asyncio
import sys

from mcp import ClientSession
from mcp.client.streamable_http import create_mcp_http_client, streamable_http_client


async def main() -> None:
    async with create_mcp_http_client(headers={"Authorization": "Bearer sk-1234"}) as http_client:
        async with streamable_http_client(sys.argv[1] + "/mcp", http_client=http_client) as streams:
            async with ClientSession(streams[0], streams[1]) as session:
                init = await session.initialize()
                print("negotiated:", init.model_dump(by_alias=True).get("protocolVersion"))
                tools = await session.list_tools()
                print("tools:", sorted(tool.name for tool in tools.tools))
                for name in ("math_stdio-add", "math_streamable_http-add"):
                    result = await session.call_tool(name, {"a": 3, "b": 4})
                    print(name, "->", result.model_dump(by_alias=True).get("structuredContent"))


asyncio.run(main())

Claude Code v2.1.278 was driven interactively in its TUI under tmux on both legs, started with claude --mcp-config claude-mcp.json --strict-mcp-config, where claude-mcp.json is:

{"mcpServers":{"litellm":{"type":"http","url":"http://127.0.0.1:<port>/mcp","headers":{"Authorization":"Bearer sk-1234"}}}}

Before (6718fd6, mcp 1.28.1, http://127.0.0.1:58904)

  1. Installing SDK 2 next to the proxy fails
$ uv pip install --dry-run --python .venv/bin/python '.[proxy]' 'mcp>=2.2,<3'
  × No solution found when resolving dependencies:
  ╰─▶ Because only litellm[proxy]==1.103.0 is available and
      litellm[proxy]==1.103.0 depends on mcp>=1.28.1,<2.0, we can conclude
      that all versions of litellm[proxy] depend on mcp>=1.28.1,<2.0.
      And because you require mcp>=2.2,<3 and litellm[proxy], we can conclude
      that your requirements are unsatisfiable.
  1. In Claude Code, /mcp shows litellm connected with 6 tools

pr41718-78e1103bb8-before-claude-mcp.png

  1. The prompt "Use the litellm MCP server's math_stdio-add tool to add 3 and 4, then its math_streamable_http-add tool to add 3 and 4. Reply with only the two tool results." asks permission for each tool call, and after choosing "1. Yes" twice it answers 7 and 107

pr41718-78e1103bb8-before-claude-result.png

  1. The SDK 1 LangChain client lists and calls the tools
$ <sdk1 venv>/bin/python langchain_client.py http://127.0.0.1:58904
tools: ['math_stdio-add', 'math_stdio-multiply', 'math_stdio-request_headers', 'math_streamable_http-add', 'math_streamable_http-multiply', 'math_streamable_http-request_headers']
{"math_stdio-add": [{"type": "text", "text": "7", "id": "lc_34a8234d-88d6-40e1-9d5a-cd7f8b19246e"}], "math_streamable_http-add": [{"type": "text", "text": "107", "id": "lc_02160dcc-b634-471d-b571-4746a7a0dcc1"}]}
  1. The stock SDK 2 client lists and calls the tools
$ <sdk2 venv>/bin/python sdk2_client.py http://127.0.0.1:58904
negotiated: 2025-11-25
tools: ['math_stdio-add', 'math_stdio-multiply', 'math_stdio-request_headers', 'math_streamable_http-add', 'math_streamable_http-multiply', 'math_streamable_http-request_headers']
math_stdio-add -> {'result': 7}
math_streamable_http-add -> {'result': 107}
  1. Raw JSON-RPC over POST /mcp, where tools/list is trimmed to its status and tool names
$ rpc 2025-06-18 '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"legacy-parity","version":"1"}}}'
event: message
data: {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-06-18","capabilities":{"experimental":{},"prompts":{"listChanged":false},"resources":{"subscribe":false,"listChanged":false},"tools":{"listChanged":false}},"serverInfo":{"name":"litellm-mcp-server","version":"1.0.0"}}}

HTTP 200
$ rpc 2025-06-18 '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' | grep -o '"name":"[^"]*"\|^HTTP [0-9]*' | sort -u
"name":"math_stdio-add"
"name":"math_stdio-multiply"
"name":"math_stdio-request_headers"
"name":"math_streamable_http-add"
"name":"math_streamable_http-multiply"
"name":"math_streamable_http-request_headers"
HTTP 200
$ rpc 2025-06-18 '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"math_stdio-add","arguments":{"a":3,"b":4}}}'
event: message
data: {"jsonrpc":"2.0","id":3,"result":{"content":[{"type":"text","text":"7"}],"structuredContent":{"result":7},"isError":false}}

HTTP 200
$ rpc 2025-06-18 '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"math_streamable_http-add","arguments":{"a":3,"b":4}}}'
event: message
data: {"jsonrpc":"2.0","id":4,"result":{"content":[{"type":"text","text":"107"}],"structuredContent":{"result":107},"isError":false}}

HTTP 200
  1. A modern-only MCP-Protocol-Version header on a legacy body is ignored
$ rpc 2026-07-28 '{"jsonrpc":"2.0","id":5,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"legacy-parity","version":"1"}}}'
event: message
data: {"jsonrpc":"2.0","id":5,"result":{"protocolVersion":"2025-06-18","capabilities":{"experimental":{},"prompts":{"listChanged":false},"resources":{"subscribe":false,"listChanged":false},"tools":{"listChanged":false}},"serverInfo":{"name":"litellm-mcp-server","version":"1.0.0"}}}

HTTP 200
  1. A future version in the initialize body with no header negotiates down
$ curl -sS -w '\nHTTP %{http_code}\n' "$P/mcp" -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' -H 'Authorization: Bearer sk-1234' -d '{"jsonrpc":"2.0","id":6,"method":"initialize","params":{"protocolVersion":"2026-07-28","capabilities":{},"clientInfo":{"name":"legacy-parity","version":"1"}}}'
event: message
data: {"jsonrpc":"2.0","id":6,"result":{"protocolVersion":"2025-11-25","capabilities":{"experimental":{},"prompts":{"listChanged":false},"resources":{"subscribe":false,"listChanged":false},"tools":{"listChanged":false}},"serverInfo":{"name":"litellm-mcp-server","version":"1.0.0"}}}

HTTP 200

After (78e1103, mcp 2.2.0, http://127.0.0.1:58906)

  1. Installing SDK 2 next to the proxy resolves, with the two local checkout path lines trimmed
$ uv pip install --dry-run --python .venv/bin/python '.[proxy]' 'mcp>=2.2,<3'
Resolved 118 packages in 464ms
Would download 1 package
Would uninstall 1 package
Would install 1 package
  1. In Claude Code, /mcp shows litellm connected with 6 tools

pr41718-78e1103bb8-after-claude-mcp.png

  1. The same prompt asks permission for each tool call, and after choosing "1. Yes" twice it answers 7 and 107

pr41718-78e1103bb8-after-claude-result.png

  1. The same SDK 1 LangChain client lists and calls the tools
$ <sdk1 venv>/bin/python langchain_client.py http://127.0.0.1:58906
tools: ['math_stdio-add', 'math_stdio-multiply', 'math_stdio-request_headers', 'math_streamable_http-add', 'math_streamable_http-multiply', 'math_streamable_http-request_headers']
{"math_stdio-add": [{"type": "text", "text": "7", "id": "lc_1863958b-881c-4a3a-94b8-036441b8138e"}], "math_streamable_http-add": [{"type": "text", "text": "107", "id": "lc_79a2a1dc-b659-47df-83a2-dc2b108169ab"}]}
  1. The same stock SDK 2 client lists and calls the tools
$ <sdk2 venv>/bin/python sdk2_client.py http://127.0.0.1:58906
negotiated: 2025-11-25
tools: ['math_stdio-add', 'math_stdio-multiply', 'math_stdio-request_headers', 'math_streamable_http-add', 'math_streamable_http-multiply', 'math_streamable_http-request_headers']
math_stdio-add -> {'result': 7}
math_streamable_http-add -> {'result': 107}
  1. The same raw JSON-RPC calls return the same values
$ rpc 2025-06-18 '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"legacy-parity","version":"1"}}}'
event: message
data: {"jsonrpc":"2.0","id":1,"result":{"capabilities":{"experimental":{},"prompts":{"listChanged":false},"resources":{"listChanged":false,"subscribe":false},"tools":{"listChanged":false}},"protocolVersion":"2025-06-18","serverInfo":{"name":"litellm-mcp-server","version":"1.0.0"}}}

HTTP 200
$ rpc 2025-06-18 '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' | grep -o '"name":"[^"]*"\|^HTTP [0-9]*' | sort -u
"name":"math_stdio-add"
"name":"math_stdio-multiply"
"name":"math_stdio-request_headers"
"name":"math_streamable_http-add"
"name":"math_streamable_http-multiply"
"name":"math_streamable_http-request_headers"
HTTP 200
$ rpc 2025-06-18 '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"math_stdio-add","arguments":{"a":3,"b":4}}}'
event: message
data: {"jsonrpc":"2.0","id":3,"result":{"content":[{"text":"7","type":"text"}],"isError":false,"structuredContent":{"result":7}}}

HTTP 200
$ rpc 2025-06-18 '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"math_streamable_http-add","arguments":{"a":3,"b":4}}}'
event: message
data: {"jsonrpc":"2.0","id":4,"result":{"content":[{"text":"107","type":"text"}],"isError":false,"structuredContent":{"result":107}}}

HTTP 200
  1. A modern-only MCP-Protocol-Version header on a legacy body is now rejected, the one intended behavior change
$ rpc 2026-07-28 '{"jsonrpc":"2.0","id":5,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"legacy-parity","version":"1"}}}'
{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"Unsupported MCP-Protocol-Version 2026-07-28; supported: 2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25"}}
HTTP 400
  1. A future version in the initialize body with no header still negotiates down
$ curl -sS -w '\nHTTP %{http_code}\n' "$P/mcp" -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' -H 'Authorization: Bearer sk-1234' -d '{"jsonrpc":"2.0","id":6,"method":"initialize","params":{"protocolVersion":"2026-07-28","capabilities":{},"clientInfo":{"name":"legacy-parity","version":"1"}}}'
event: message
data: {"jsonrpc":"2.0","id":6,"result":{"capabilities":{"experimental":{},"prompts":{"listChanged":false},"resources":{"listChanged":false,"subscribe":false},"tools":{"listChanged":false}},"protocolVersion":"2025-11-25","serverInfo":{"name":"litellm-mcp-server","version":"1.0.0"}}}

HTTP 200

What the run noticed:

  • After responses order JSON keys alphabetically, caused by this PR
  • New 400 needs a hand-set modern-only header, this PR's change
  • Stock SDK 2.2.0 client negotiates 2025-11-25 on both legs, unchanged
  • tools/call works without initialize or session id, left alone
  • Responses are SSE-framed even when application/json comes first, left alone
  • Claude Code shows structuredContent, not the text block, left alone

Author's checks at the same head that this run did not repeat

The no-database legs above cannot mint a key without server grants, and the last two checks exercise the SDK and a guardrail hook directly, so they stay here as the author reported them

  • Permission denial: tools/call for math_stdio-add with a key that has no server grants returns HTTP 200 with isError:true and Error: User not allowed to call this tool. on both legs
  • Expired upstream session: after a DELETE with its Mcp-Session-Id, listing tools fails with McpError: Session terminated before and MCPError: Not Found: Session has been terminated after, and a fresh session returns 7 on both
  • Guardrail inspection wire fields: sending image, audio, and embedded-resource results through the Cisco hook fails before with Object of type AnyUrl is not JSON serializable, and after both captured requests carry mimeType with image/png, audio/wav, and nested text/plain

Type

🐛 Bug Fix
🧹 Refactoring
🚄 Infrastructure
✅ Test

Caveats (if any)

Severe

  • Shared Python environments must migrate SDK 1-dependent libraries
    • langchain-mcp-adapters==0.2.1 uses removed SDK 1 APIs although its metadata allows MCP 2; it stays tested here as an isolated network client
  • Experimental client return objects now expose SDK 2 Python attributes

Medium

  • Phase 0 release and canary observation remain separate gates; modern MCP behavior stays off

Low

  • MCP unit and integration suites must run as separate processes; combining them causes duplicate module imports and shared proxy-state interference
  • The installation checker's failure diagnostics stay uncovered by design, so its changed-line coverage sits at 73% where the production changes sit at 96%

QA runbook

The only tests/e2e change is the shared OAuth helper's port to SDK 2 (httpx2 client, AuthorizationCodeResult callback result, two-stream transport tuple). No e2e test was added or changed, so tests/e2e/mcp/test_mcp_chat_completion_oauth_e2e.py keeps its two cases and there is nothing new to reproduce by hand

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR

@joshua-berri

Copy link
Copy Markdown
Contributor Author

@greptileai Please review commit 6aa921c for dependency isolation, reproducible installation checks, SDK1 preservation, and the new CI workflow

@joshua-berri

Copy link
Copy Markdown
Contributor Author

bugbot run Please review commit 6aa921c for dependency isolation, snapshot validation, clean test execution, and existing SDK1 compatibility

@joshua-berri

Copy link
Copy Markdown
Contributor Author

@veria-ai Please review commit 6aa921c for isolation, artifact integrity, workflow permissions, and exposure from test-only minimum dependency fixtures

@codspeed

codspeed Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing litellm_mcp_dependency_gate_7737 (78e1103) with main (d0f60fc)

Open in CodSpeed

@greptile-apps

greptile-apps Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

The PR appears safe to merge based on the reviewed changes, with no outstanding correctness or repository-rule findings.

Summary

This PR upgrades LiteLLM’s MCP integration to SDK 2 while retaining targeted legacy gateway behavior and isolated SDK 1 network-client coverage.

  • Ports MCP clients, gateway handlers, transport authentication, serialization, sampling, and guardrail integration to SDK 2 APIs.
  • Adds dependency-resolution checks across supported Python versions and consolidates MCP integration tests into the shared unit-test workflow.
  • The latest revision places isolated SDK 1 peer installation under the existing dependency-setup deadline and restores the MCP shard’s standard 60-minute job budget.
  • All previous Greptile findings were resolved and withdrawn; no new actionable issue was identified.

Reviews (9) · Last reviewed commit: "fix(ci): preserve shared runner setup ti..."

Comment thread .github/workflows/test-dependency-installs.yml Outdated

@cursor cursor 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.

Stale Bugbot comment from a previous run.

Comment thread tests/mcp_dependency_tests/check_environment.py Outdated
@codecov

codecov Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.58233% with 11 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ail_hooks/cisco_ai_defense/cisco_ai_defense_mcp.py 75.00% 6 Missing ⚠️
litellm/proxy/_experimental/mcp_server/server.py 94.50% 5 Missing ⚠️

📢 Thoughts on this report? Let us know!

@joshua-berri

Copy link
Copy Markdown
Contributor Author

@greptileai Please review commit 21beb9b, including the Codecov key URL repair, pinned uploader, and package-name normalization regression tests

@joshua-berri

Copy link
Copy Markdown
Contributor Author

bugbot run. Please review commit 21beb9b and verify the package-name normalization repair against dotted names and repeated punctuation

@joshua-berri

Copy link
Copy Markdown
Contributor Author

@veria-ai Please review commit 21beb9b for signature verification, isolated dependency inventories, workflow permissions, and the existing minimum-fixture exposure boundaries

@cursor cursor 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.

Stale Bugbot comment from a previous run.

@joshua-berri

Copy link
Copy Markdown
Contributor Author

@greptileai Please review dfd0474, which preserves repository-relative coverage paths while keeping every measured line hit and branch result unchanged

@joshua-berri

Copy link
Copy Markdown
Contributor Author

bugbot run. Please review dfd0474 and check the reporting-only coverage configuration, file paths, and preservation of measured results

@joshua-berri

Copy link
Copy Markdown
Contributor Author

@veria-ai Please review dfd0474, including the reporting-only coverage export, signature verification, and previously reviewed isolated dependency gate boundaries

@cursor cursor 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.

Stale Bugbot comment from a previous run.

@joshua-berri
joshua-berri marked this pull request as ready for review September 18, 2026 01:44
@joshua-berri
joshua-berri requested a review from a team September 18, 2026 01:44
joshua-berri and others added 3 commits September 18, 2026 22:12
Replace the bespoke dependency-install CI gate with a real migration:
require mcp>=2.2.0,<3 alongside httpx2>=2.5.0,<3 and pydantic>=2.12.0,<3
in the proxy and mcp extras, drop langchain-mcp-adapters (pins mcp<2)
from the dev group, and remove the dependency-install workflow and
tests/mcp_dependency_tests that only exercised the old pins.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
McpError -> MCPError (new code/message/data constructor), camelCase model
attributes and constructor kwargs -> snake_case, RequestResponder ->
ClientSession message handler receiving ServerNotification | Exception,
RequestContext -> ClientRequestContext, read_timeout_seconds -> float,
server_capabilities property, JSONRPCMessage union parsed via TypeAdapter,
and httpx -> httpx2 for every object handed to the SDK transports
(MCPSigV4Auth, the httpx client factory, outbound_credentials auth
classes and resolver return types). Helpers that serve both litellm httpx
clients and the SDK's httpx2 transport accept both response types.

The SDK read-timeout code is now the JSON-RPC REQUEST_TIMEOUT (-32001)
instead of HTTP 408; as_mcp_read_timeout keeps the TimeoutError context
discriminator. Upstream transport exceptions and responses found in
exception trees are matched as httpx2 alongside httpx.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Rename McpError/isError/inputSchema-style references to the SDK 2
spellings, parse the JSONRPCMessage union with a TypeAdapter, and drive
the SDK transports off httpx2 MockTransport injection where respx can no
longer intercept. Adjust for SDK 2 behavior: the initialize handshake
negotiates handshake-era protocol versions only, an empty SSE stream
surfaces CONNECTION_CLOSED, non-2xx tool responses surface INTERNAL_ERROR
MCPError instead of HTTPStatusError, and the SDK read timeout carries the
JSON-RPC REQUEST_TIMEOUT code.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@joshua-berri

Copy link
Copy Markdown
Contributor Author

bugbot run. Please review fb56a14 after merging main and confirm the earlier session-expiry and guardrail serialization fixes remain sound

@joshua-berri

Copy link
Copy Markdown
Contributor Author

@veria-ai Please review fb56a14 after merging main, including preserved legacy authentication, session handling, and refreshed live compatibility evidence

@cursor cursor 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.

Stale Bugbot comment from a previous run.

@joshua-berri

Copy link
Copy Markdown
Contributor Author

@greptileai Please review 8f3562e: dedicated MCP workflow removed, integration coverage retained in shared CI, isolated SDK1 smoke test preserved

@joshua-berri

Copy link
Copy Markdown
Contributor Author

bugbot run. Please review 8f3562e for shared MCP test setup, single execution, isolated legacy peer installation, and coverage reporting

@joshua-berri

Copy link
Copy Markdown
Contributor Author

@veria-ai Please review 8f3562e: MCP integration tests now use shared CI, retaining isolated SDK1 compatibility checks and existing security coverage

@cursor cursor 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.

Stale Bugbot comment from a previous run.

@joshua-berri

Copy link
Copy Markdown
Contributor Author

@greptileai Please review 78e1103: legacy peer installation now shares the existing dependency setup deadline; workflow safety and compatibility checks pass

@joshua-berri

Copy link
Copy Markdown
Contributor Author

bugbot run. Please review 78e1103, confirming isolated SDK1 setup remains limited to the MCP shard without increasing shared setup timeouts

@joshua-berri

Copy link
Copy Markdown
Contributor Author

@veria-ai Please review 78e1103: isolated legacy peer setup now runs inside the existing dependency step, preserving timeout and compatibility safeguards

@cursor cursor 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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 78e1103. Configure here.

@joshua-berri
joshua-berri merged commit eda1fab into main Sep 19, 2026
115 checks passed
@joshua-berri
joshua-berri deleted the litellm_mcp_dependency_gate_7737 branch September 19, 2026 18:53
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.

3 participants