Skip to content

Conversation

@Cristhianzl
Copy link
Member

@Cristhianzl Cristhianzl commented Dec 15, 2025

test(headers): add comprehensive tests for headers functionality in MCP component to ensure correct behavior and validation of header inputs
feat(mcp_component.py): add headers input to MCPToolsComponent for customizable HTTP headers in requests

This change allows users to specify HTTP headers, such as Authorization, for requests to the MCP server, enhancing authentication and flexibility in server interactions.

Summary by CodeRabbit

Release Notes

  • New Features
    • Introduced HTTP headers configuration capability for MCP-related components, enabling users to customize headers for MCP tools and documentation services.
    • Headers from components are automatically merged with existing server headers during configuration, with component-provided headers taking precedence.
    • Supports flexible header input formats for streamlined configuration.

✏️ Tip: You can customize this high-level summary in your review settings.

…CP component to ensure correct behavior and validation of header inputs

feat(mcp_component.py): add headers input to MCPToolsComponent for customizable HTTP headers in requests

This change allows users to specify HTTP headers, such as
Authorization, for requests to the MCP server, enhancing
authentication and flexibility in server interactions.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 15, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The changes introduce HTTP headers configuration capability to MCP-related components by adding a new public headers input (DictInput) to MCPTools and RemixDocumentation components, along with header merging logic that combines component-provided headers with existing server headers during configuration resolution.

Changes

Cohort / File(s) Summary
MCP Component Schema Updates
src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json
Added new public headers input (DictInput) to both MCPTools and RemixDocumentation nodes; included headers in MCPTools default_keys for config export/regression participation
MCP Component Implementation
src/lfx/src/lfx/components/models_and_agents/mcp_component.py
Added headers input to MCPToolsComponent using DictInput with is_list=True; updated default_keys to include headers; implemented header merging logic that normalizes component headers (list or dict format) and merges with existing server headers, giving component headers precedence
Headers Test Coverage
src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
Added comprehensive TestMCPComponentHeaders test suite validating headers input configuration, headers merging scenarios (basic merge, override, empty/None handling, format normalization), and special character handling

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Header merging logic in mcp_component.py: Verify correct handling of both list and dict header formats, precedence rules, and edge cases (None values, empty strings, malformed items)
  • Test coverage: Ensure all documented merging scenarios are adequately tested and edge cases are represented
  • Schema consistency: Confirm Nvidia Remix.json node definitions align with MCPToolsComponent implementation and both RemixDocumentation and MCPTools expose headers correctly

Pre-merge checks and finishing touches

