From bc87cd4db31b207bd90edb80745d3577bcec770e Mon Sep 17 00:00:00 2001 From: Yuneng Jiang Date: Mon, 12 Oct 2026 00:24:47 -0700 Subject: [PATCH 1/3] ci: run the MCP unit tests in the GHA unit workflow CircleCI's mcp_integration job only ran tests/unit folders. A new mcp shard in test-unit.yml runs the files no other shard claims, and the CircleCI job is removed --- .circleci/config.yml | 49 --------------------------------- .github/workflows/test-unit.yml | 22 +++++++++++++++ 2 files changed, 22 insertions(+), 49 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ceeb4b5fbf8..cc83253f9b0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1491,52 +1491,6 @@ jobs: - store_artifacts: path: test-results - mcp_integration: - machine: - image: ubuntu-2204:2024.04.1 - resource_class: large - working_directory: ~/project - environment: - COVERAGE_CORE: sysmon - LITELLM_LOCAL_MODEL_COST_MAP: "True" - steps: - - checkout - - skip_if_unrelated_changes - - setup_litellm_test_deps - - run: - name: Generate Prisma client - command: uv run --no-sync prisma generate --schema litellm/proxy/schema.prisma - - run: - name: Install MCP SDK1 peer - command: | - uv venv --python 3.12 .venv-mcp-peer - uv pip install --python .venv-mcp-peer 'mcp==1.28.1' 'langchain-mcp-adapters==0.2.1' - echo "export MCP_TEST_PEER_PYTHON=$PWD/.venv-mcp-peer/bin/python" >> "$BASH_ENV" - - run: - name: Run MCP integration tests - command: | - mkdir -p test-results - env -u OPENAI_API_KEY -u ANTHROPIC_API_KEY \ - timeout --signal=TERM 20m uv run --no-sync pytest \ - tests/unit/experimental_mcp_client tests/unit/proxy/_experimental/mcp_server \ - tests/unit/responses/mcp --tb=short -vv --maxfail=10 -n 2 --dist=loadscope --reruns 0 \ - --reruns-delay 1 --timeout=120 --rerun-except "from pytest-timeout" --durations=20 \ - --cov=./litellm --cov=./enterprise/litellm_enterprise --cov-report=xml:coverage.xml \ - --cov-config=pyproject.toml -o junit_family=xunit1 --junitxml=test-results/junit.xml - - install_codecov_cli - - run: - name: Upload MCP integration coverage - when: always - command: | - [ -f coverage.xml ] || { echo "no coverage.xml produced"; exit 1; } - codecov upload-process --disable-search --fail-on-error -f coverage.xml \ - -F mcp-integration -C "$CIRCLE_SHA1" \ - -n "mcp-integration-${CIRCLE_BUILD_NUM}" --git-service github - - store_test_results: - path: test-results - - store_artifacts: - path: test-results - redis_compat: parameters: redis_py: @@ -1749,9 +1703,6 @@ workflows: coverage_flag: roi-postgres timeout_minutes: 10 filters: *integration_default_run - - mcp_integration: - name: mcp-integration - filters: *integration_default_run - redis_compat: name: redis-compat-<< matrix.redis_py >> matrix: diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml index 23a340cd436..232797d3665 100644 --- a/.github/workflows/test-unit.yml +++ b/.github/workflows/test-unit.yml @@ -573,6 +573,28 @@ jobs: job-timeout-minutes: 60 dist: loadscope + - shard: mcp + test-path: >- + tests/unit/experimental_mcp_client + tests/unit/proxy/_experimental/mcp_server + tests/unit/responses/mcp + --ignore=tests/unit/experimental_mcp_client/test_mcp_client.py + --ignore=tests/unit/proxy/_experimental/mcp_server/test_capabilities.py + --ignore=tests/unit/proxy/_experimental/mcp_server/test_interactions.py + --ignore=tests/unit/proxy/_experimental/mcp_server/test_mcp_elicitation_handler.py + --ignore=tests/unit/proxy/_experimental/mcp_server/test_mcp_server_manager.py + --ignore=tests/unit/proxy/_experimental/mcp_server/test_mcp_server_tool_calls_and_headers.py + --ignore=tests/unit/proxy/_experimental/mcp_server/test_operations.py + --ignore=tests/unit/proxy/_experimental/mcp_server/test_discoverable_endpoints.py + --ignore=tests/unit/proxy/_experimental/mcp_server/test_db_credentials.py + --ignore=tests/unit/proxy/_experimental/mcp_server/outbound_credentials + python-version: "3.12" + workers: 4 + reruns: 0 + timeout-minutes: 15 + job-timeout-minutes: 30 + dist: loadscope + - shard: proxy-infra test-path: |- tests/unit/proxy/db From 61fc7d8c3a65aaf32a6fa0b9672f49b41707f5af Mon Sep 17 00:00:00 2001 From: Yuneng Jiang Date: Mon, 12 Oct 2026 00:33:45 -0700 Subject: [PATCH 2/3] ci: give the mcp unit shard the same job timeout as its neighbours check_workflow_startup_safety requires room for setup on top of the 15m pytest budget --- .github/workflows/test-unit.yml | 2 +- license_cache.json | 30 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml index 232797d3665..e76f2ddb171 100644 --- a/.github/workflows/test-unit.yml +++ b/.github/workflows/test-unit.yml @@ -592,7 +592,7 @@ jobs: workers: 4 reruns: 0 timeout-minutes: 15 - job-timeout-minutes: 30 + job-timeout-minutes: 60 dist: loadscope - shard: proxy-infra diff --git a/license_cache.json b/license_cache.json index dc061b48f4f..6646aadc1ea 100644 --- a/license_cache.json +++ b/license_cache.json @@ -57,5 +57,33 @@ "vcrpy:8.1.1": "MIT", "langchain-openai:1.1.14": "MIT", "grpc-google-iam-v1:0.14.4": "Apache 2.0", - "tornado:6.5.5": "Apache-2.0" + "tornado:6.5.5": "Apache-2.0", + "packaging:24.0": "Apache Software License", + "huggingface-hub:0.34.0": "Apache", + "async-timeout:4.0.3": "Apache 2", + "pydantic-settings:2.14.1": "MIT", + "granian:2.7.4": "BSD-3-Clause", + "hiredis:3.0.0": "MIT", + "InquirerPy:0.3.4": "MIT", + "tomlkit:0.13.3": "MIT", + "requests:2.32.0": "Apache-2.0", + "keyring:25.6.0": "MIT License", + "python3-saml:1.16.0": "MIT", + "google-cloud-speech:2.40.0": "Apache-2.0", + "aws-sdk-bedrock-runtime:0.10.0": "Apache-2.0", + "opentelemetry-instrumentation-fastapi:0.54b1": "Apache-2.0", + "reportlab:5.0.1": "BSD license (see license.txt for details), Copyright (c) 2000-2025, ReportLab Inc.", + "basedpyright:1.39.7": "MIT License", + "mypy:1.20.1": "MIT", + "keyring:25.7.0": "MIT", + "pytest-socket:0.8.1": "MIT", + "tomli:2.4.1": "MIT", + "botocore-stubs:1.43.14": "MIT", + "types-boto3:1.43.30": "MIT", + "playwright:1.61.0": "Apache-2.0", + "psutil:7.2.2": "BSD-3-Clause", + "pyarrow:23.0.1": "Apache-2.0", + "langchain:1.3.9": "MIT", + "traceloop-sdk:0.34.0": "Apache-2.0", + "tornado:6.5.10": "Apache-2.0" } \ No newline at end of file From 4c66e1cb29155a1f051cc001a2e23cc78fecdd1d Mon Sep 17 00:00:00 2001 From: Yuneng Jiang Date: Mon, 12 Oct 2026 00:33:57 -0700 Subject: [PATCH 3/3] chore: restore license_cache.json --- license_cache.json | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/license_cache.json b/license_cache.json index 6646aadc1ea..dc061b48f4f 100644 --- a/license_cache.json +++ b/license_cache.json @@ -57,33 +57,5 @@ "vcrpy:8.1.1": "MIT", "langchain-openai:1.1.14": "MIT", "grpc-google-iam-v1:0.14.4": "Apache 2.0", - "tornado:6.5.5": "Apache-2.0", - "packaging:24.0": "Apache Software License", - "huggingface-hub:0.34.0": "Apache", - "async-timeout:4.0.3": "Apache 2", - "pydantic-settings:2.14.1": "MIT", - "granian:2.7.4": "BSD-3-Clause", - "hiredis:3.0.0": "MIT", - "InquirerPy:0.3.4": "MIT", - "tomlkit:0.13.3": "MIT", - "requests:2.32.0": "Apache-2.0", - "keyring:25.6.0": "MIT License", - "python3-saml:1.16.0": "MIT", - "google-cloud-speech:2.40.0": "Apache-2.0", - "aws-sdk-bedrock-runtime:0.10.0": "Apache-2.0", - "opentelemetry-instrumentation-fastapi:0.54b1": "Apache-2.0", - "reportlab:5.0.1": "BSD license (see license.txt for details), Copyright (c) 2000-2025, ReportLab Inc.", - "basedpyright:1.39.7": "MIT License", - "mypy:1.20.1": "MIT", - "keyring:25.7.0": "MIT", - "pytest-socket:0.8.1": "MIT", - "tomli:2.4.1": "MIT", - "botocore-stubs:1.43.14": "MIT", - "types-boto3:1.43.30": "MIT", - "playwright:1.61.0": "Apache-2.0", - "psutil:7.2.2": "BSD-3-Clause", - "pyarrow:23.0.1": "Apache-2.0", - "langchain:1.3.9": "MIT", - "traceloop-sdk:0.34.0": "Apache-2.0", - "tornado:6.5.10": "Apache-2.0" + "tornado:6.5.5": "Apache-2.0" } \ No newline at end of file