Merge pull request #22680 from BerriAI/litellm_fix_mcp_server_dates

[Fix] MCP server: preserve created_at and updated_at timestamps
This commit is contained in:
yuneng-jiang
2026-03-03 09:53:37 -08:00
committed by GitHub
3 changed files with 92 additions and 6 deletions
@@ -642,6 +642,7 @@ class MCPServerManager:
available_on_public_internet=bool(
getattr(mcp_server, "available_on_public_internet", True)
),
created_at=getattr(mcp_server, "created_at", None),
updated_at=getattr(mcp_server, "updated_at", None),
)
return new_server
@@ -2540,8 +2541,8 @@ class MCPServerManager:
url=server.url,
transport=server.transport,
auth_type=server.auth_type,
created_at=datetime.now(),
updated_at=datetime.now(),
created_at=server.created_at,
updated_at=server.updated_at,
teams=[],
mcp_access_groups=server.access_groups or [],
allowed_tools=server.allowed_tools or [],
@@ -2620,8 +2621,6 @@ class MCPServerManager:
return list_mcp_servers
def _build_mcp_server_table(self, server: MCPServer) -> LiteLLM_MCPServerTable:
from datetime import datetime
return LiteLLM_MCPServerTable(
server_id=server.server_id,
server_name=server.server_name,
@@ -2633,8 +2632,8 @@ class MCPServerManager:
spec_path=server.spec_path,
transport=server.transport,
auth_type=server.auth_type,
created_at=datetime.now(),
updated_at=datetime.now(),
created_at=server.created_at,
updated_at=server.updated_at,
teams=[],
mcp_access_groups=server.access_groups or [],
allowed_tools=server.allowed_tools or [],
@@ -53,6 +53,7 @@ class MCPServer(BaseModel):
access_groups: Optional[List[str]] = None
allow_all_keys: bool = False
available_on_public_internet: bool = True
created_at: Optional[datetime] = None
updated_at: Optional[datetime] = None
model_config = ConfigDict(arbitrary_types_allowed=True)
@@ -2307,5 +2307,91 @@ class TestMCPServerManager:
assert resolved_server.server_name == "test_server" # server_name matches
class TestMCPServerTimestamps:
"""Regression tests: created_at/updated_at must be preserved, not overwritten with datetime.now()."""
@pytest.mark.asyncio
async def test_build_mcp_server_from_table_preserves_timestamps(self):
"""build_mcp_server_from_table must carry created_at and updated_at into MCPServer."""
manager = MCPServerManager()
created = datetime(2024, 1, 15, 10, 0, 0)
updated = datetime(2024, 6, 20, 12, 30, 0)
table_record = LiteLLM_MCPServerTable(
server_id="ts-server-1",
server_name="ts_server",
url="https://example.com/mcp",
transport=MCPTransport.http,
created_at=created,
updated_at=updated,
)
mcp_server = await manager.build_mcp_server_from_table(table_record)
assert mcp_server.created_at == created
assert mcp_server.updated_at == updated
def test_build_mcp_server_table_preserves_timestamps(self):
"""_build_mcp_server_table must use the MCPServer's stored timestamps, not datetime.now()."""
manager = MCPServerManager()
created = datetime(2024, 1, 15, 10, 0, 0)
updated = datetime(2024, 6, 20, 12, 30, 0)
server = MCPServer(
server_id="ts-server-2",
name="ts_server",
url="https://example.com/mcp",
transport=MCPTransport.http,
created_at=created,
updated_at=updated,
)
table = manager._build_mcp_server_table(server)
assert table.created_at == created
assert table.updated_at == updated
def test_build_mcp_server_table_none_timestamps_when_not_set(self):
"""_build_mcp_server_table must return None timestamps when not set on MCPServer."""
manager = MCPServerManager()
server = MCPServer(
server_id="ts-server-3",
name="ts_server",
url="https://example.com/mcp",
transport=MCPTransport.http,
)
table = manager._build_mcp_server_table(server)
assert table.created_at is None
assert table.updated_at is None
@pytest.mark.asyncio
async def test_round_trip_timestamps_preserved(self):
"""Timestamps survive the full round-trip: LiteLLM_MCPServerTable -> MCPServer -> LiteLLM_MCPServerTable."""
manager = MCPServerManager()
created = datetime(2023, 3, 10, 8, 0, 0)
updated = datetime(2023, 9, 5, 16, 45, 0)
table_record = LiteLLM_MCPServerTable(
server_id="ts-server-4",
server_name="ts_server_rt",
url="https://example.com/mcp",
transport=MCPTransport.http,
created_at=created,
updated_at=updated,
)
mcp_server = await manager.build_mcp_server_from_table(table_record)
rebuilt_table = manager._build_mcp_server_table(mcp_server)
assert rebuilt_table.created_at == created
assert rebuilt_table.updated_at == updated
if __name__ == "__main__":
pytest.main([__file__])