✅ Passed checks (7 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: adding customizable HTTP headers support to MCPToolsComponent.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Test Coverage For New Implementations ✅ Passed PR includes comprehensive test coverage for new headers functionality in MCPToolsComponent with 13 test methods validating headers input, merging logic, and implementation.
Test Quality And Coverage ✅ Passed The test suite includes comprehensive TestMCPComponentHeaders class with 11 test methods covering headers functionality, validation, merging logic, precedence, and edge cases.
Test File Naming And Structure ✅ Passed The test file test_mcp_component.py fully complies with backend testing standards using correct naming, proper directory structure, and contains 30 well-organized test methods with comprehensive pytest fixtures, async patterns, mocking, and assertions.
Excessive Mock Usage Warning ✅ Passed TestMCPComponentHeaders uses mocks appropriately as test data fixtures rather than excessive mocking. Real MCPToolsComponent instances are tested with assertions; no external dependencies are patched.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the enhancement New feature or request label Dec 15, 2025
@codecov
Copy link

codecov bot commented Dec 15, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 33.09%. Comparing base (909bdb1) to head (fb537cd).

❌ Your project check has failed because the head coverage (39.21%) is below the target coverage (60.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main   #11023      +/-   ##
==========================================
- Coverage   33.09%   33.09%   -0.01%     
==========================================
  Files        1389     1389              
  Lines       65682    65682              
  Branches     9720     9720              
==========================================
- Hits        21737    21736       -1     
- Misses      42830    42831       +1     
  Partials     1115     1115              
Flag Coverage Δ
backend 52.39% <ø> (-0.01%) ⬇️
frontend 15.35% <ø> (ø)
lfx 39.21% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.
see 4 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 15, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 15, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 15, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lfx/src/lfx/components/models_and_agents/mcp_component.py (1)

205-227: Cached server config can serve stale or incorrect headers when use_cache=True

Right now server_config (including merged headers) is cached per server_name in servers_cache, and the cached path returns early using cached["config"] without reapplying self.headers. This means:

  • If use_cache=True and headers change (e.g., rotated Authorization token), subsequent calls for the same server_name will continue to use the old headers.
  • Because the cache key is only server_name, any other component instance sharing the same cache entry will also see whatever headers were merged when that entry was first populated.

Given that headers are often auth-bearing, this is a significant behavior/safety issue when caching is enabled.

Consider one of the following adjustments:

  • Re-merge self.headers into a copy of the cached config before returning, so the effective headers always reflect the current component state, or
  • Exclude headers from the cached config and keep them as a per-call overlay (e.g., via a small _apply_headers(server_config) helper used in both cached and non‑cached paths), or
  • Extend the cache key so that entries differ when headers (or other per-component overrides like verify_ssl) differ.

It would also be worth adding a dedicated test that sets use_cache=True, exercises update_tool_list twice with different headers, and asserts that the second call sees the new headers.

Also applies to: 273-297

🧹 Nitpick comments (1)
src/backend/tests/unit/components/models_and_agents/test_mcp_component.py (1)

230-512: Good coverage of header shapes; consider reducing duplication and exercising the real path

The TestMCPComponentHeaders suite does a nice job covering list/dict formats, malformed entries, existing headers as dict/list, special characters, and empty values, so the intended merge semantics are well specified.

Two follow‑ups to consider:

  • The header merge snippet (component_headers = getattr(...); component_headers_dict = {}; ... merged_headers = ...) is duplicated across many tests and mirrors the production code; factoring this into a small test helper (or, better, a dedicated helper on MCPToolsComponent that both production and tests call) would reduce drift risk and make future changes to the merge logic safer.
  • Given the caching behavior in update_tool_list, it would be valuable to add at least one test that sets use_cache=True, calls update_tool_list with one set of headers and then with a different set, and asserts that the effective headers match the latest values; this will guard against stale-header bugs when caching is enabled.

If you want these tests to integrate more tightly with the existing component test harness, you could also (optionally) mirror the pattern in TestMCPToolsComponent by using the appropriate ComponentTestBase* base class, but that’s not strictly required for correctness here.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 909bdb1 and 486b7db.

📒 Files selected for processing (2)
  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py (1 hunks)
  • src/lfx/src/lfx/components/models_and_agents/mcp_component.py (4 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
src/backend/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

src/backend/**/*.py: Use FastAPI async patterns with await for async operations in component execution methods
Use asyncio.create_task() for background tasks and implement proper cleanup with try/except for asyncio.CancelledError
Use queue.put_nowait() for non-blocking queue operations and asyncio.wait_for() with timeouts for controlled get operations

Files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
src/backend/**/*component*.py

📄 CodeRabbit inference engine (.cursor/rules/icons.mdc)

In Python component classes, set the icon attribute to a string matching the desired icon name (e.g., icon = "AstraDB"). The string must match the frontend icon mapping exactly (case-sensitive).

Files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
src/backend/tests/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/testing.mdc)

src/backend/tests/**/*.py: Place backend unit tests in src/backend/tests/ directory, component tests in src/backend/tests/unit/components/ organized by component subdirectory, and integration tests accessible via make integration_tests
Use same filename as component with appropriate test prefix/suffix (e.g., my_component.pytest_my_component.py)
Use the client fixture (FastAPI Test Client) defined in src/backend/tests/conftest.py for API tests; it provides an async httpx.AsyncClient with automatic in-memory SQLite database and mocked environment variables. Skip client creation by marking test with @pytest.mark.noclient
Inherit from the correct ComponentTestBase family class located in src/backend/tests/base.py based on API access needs: ComponentTestBase (no API), ComponentTestBaseWithClient (needs API), or ComponentTestBaseWithoutClient (pure logic). Provide three required fixtures: component_class, default_kwargs, and file_names_mapping
Create comprehensive unit tests for all new backend components. If unit tests are incomplete, create a corresponding Markdown file documenting manual testing steps and expected outcomes
Test both sync and async code paths, mock external dependencies appropriately, test error handling and edge cases, validate input/output behavior, and test component initialization and configuration
Use @pytest.mark.asyncio decorator for async component tests and ensure async methods are properly awaited
Test background tasks using asyncio.create_task() and verify completion with asyncio.wait_for() with appropriate timeout constraints
Test queue operations using non-blocking queue.put_nowait() and asyncio.wait_for(queue.get(), timeout=...) to verify queue processing without blocking
Use @pytest.mark.no_blockbuster marker to skip the blockbuster plugin in specific tests
For database tests that may fail in batch runs, run them sequentially using uv run pytest src/backend/tests/unit/test_database.py r...

Files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
**/test_*.py

📄 CodeRabbit inference engine (Custom checks)

**/test_*.py: Review test files for excessive use of mocks that may indicate poor test design - check if tests have too many mock objects that obscure what's actually being tested
Warn when mocks are used instead of testing real behavior and interactions, and suggest using real objects or test doubles when mocks become excessive
Ensure mocks are used appropriately for external dependencies only, not for core logic
Backend test files should follow the naming convention test_*.py with proper pytest structure
Test files should have descriptive test function names that explain what is being tested
Tests should be organized logically with proper setup and teardown
Consider including edge cases and error conditions for comprehensive test coverage
Verify tests cover both positive and negative scenarios where appropriate
For async functions in backend tests, ensure proper async testing patterns are used with pytest
For API endpoints, verify both success and error response testing

Files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
🧠 Learnings (8)
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Inherit from the correct `ComponentTestBase` family class located in `src/backend/tests/base.py` based on API access needs: `ComponentTestBase` (no API), `ComponentTestBaseWithClient` (needs API), or `ComponentTestBaseWithoutClient` (pure logic). Provide three required fixtures: `component_class`, `default_kwargs`, and `file_names_mapping`

Applied to files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
📚 Learning: 2025-11-24T19:46:09.104Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.104Z
Learning: Applies to tests/unit/components/**/*.py : Create unit tests in `src/backend/tests/unit/components/` mirroring the component directory structure, using `ComponentTestBaseWithClient` or `ComponentTestBaseWithoutClient` base classes

Applied to files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Test component versioning and backward compatibility using `file_names_mapping` fixture with `VersionComponentMapping` objects mapping component files across Langflow versions

Applied to files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Create comprehensive unit tests for all new backend components. If unit tests are incomplete, create a corresponding Markdown file documenting manual testing steps and expected outcomes

Applied to files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Test component build config updates by calling `to_frontend_node()` to get the node template, then calling `update_build_config()` to apply configuration changes

Applied to files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
📚 Learning: 2025-08-05T22:51:27.961Z
Learnt from: edwinjosechittilappilly
Repo: langflow-ai/langflow PR: 0
File: :0-0
Timestamp: 2025-08-05T22:51:27.961Z
Learning: The TestComposioComponentAuth test in src/backend/tests/unit/components/bundles/composio/test_base_composio.py demonstrates proper integration testing patterns for external API components, including real API calls with mocking for OAuth completion, comprehensive resource cleanup, and proper environment variable handling with pytest.skip() fallbacks.

Applied to files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: When adding a new component test, inherit from the correct `ComponentTestBase` class and provide the three required fixtures (`component_class`, `default_kwargs`, `file_names_mapping`) to greatly reduce boilerplate and enforce version compatibility

Applied to files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Test both sync and async code paths, mock external dependencies appropriately, test error handling and edge cases, validate input/output behavior, and test component initialization and configuration

Applied to files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
🧬 Code graph analysis (2)
src/backend/tests/unit/components/models_and_agents/test_mcp_component.py (2)
src/lfx/src/lfx/components/models_and_agents/mcp_component.py (1)
  • MCPToolsComponent (51-680)
src/lfx/src/lfx/components/ollama/ollama.py (1)
  • headers (544-548)
src/lfx/src/lfx/components/models_and_agents/mcp_component.py (1)
src/lfx/src/lfx/inputs/inputs.py (2)
  • DictInput (551-563)
  • McpInput (730-742)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (15)
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 2
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 5
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 3
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 4
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 1
  • GitHub Check: Test Docker Images / Test docker images
  • GitHub Check: Lint Backend / Run Mypy (3.11)
  • GitHub Check: Lint Backend / Run Mypy (3.12)
  • GitHub Check: Lint Backend / Run Mypy (3.10)
  • GitHub Check: Run Backend Tests / Integration Tests - Python 3.10
  • GitHub Check: Test Starter Templates
  • GitHub Check: Run Backend Tests / LFX Tests - Python 3.10
  • GitHub Check: Run Ruff Check and Format
  • GitHub Check: Update Component Index
  • GitHub Check: Update Starter Projects
🔇 Additional comments (1)
src/lfx/src/lfx/components/models_and_agents/mcp_component.py (1)

81-91: Headers input wiring and default key inclusion look consistent

Adding "headers" to default_keys and introducing it as an advanced DictInput with is_list=True lines up with the intended “global per-component” configuration and ensures it survives remove_non_default_keys calls. I don’t see functional issues with this wiring.

Also applies to: 126-136

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
src/lfx/src/lfx/components/models_and_agents/mcp_component.py (1)

273-296: LGTM! Header merging logic handles edge cases correctly.

The implementation properly:

  • Converts list format [{"key": k, "value": v}] to dict
  • Falls back to dict format for flexibility
  • Converts existing server headers from list to dict if needed
  • Ensures component headers take precedence over server config headers

Consider adding a debug log when malformed list items are skipped, to aid troubleshooting misconfigured headers.

                 if isinstance(component_headers, list):
                     for item in component_headers:
                         if isinstance(item, dict) and "key" in item and "value" in item:
                             component_headers_dict[item["key"]] = item["value"]
+                        elif item is not None:
+                            await logger.adebug(f"Skipping malformed header item: {item}")
                 elif isinstance(component_headers, dict):
                     component_headers_dict = component_headers
src/backend/tests/unit/components/models_and_agents/test_mcp_component.py (3)

259-286: Consider extracting header merge logic into a testable function.

These tests duplicate the merging logic from update_tool_list instead of testing the actual component behavior. If the component's implementation changes, these tests would still pass with the outdated duplicated logic.

Consider extracting the header merging logic into a standalone function (e.g., merge_headers(component_headers, existing_headers)) that can be imported and tested directly:

# In mcp_component.py
def merge_headers(component_headers: list | dict | None, existing_headers: list | dict | None) -> dict:
    """Merge component headers with existing headers, component takes precedence."""
    component_headers_dict = {}
    headers_input = component_headers or []
    
    if isinstance(headers_input, list):
        for item in headers_input:
            if isinstance(item, dict) and "key" in item and "value" in item:
                component_headers_dict[item["key"]] = item["value"]
    elif isinstance(headers_input, dict):
        component_headers_dict = headers_input
    
    if not component_headers_dict:
        return existing_headers if isinstance(existing_headers, dict) else {}
    
    existing_dict = {}
    if isinstance(existing_headers, list):
        for item in existing_headers:
            if isinstance(item, dict) and "key" in item and "value" in item:
                existing_dict[item["key"]] = item["value"]
    elif isinstance(existing_headers, dict):
        existing_dict = existing_headers or {}
    
    return {**existing_dict, **component_headers_dict}

Then tests can import and call merge_headers directly without duplicating logic.


259-260: Async markers unnecessary for synchronous tests.

These header merge tests don't perform any async operations - they only set attributes and run synchronous assertions. The @pytest.mark.asyncio decorators can be removed.

-    @pytest.mark.asyncio
-    async def test_headers_merge_list_format(self, component):
+    def test_headers_merge_list_format(self, component):

Apply similar changes to all merge tests that don't actually await anything.

Also applies to: 288-289, 319-320, 344-345, 366-367, 398-399, 428-429, 466-467, 489-490


230-236: Consider adding an integration test for headers through update_tool_list.

While the unit tests cover the merge algorithm well, consider adding one test that verifies headers actually flow through update_tool_list by mocking the database access and checking the resulting server_config passed to update_tools.

Example integration test approach:

@pytest.mark.asyncio
async def test_headers_flow_through_update_tool_list(self, component):
    """Test that headers are actually merged into server_config during update_tool_list."""
    component.headers = [{"key": "Authorization", "value": "Bearer token"}]
    component.mcp_server = {"name": "test_server", "config": {"url": "http://test"}}
    component._user_id = "test_user"

    with (
        patch("langflow.api.v2.mcp.get_server", return_value=None),
        patch("langflow.services.database.models.user.crud.get_user_by_id", return_value=MagicMock()),
        patch("lfx.components.models_and_agents.mcp_component.session_scope"),
        patch("lfx.base.mcp.util.update_tools") as mock_update_tools,
    ):
        mock_update_tools.return_value = (None, [], {})
        await component.update_tool_list()
        
        # Verify headers were merged into server_config
        call_kwargs = mock_update_tools.call_args.kwargs
        assert call_kwargs["server_config"]["headers"] == {"Authorization": "Bearer token"}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 909bdb1 and 27f3eac.

📒 Files selected for processing (3)
  • src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json (2 hunks)
  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py (1 hunks)
  • src/lfx/src/lfx/components/models_and_agents/mcp_component.py (4 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
src/backend/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

src/backend/**/*.py: Use FastAPI async patterns with await for async operations in component execution methods
Use asyncio.create_task() for background tasks and implement proper cleanup with try/except for asyncio.CancelledError
Use queue.put_nowait() for non-blocking queue operations and asyncio.wait_for() with timeouts for controlled get operations

Files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
src/backend/**/*component*.py

📄 CodeRabbit inference engine (.cursor/rules/icons.mdc)

In Python component classes, set the icon attribute to a string matching the desired icon name (e.g., icon = "AstraDB"). The string must match the frontend icon mapping exactly (case-sensitive).

Files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
src/backend/tests/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/testing.mdc)

src/backend/tests/**/*.py: Place backend unit tests in src/backend/tests/ directory, component tests in src/backend/tests/unit/components/ organized by component subdirectory, and integration tests accessible via make integration_tests
Use same filename as component with appropriate test prefix/suffix (e.g., my_component.pytest_my_component.py)
Use the client fixture (FastAPI Test Client) defined in src/backend/tests/conftest.py for API tests; it provides an async httpx.AsyncClient with automatic in-memory SQLite database and mocked environment variables. Skip client creation by marking test with @pytest.mark.noclient
Inherit from the correct ComponentTestBase family class located in src/backend/tests/base.py based on API access needs: ComponentTestBase (no API), ComponentTestBaseWithClient (needs API), or ComponentTestBaseWithoutClient (pure logic). Provide three required fixtures: component_class, default_kwargs, and file_names_mapping
Create comprehensive unit tests for all new backend components. If unit tests are incomplete, create a corresponding Markdown file documenting manual testing steps and expected outcomes
Test both sync and async code paths, mock external dependencies appropriately, test error handling and edge cases, validate input/output behavior, and test component initialization and configuration
Use @pytest.mark.asyncio decorator for async component tests and ensure async methods are properly awaited
Test background tasks using asyncio.create_task() and verify completion with asyncio.wait_for() with appropriate timeout constraints
Test queue operations using non-blocking queue.put_nowait() and asyncio.wait_for(queue.get(), timeout=...) to verify queue processing without blocking
Use @pytest.mark.no_blockbuster marker to skip the blockbuster plugin in specific tests
For database tests that may fail in batch runs, run them sequentially using uv run pytest src/backend/tests/unit/test_database.py r...

Files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
**/test_*.py

📄 CodeRabbit inference engine (Custom checks)

**/test_*.py: Review test files for excessive use of mocks that may indicate poor test design - check if tests have too many mock objects that obscure what's actually being tested
Warn when mocks are used instead of testing real behavior and interactions, and suggest using real objects or test doubles when mocks become excessive
Ensure mocks are used appropriately for external dependencies only, not for core logic
Backend test files should follow the naming convention test_*.py with proper pytest structure
Test files should have descriptive test function names that explain what is being tested
Tests should be organized logically with proper setup and teardown
Consider including edge cases and error conditions for comprehensive test coverage
Verify tests cover both positive and negative scenarios where appropriate
For async functions in backend tests, ensure proper async testing patterns are used with pytest
For API endpoints, verify both success and error response testing

Files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
🧠 Learnings (7)
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Inherit from the correct `ComponentTestBase` family class located in `src/backend/tests/base.py` based on API access needs: `ComponentTestBase` (no API), `ComponentTestBaseWithClient` (needs API), or `ComponentTestBaseWithoutClient` (pure logic). Provide three required fixtures: `component_class`, `default_kwargs`, and `file_names_mapping`

Applied to files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Test component versioning and backward compatibility using `file_names_mapping` fixture with `VersionComponentMapping` objects mapping component files across Langflow versions

Applied to files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Test component build config updates by calling `to_frontend_node()` to get the node template, then calling `update_build_config()` to apply configuration changes

Applied to files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
📚 Learning: 2025-11-24T19:46:09.104Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.104Z
Learning: Applies to tests/unit/components/**/*.py : Create unit tests in `src/backend/tests/unit/components/` mirroring the component directory structure, using `ComponentTestBaseWithClient` or `ComponentTestBaseWithoutClient` base classes

Applied to files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
📚 Learning: 2025-08-05T22:51:27.961Z
Learnt from: edwinjosechittilappilly
Repo: langflow-ai/langflow PR: 0
File: :0-0
Timestamp: 2025-08-05T22:51:27.961Z
Learning: The TestComposioComponentAuth test in src/backend/tests/unit/components/bundles/composio/test_base_composio.py demonstrates proper integration testing patterns for external API components, including real API calls with mocking for OAuth completion, comprehensive resource cleanup, and proper environment variable handling with pytest.skip() fallbacks.

Applied to files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: When adding a new component test, inherit from the correct `ComponentTestBase` class and provide the three required fixtures (`component_class`, `default_kwargs`, `file_names_mapping`) to greatly reduce boilerplate and enforce version compatibility

Applied to files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Test both sync and async code paths, mock external dependencies appropriately, test error handling and edge cases, validate input/output behavior, and test component initialization and configuration

Applied to files:

  • src/backend/tests/unit/components/models_and_agents/test_mcp_component.py
🧬 Code graph analysis (1)
src/lfx/src/lfx/components/models_and_agents/mcp_component.py (1)
src/lfx/src/lfx/inputs/inputs.py (1)
  • DictInput (551-563)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 4
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 1
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 2
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 5
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 3
  • GitHub Check: Run Frontend Unit Tests / Frontend Jest Unit Tests
  • GitHub Check: Lint Backend / Run Mypy (3.11)
  • GitHub Check: Lint Backend / Run Mypy (3.10)
  • GitHub Check: Lint Backend / Run Mypy (3.12)
  • GitHub Check: Lint Backend / Run Mypy (3.13)
  • GitHub Check: Run Backend Tests / Integration Tests - Python 3.10
  • GitHub Check: Run Backend Tests / LFX Tests - Python 3.10
  • GitHub Check: Run Frontend Tests / Determine Test Suites and Shard Distribution
  • GitHub Check: Test Docker Images / Test docker images
  • GitHub Check: Test Starter Templates
  • GitHub Check: Optimize new Python code in this PR
  • GitHub Check: test-starter-projects
  • GitHub Check: Update Component Index
🔇 Additional comments (7)
src/lfx/src/lfx/components/models_and_agents/mcp_component.py (3)

18-18: LGTM!

Import correctly added for DictInput to support the new headers input.


81-91: LGTM!

Including "headers" in default_keys ensures the headers configuration persists when switching tools or cleaning the build config.


126-136: LGTM!

The headers input is well-configured with is_list=True for multiple entries and advanced=True to avoid cluttering the basic UI. The info text clearly documents the override precedence behavior.

src/backend/tests/unit/components/models_and_agents/test_mcp_component.py (2)

238-257: LGTM!

Good validation of the headers input configuration properties - checking existence, inclusion in default_keys, is_list, and advanced attributes.


467-487: Good edge case coverage for special characters.

Testing headers with JWT-like tokens and special characters ensures the implementation handles real-world authentication scenarios correctly.

src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json (2)

2318-2318: MCPTools metadata hash update is benign

The updated code_hash for MCPToolsComponent metadata is consistent with the embedded code changes; no action needed.


2378-2379: MCPToolsComponent headers merging logic looks solid

The updated MCPToolsComponent implementation correctly:

  • Adds headers to default_keys so the field survives config cleanup.
  • Introduces a DictInput headers input (advanced, list-aware).
  • Merges component-provided headers over server-config headers, handling both list ([{key, value}]) and dict forms, and normalizing server headers when needed.

This matches the intended precedence (component overrides server) and is defensive against malformed or cached configs.

Comment on lines +2380 to +2398
"headers": {
"_input_type": "DictInput",
"advanced": true,
"display_name": "Headers",
"dynamic": false,
"info": "HTTP headers to include with MCP server requests. Useful for authentication (e.g., Authorization header). These headers override any headers configured in the MCP server settings.",
"list": true,
"list_add_label": "Add More",
"name": "headers",
"override_skip": false,
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_input": true,
"track_in_telemetry": false,
"type": "dict",
"value": {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Avoid tracing potentially sensitive header values

headers is intended for HTTP headers like Authorization, which often contain secrets. In the template entry, it is currently marked with "trace_as_input": true, meaning header values may end up in traces or logs, even though "track_in_telemetry": false prevents external telemetry.

To reduce leakage risk, consider disabling input tracing for this field:

-              "trace_as_input": true,
+              "trace_as_input": false,
               "track_in_telemetry": false,

Optionally, you could also mention in the info text that this field may contain secrets and will not be traced, to set expectations for users configuring authentication headers.

🤖 Prompt for AI Agents
In src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json
around lines 2380 to 2398, the headers field is marked "trace_as_input": true
which risks leaking sensitive header values (e.g., Authorization); change
"trace_as_input" to false to prevent input tracing and optionally update the
"info" text to note that this field may contain secrets and will not be traced
so users know not to expect header values in traces.

@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 15, 2025
@github-actions
Copy link
Contributor

Frontend Unit Test Coverage Report

Coverage Summary

Lines Statements Branches Functions
Coverage: 17%
16.65% (4686/28138) 10.02% (2179/21743) 10.93% (676/6180)

Unit Test Results

Tests Skipped Failures Errors Time
1829 0 💤 0 ❌ 0 🔥 23.009s ⏱️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants