fix(mcp): preserve source_url in GET /v1/mcp/server list responses - #29249
Conversation
The list endpoint builds responses from the in-memory registry, but
source_url was dropped during the DB-to-registry roundtrip even though
GET /v1/mcp/server/{id} returned it correctly from the database.
Co-authored-by: Cursor <cursoragent@cursor.com>
Greptile SummaryThis PR fixes
Confidence Score: 5/5Safe to merge — the change is a minimal, isolated field propagation fix with no side effects on other code paths. All three touch points (type model, DB-to-registry loader, registry-to-response builder) are updated consistently, matching the pattern of every other field in those same conversion functions. The regression test covers the exact round-trip that was broken and runs entirely in-memory. No files require special attention.
|
| Filename | Overview |
|---|---|
| litellm/types/mcp_server/mcp_server_manager.py | Adds source_url: Optional[str] = None to the runtime MCPServer model, consistent with placement in _types.py. |
| litellm/proxy/_experimental/mcp_server/mcp_server_manager.py | Threads source_url through both conversion paths: build_mcp_server_from_table() (DB → registry) and _build_mcp_server_table() (registry → list response). Fix is minimal and targeted. |
| tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server_manager.py | Adds test_round_trip_source_url_preserved — a pure in-memory regression test covering the full LiteLLM_MCPServerTable → MCPServer → LiteLLM_MCPServerTable round-trip with no real network calls. |
Reviews (1): Last reviewed commit: "fix(mcp): preserve source_url in GET /v1..." | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
MagicMock auto-creates source_url as a mock object, which fails MCPServer Pydantic validation after source_url was wired through build_mcp_server_from_table. Co-authored-by: Cursor <cursoragent@cursor.com>
ace3c65
into
litellm_internal_staging
…erriAI#29249) * fix(mcp): preserve source_url in GET /v1/mcp/server list responses The list endpoint builds responses from the in-memory registry, but source_url was dropped during the DB-to-registry roundtrip even though GET /v1/mcp/server/{id} returned it correctly from the database. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(tests/mcp): set source_url on MagicMock table records MagicMock auto-creates source_url as a mock object, which fails MCPServer Pydantic validation after source_url was wired through build_mcp_server_from_table. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
Resolves LIT-3425
Description
source_url was saved correctly when creating MCP servers, but GET /v1/mcp/server always returned "source_url": null. The single-server endpoint (GET /v1/mcp/server/{id}) worked because it reads directly from the database.
This PR threads source_url through the in-memory registry roundtrip used by the list endpoint.
Cause
The list endpoint builds its response from the in-memory MCP registry via:
LiteLLM_MCPServerTable → MCPServer → LiteLLM_MCPServerTable
source_url existed on the DB/API model but was never added to the runtime MCPServer model, so it was dropped when loading servers into the registry and when rebuilding list responses in _build_mcp_server_table().
Fix
Add source_url to the runtime MCPServer model
Map source_url in build_mcp_server_from_table() when loading from DB
Map source_url in _build_mcp_server_table() when building list responses
Add regression test: test_round_trip_source_url_preserved
Before:

After:
