Skip to content

ref: refactor MCP-related functionality centralizing common utilities#9059

Merged
edwinjosechittilappilly merged 11 commits into
mainfrom
mcp-ref-common-codes
Jul 17, 2025
Merged

ref: refactor MCP-related functionality centralizing common utilities#9059
edwinjosechittilappilly merged 11 commits into
mainfrom
mcp-ref-common-codes

Conversation

@edwinjosechittilappilly
Copy link
Copy Markdown
Collaborator

@edwinjosechittilappilly edwinjosechittilappilly commented Jul 15, 2025

Purpose: Simplify the code base and a optimize the resuable elements in mcp.py and mcp_projects.py. This ensure better maintanence of the codebase.


This pull request refactors the MCP-related functionality in the backend by centralizing common utilities into a new module, mcp_support.py. It simplifies the codebase by removing redundant implementations and consolidating logic for handling MCP server operations. Additionally, it introduces global handlers for MCP server operations to streamline functionality.

Refactoring and Code Simplification:

  • Centralization of MCP Utilities: Common MCP utilities, such as handle_call_tool, handle_list_resources, handle_list_tools, and handle_read_resource, are now imported from mcp_support.py instead of being defined redundantly in multiple files. (src/backend/base/langflow/api/v1/mcp.py, [1]; src/backend/base/langflow/api/v1/mcp_projects.py, [2]
  • Removal of Redundant Code: Removed duplicate implementations of MCP handlers (handle_call_tool, handle_list_resources, handle_list_tools, handle_read_resource) and replaced them with global handlers that delegate to the centralized utilities. (src/backend/base/langflow/api/v1/mcp.py, src/backend/base/langflow/api/v1/mcp.pyL97-R67)

Improved Code Organization:

  • New Context Variable: Introduced a project-specific context variable, current_project_ctx, to manage project-specific state. (src/backend/base/langflow/api/v1/mcp_projects.py, src/backend/base/langflow/api/v1/mcp_projects.pyL26-R49)
  • File Imports Cleanup: Removed unused imports like base64, uuid4, and others to streamline the code and improve readability. (src/backend/base/langflow/api/v1/mcp.py, [1]; src/backend/base/langflow/api/v1/mcp_projects.py, [2]

These changes enhance maintainability by reducing duplication and improving modularity, making the MCP server logic easier to extend and debug.

Summary by CodeRabbit

  • Refactor

    • Centralized and streamlined MCP server logic for resource and tool handling, reducing duplication and improving maintainability.
    • Improved error handling and consistency across MCP-related endpoints.
  • New Features

    • Introduced a unified backend for listing and reading resources, executing tools, and listing available tools, enhancing reliability and user experience.
  • Chores

    • Cleaned up unused imports and legacy code for better code organization.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jul 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 refactor MCP server handler logic by moving all internal implementations from mcp.py and mcp_projects.py into a new centralized module, mcp_support.py. The original files now serve as thin adapters, delegating all resource, tool, and execution handling to the shared support module, which encapsulates error handling, database access, and flow execution.

Changes

File(s) Change Summary
src/backend/base/langflow/api/v1/mcp.py Removed all inline MCP handler logic and utilities; replaced with imports and thin wrappers calling mcp_support
src/backend/base/langflow/api/v1/mcp_projects.py Replaced all project-scoped MCP handler logic with calls to centralized functions from mcp_support
src/backend/base/langflow/api/v1/mcp_support.py New module containing all MCP handler logic, error handling, and shared utilities

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Router
    participant MCP_Handler (mcp.py/mcp_projects.py)
    participant MCP_Support

    Client->>Router: HTTP Request (e.g., list resources, call tool)
    Router->>MCP_Handler: Route to handler
    MCP_Handler->>MCP_Support: Call centralized handler (e.g., handle_list_resources)
    MCP_Support-->>MCP_Handler: Result (resources, tool output, etc.)
    MCP_Handler-->>Router: Return response
    Router-->>Client: Response
Loading

Possibly related PRs

Suggested labels

refactor, size:L, lgtm

Suggested reviewers

  • ogabrielluiz
  • mfortman11
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch mcp-ref-common-codes

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@edwinjosechittilappilly edwinjosechittilappilly changed the title @coderabbitai ref: QoL MCP and MCP Projects Merging the resusable elements Jul 15, 2025
@edwinjosechittilappilly
Copy link
Copy Markdown
Collaborator Author

Known Issues: MCP With Cursor Install not working, same experience as Main.

@edwinjosechittilappilly
Copy link
Copy Markdown
Collaborator Author

Next Step I am planning to have a Test suite for MCP!

@edwinjosechittilappilly edwinjosechittilappilly changed the title ref: QoL MCP and MCP Projects Merging the resusable elements ref: QoL MCP and MCP Projects merging the resusable elements Jul 15, 2025
@edwinjosechittilappilly edwinjosechittilappilly changed the title ref: QoL MCP and MCP Projects merging the resusable elements ref: MCP-related functionality centralizing common utilities Jul 15, 2025
@edwinjosechittilappilly edwinjosechittilappilly marked this pull request as ready for review July 15, 2025 18:45
@edwinjosechittilappilly
Copy link
Copy Markdown
Collaborator Author

Testing Ongoing!

@dosubot dosubot Bot added size:XL This PR changes 500-999 lines, ignoring generated files. enhancement New feature or request labels Jul 15, 2025
Copy link
Copy Markdown
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: 2

🧹 Nitpick comments (3)
src/backend/base/langflow/api/v1/mcp_support.py (3)

91-96: Simplify conditional assignment with ternary operator.

The if-else block can be simplified using a ternary operator as suggested by static analysis.

-            # Build query based on whether project_id is provided
-            if project_id:
-                # Filter flows by project (folder_id)
-                flows_query = select(Flow).where(Flow.folder_id == project_id)
-            else:
-                # Get all flows
-                flows_query = select(Flow)
+            # Build query based on whether project_id is provided
+            flows_query = (
+                select(Flow).where(Flow.folder_id == project_id)
+                if project_id
+                else select(Flow)
+            )

136-137: Remove unnecessary variable assignment.

The variable two is only used once and adds no clarity.

-        # The flow_id and filename should be the last two parts
-        two = 2
-        if len(path_parts) < two:
+        # The flow_id and filename should be the last two parts
+        if len(path_parts) < 2:

323-332: Consider extracting unique name generation logic.

The logic for generating unique names with numeric suffixes is complex and could be extracted to a helper function for better readability and reusability.

Would you like me to create a helper function to handle the unique name generation with numeric suffixes? This would improve code readability and make the logic reusable.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f07f0e2 and c177c80.

📒 Files selected for processing (3)
  • src/backend/base/langflow/api/v1/mcp.py (2 hunks)
  • src/backend/base/langflow/api/v1/mcp_projects.py (3 hunks)
  • src/backend/base/langflow/api/v1/mcp_support.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/backend/**/*.py

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/backend_development.mdc
🧠 Learnings (1)
src/backend/base/langflow/api/v1/mcp.py (4)
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Use 'anyio' and 'aiofiles' for async file operations in tests.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.464Z
Learning: Applies to src/backend/base/langflow/components/**/*.py : Use asyncio.Queue for non-blocking queue operations in async components and handle timeouts appropriately
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Be aware of ContextVar propagation in async tests and test both direct event loop execution and 'asyncio.to_thread' scenarios.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.464Z
Learning: Context variables may not propagate correctly in asyncio.to_thread; test both patterns
🪛 GitHub Check: Ruff Style Check (3.13)
src/backend/base/langflow/api/v1/mcp_support.py

[failure] 283-283: Ruff (FBT002)
src/backend/base/langflow/api/v1/mcp_support.py:283:46: FBT002 Boolean default positional argument in function definition


[failure] 163-163: Ruff (FBT002)
src/backend/base/langflow/api/v1/mcp_support.py:163:58: FBT002 Boolean default positional argument in function definition


[failure] 91-96: Ruff (SIM108)
src/backend/base/langflow/api/v1/mcp_support.py:91:13: SIM108 Use ternary operator flows_query = select(Flow).where(Flow.folder_id == project_id) if project_id else select(Flow) instead of if-else-block

🪛 GitHub Actions: Ruff Style Check
src/backend/base/langflow/api/v1/mcp_support.py

[error] 91-91: Ruff SIM108: Use ternary operator flows_query = select(Flow).where(Flow.folder_id == project_id) if project_id else select(Flow) instead of if-else-block.

⏰ 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). (1)
  • GitHub Check: Check PyPI Version Update
🔇 Additional comments (8)
src/backend/base/langflow/api/v1/mcp_projects.py (4)

24-31: LGTM! Clean import organization.

The imports from the centralized mcp_support.py module are well-organized and include all the necessary utilities for MCP operations.


45-47: Good use of context variables for project-specific state.

The introduction of current_project_ctx appropriately manages project-specific state alongside the user context.


653-655: Clean delegation to centralized handler.

The refactored handler correctly delegates to the centralized handle_list_tools function with appropriate parameters for project-specific filtering.


662-675: Excellent refactoring of MCP handlers.

All project-specific handlers now properly delegate to their centralized counterparts in mcp_support.py, passing the project ID and other necessary parameters. This significantly reduces code duplication and improves maintainability.

src/backend/base/langflow/api/v1/mcp.py (1)

46-67: Clean delegation pattern for global MCP handlers.

All global MCP handlers have been successfully refactored to delegate to the centralized implementations in mcp_support.py. The handlers correctly omit the project_id parameter for global operations.

src/backend/base/langflow/api/v1/mcp_support.py (3)

1-4: Good module documentation.

The module docstring clearly explains its purpose as the centralized source for MCP functionality.


197-201: Excellent progress notification implementation.

The progress notification logic properly checks for both the configuration flag and the presence of a progress token before sending notifications. The async task management with proper cancellation handling is well implemented.


238-255: Well-designed result deduplication logic.

The use of a set to track processed texts ensures no duplicate results are returned, and the handling of different result types (messages vs other values) is comprehensive.

Comment thread src/backend/base/langflow/api/v1/mcp.py Outdated

def get_mcp_config():
return MCPConfig()
# Common MCP utilities now imported from mcp_projects.py
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.

⚠️ Potential issue

Fix incorrect comment.

The comment incorrectly states that utilities are imported from mcp_projects.py, but they are actually imported from mcp_support.py.

-# Common MCP utilities now imported from mcp_projects.py
+# Common MCP utilities now imported from mcp_support.py
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Common MCP utilities now imported from mcp_projects.py
# Common MCP utilities now imported from mcp_support.py
🤖 Prompt for AI Agents
In src/backend/base/langflow/api/v1/mcp.py at line 23, the comment incorrectly
states that common MCP utilities are imported from mcp_projects.py. Update the
comment to correctly reflect that these utilities are imported from
mcp_support.py.

Comment on lines +162 to +164
async def handle_call_tool(
name: str, arguments: dict, server, project_id=None, is_action=False
) -> list[types.TextContent]:
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Jul 15, 2025

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use keyword-only arguments for boolean parameters.

Boolean positional arguments can be confusing at call sites. Consider making these parameters keyword-only for better clarity.

 async def handle_call_tool(
-    name: str, arguments: dict, server, project_id=None, is_action=False
+    name: str, arguments: dict, server, *, project_id=None, is_action=False
 ) -> list[types.TextContent]:
-async def handle_list_tools(project_id=None, mcp_enabled_only=False):
+async def handle_list_tools(*, project_id=None, mcp_enabled_only=False):

Also applies to: 283-283

🧰 Tools
🪛 GitHub Check: Ruff Style Check (3.13)

[failure] 163-163: Ruff (FBT002)
src/backend/base/langflow/api/v1/mcp_support.py:163:58: FBT002 Boolean default positional argument in function definition

🤖 Prompt for AI Agents
In src/backend/base/langflow/api/v1/mcp_support.py at lines 162-164 and also
line 283, the boolean parameter is_action should be made keyword-only to improve
clarity at call sites. Modify the function definitions to place a * before
is_action so that it can only be passed as a keyword argument, preventing
confusion from positional boolean arguments.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Can you explain why should we do that way?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

is it for fixing the ruff error?

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.

@edwinjosechittilappilly Great question! Let me explain why keyword-only boolean parameters are considered a best practice in Python:

The Problem with Positional Boolean Arguments

When boolean parameters can be passed positionally, it creates unclear code at call sites. For example:

# Current (confusing):
result = handle_call_tool("my_tool", {}, server, None, True)
# What does True mean? is_action? Some other flag?

# With multiple booleans, it gets worse:
tools = handle_list_tools(project_123, True) 
# Is True for mcp_enabled_only? Hard to tell without checking the function signature

Benefits of Keyword-Only Arguments

1. Self-Documenting Code

# Much clearer with keyword-only:
result = handle_call_tool("my_tool", {}, server, is_action=True)
tools = handle_list_tools(project_id=project_123, mcp_enabled_only=True)

2. Prevents Mistakes

# Easy to accidentally swap boolean values:
handle_call_tool("tool", {}, server, True, False)  # Which is which?

# Keyword-only prevents this:
handle_call_tool("tool", {}, server, project_id=None, is_action=True)  # Clear intent

3. Better Maintainability
If you need to add more parameters or reorder them later, keyword-only parameters are much safer and less likely to break existing code.

4. Python Best Practice
This aligns with PEP 570 and general Python style guidelines that recommend keyword-only arguments for flags and optional parameters to improve code clarity.

The * forces callers to be explicit about their intent, making the code more readable and maintainable. It's a small change that significantly improves code quality!

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.

@edwinjosechittilappilly Yes, the suggestion does fix the Ruff error FBT002, but the error exists for good reasons related to code clarity and maintainability.

The Ruff rule FBT002 flags boolean default positional arguments because they create confusing code at call sites. For example:

Confusing (current):

# What does False mean here?
result = await handle_call_tool("my_tool", {}, server, None, False)

Clear (with keyword-only):

# Much clearer what False refers to
result = await handle_call_tool("my_tool", {}, server, project_id=None, is_action=False)

The keyword-only approach (* before the parameter) forces callers to be explicit about what the boolean argument represents, making the code more readable and less error-prone. This is especially important in functions with multiple parameters where the boolean's meaning isn't obvious from position alone.

So while it does fix the Ruff error, the underlying motivation is improving code quality and preventing bugs that can arise from unclear boolean arguments.

                /|   /|  
               ( :v:  )
                |(_)|
               -"-"-

Updated function calls in mcp_projects.py to use explicit keyword arguments for clarity. Refactored mcp_support.py to use more concise query assignment and added keyword-only arguments to handle_call_tool and handle_list_tools for improved code readability and maintainability.
@edwinjosechittilappilly
Copy link
Copy Markdown
Collaborator Author

@coderabbitai check the production readiness of the changes made.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jul 16, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

@edwinjosechittilappilly I'll analyze the production readiness of your MCP refactoring changes. Let me examine the code structure, error handling, and potential issues.

Based on my analysis, here's my assessment of the production readiness of your MCP refactoring changes:

🟢 Strengths (Production Ready)

  1. Code Consolidation: Excellent refactoring that eliminates code duplication and creates a centralized support module
  2. Error Handling: Comprehensive error handling with the handle_mcp_errors decorator and proper logging
  3. Database Management: Proper session management with with_db_session helper
  4. Type Safety: Good use of type hints and proper async/await patterns
  5. Modularity: Clean separation of concerns with thin adapter layers

🟡 Areas Requiring Attention

  1. Testing Coverage: You mentioned planning a test suite - this is critical for production readiness
  2. Context Variables: The current_user_ctx and current_project_ctx variables need proper context propagation testing
  3. Database Transaction Handling: Ensure proper rollback mechanisms in error scenarios
  4. Configuration Management: The MCPConfig singleton needs proper initialization and thread safety

🔴 Production Concerns

  1. Known Issue: MCP with Cursor Install not working (as you mentioned) - this needs resolution before production
  2. Missing Integration Tests: The refactored handlers need comprehensive integration testing
  3. Performance Impact: Centralized handlers may introduce bottlenecks under high load
  4. Backward Compatibility: Verify all existing MCP integrations still work

📋 Recommendations for Production Readiness

  1. Implement comprehensive test suite (as you planned) covering:

    • Unit tests for all handlers in mcp_support.py
    • Integration tests for the adapter layers
    • Error scenario testing
    • Performance benchmarks
  2. Add monitoring and observability:

    • Performance metrics for handler execution times
    • Error rate monitoring
    • Database connection pool monitoring
  3. Security review:

    • Input validation for all MCP operations
    • Permission checks for project-specific operations
    • Rate limiting for tool execution
  4. Documentation:

    • Update API documentation for any signature changes
    • Add deployment notes for the new module structure

🎯 Next Steps

  1. ✅ Complete the test suite development
  2. ✅ Fix the Cursor Install issue
  3. ✅ Add performance monitoring
  4. ✅ Security audit of the centralized handlers
  5. ✅ Gradual rollout with feature flags

The refactoring is well-structured and follows good practices, but the missing test coverage and known issues need resolution before production deployment.

    (\   /)
   ( ._.)
  o_(")(")  *thinking deeply about production readiness*

🏁 Script executed:

#!/bin/bash
# Analyze the new mcp_support.py module for production readiness issues
echo "=== Analyzing mcp_support.py structure ==="
cat src/backend/base/langflow/api/v1/mcp_support.py | head -50

echo -e "\n=== Checking imports and dependencies ==="
grep -n "^from\|^import" src/backend/base/langflow/api/v1/mcp_support.py

echo -e "\n=== Analyzing error handling patterns ==="
grep -n -A3 -B1 "except\|raise\|Error\|Exception" src/backend/base/langflow/api/v1/mcp_support.py

echo -e "\n=== Checking logging usage ==="
grep -n "logger\|log\|logging" src/backend/base/langflow/api/v1/mcp_support.py

echo -e "\n=== Analyzing database operations ==="
grep -n -A2 -B2 "session\|db\|database\|commit\|rollback" src/backend/base/langflow/api/v1/mcp_support.py

Length of output: 10920


🏁 Script executed:

#!/bin/bash
# Check for security and validation patterns
echo "=== Security analysis - input validation ==="
grep -n -A3 -B1 "validate\|sanitize\|clean" src/backend/base/langflow/api/v1/mcp_support.py

echo -e "\n=== Check for potential SQL injection or unsafe operations ==="
grep -n -A2 -B2 "query\|filter\|where\|execute" src/backend/base/langflow/api/v1/mcp_support.py

echo -e "\n=== Analyze async/await usage ==="
grep -n "async\|await" src/backend/base/langflow/api/v1/mcp_support.py | head -20

echo -e "\n=== Check for hardcoded values or configuration issues ==="
grep -n -E "['\"][^'\"]*['\"]" src/backend/base/langflow/api/v1/mcp_support.py | grep -v "import\|from" | head -10

Length of output: 5481


🏁 Script executed:

#!/bin/bash
# Analyze the adapter files for potential breaking changes
echo "=== Checking mcp.py for breaking changes ==="
echo "Old vs New function signatures:"
grep -n "def handle_" src/backend/base/langflow/api/v1/mcp.py

echo -e "\n=== Checking mcp_projects.py for breaking changes ==="
grep -n "def handle_" src/backend/base/langflow/api/v1/mcp_projects.py

echo -e "\n=== Analyzing context variable usage ==="
grep -n -A2 -B2 "current_.*_ctx" src/backend/base/langflow/api/v1/mcp_support.py src/backend/base/langflow/api/v1/mcp.py src/backend/base/langflow/api/v1/mcp_projects.py

echo -e "\n=== Check for TODO comments or incomplete code ==="
grep -n -i "todo\|fixme\|hack\|xxx" src/backend/base/langflow/api/v1/mcp_support.py src/backend/base/langflow/api/v1/mcp.py src/backend/base/langflow/api/v1/mcp_projects.py

Length of output: 6877


🏁 Script executed:

#!/bin/bash
# Check for proper resource cleanup and memory management
echo "=== Resource management analysis ==="
grep -n -A3 -B3 "close\|cleanup\|dispose\|finally\|with " src/backend/base/langflow/api/v1/mcp_support.py

echo -e "\n=== Check for concurrent operations and race conditions ==="
grep -n -A2 -B2 "lock\|mutex\|semaphore\|concurrent" src/backend/base/langflow/api/v1/mcp_support.py

echo -e "\n=== Analyze configuration and environment dependencies ==="
grep -n -A2 -B2 "config\|settings\|env\|ENV" src/backend/base/langflow/api/v1/mcp_support.py

echo -e "\n=== Check for proper typing and type hints ==="
grep -n -A1 -B1 "def \|async def " src/backend/base/langflow/api/v1/mcp_support.py | head -20

Length of output: 5208


Based on my comprehensive analysis of the codebase, here's my detailed production readiness assessment:

🟢 Production-Ready Aspects

1. Error Handling & Logging

Excellent implementation

  • Comprehensive error handling with handle_mcp_errors decorator
  • Proper exception propagation and logging with loguru
  • Structured error messages with context information
  • Graceful degradation for non-critical failures (file listing)

2. Database Operations

Well-structured

  • Proper session management with session_scope() context manager
  • Clean separation of database operations in with_db_session
  • Appropriate use of SQLModel for query building
  • No SQL injection vulnerabilities detected

3. Security Practices

Good foundation

  • Input sanitization with sanitize_mcp_name function
  • URL decoding for file paths with unquote
  • Base64 encoding for binary content
  • Proper user context management

4. Resource Management

Proper cleanup

  • Context managers for database sessions
  • Async task cancellation in finally blocks
  • Progress notification cleanup on errors
  • No memory leaks detected

5. Code Structure

Well-organized

  • Clear separation of concerns with centralized support module
  • Proper typing with TypeVar and ParamSpec
  • Consistent async/await usage
  • Good function signatures and documentation

🟡 Areas Needing Attention

1. Input Validation

  • Limited validation beyond name sanitization
  • Recommendation: Add comprehensive input validation for:
    • Tool arguments schema validation
    • File path traversal protection
    • Resource URI format validation

2. Configuration Management

  • Singleton pattern for MCPConfig may cause issues in multi-threaded environments
  • Recommendation: Consider thread-safe configuration management

3. Error Boundaries

  • Generic exception handling in some places (except Exception)
  • Recommendation: Use more specific exception types where possible

🔴 Critical Production Blockers

1. Missing Test Coverage

  • No automated tests for the refactored functionality
  • Impact: High risk of regressions and production failures
  • Recommendation: MUST implement comprehensive test suite before production

2. Known Functional Issues

  • MCP with Cursor Install not working (acknowledged by user)
  • Impact: Critical functionality broken
  • Recommendation: MUST resolve before production deployment

3. Performance Considerations

  • No rate limiting or DOS protection
  • Potential bottlenecks in centralized handlers
  • Recommendation: Add performance monitoring and rate limiting

📋 Production Readiness Checklist

Critical (Must Fix)

  • Implement comprehensive test suite (unit + integration tests)
  • Fix MCP with Cursor Install issue
  • Add performance monitoring and metrics
  • Implement rate limiting for tool execution

High Priority (Should Fix)

  • Add input validation for tool arguments
  • Implement circuit breaker pattern for external calls
  • Add request/response logging for debugging
  • Set up health checks for MCP services

Medium Priority (Nice to Have)

  • Add more specific exception types
  • Implement request tracing/correlation IDs
  • Add configuration validation on startup
  • Enhance documentation for new architecture

🎯 Final Verdict

❌ NOT READY FOR PRODUCTION - Critical blockers must be resolved

Blocking Issues:

  1. Missing test coverage - High risk of production failures
  2. Known functional issue - MCP with Cursor Install broken
  3. No performance safeguards - Risk of service degradation

Recommendation:

  • Complete the test suite implementation (as planned)
  • Fix the Cursor Install issue
  • Add basic performance monitoring
  • Then proceed with staged rollout

Estimated Timeline to Production Ready: 1-2 weeks with focused effort on testing and bug fixes.

The refactoring itself is well-executed and follows good practices, but the lack of test coverage and known issues make it unsuitable for production deployment at this time.

    (\   /)
   ( ._.)
  o_(")(")  *carefully analyzing production readiness*

🧠 Learnings used
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.849Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Complex test setups should be commented, and mock usage should be documented within the test code.

Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-06-30T14:40:29.510Z
Learning: All changes must be tested in both light and dark mode before committing.

Comment thread src/backend/base/langflow/api/v1/mcp.py Outdated

# Create a context variable to store the current user
current_user_ctx: ContextVar[User] = ContextVar("current_user_ctx")
# Context variable now imported from mcp_projects.py
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

can remove

from langflow.services.storage.utils import build_content_type_from_extension
from langflow.services.deps import get_settings_service, session_scope

# Common MCP utilities now imported from mcp_support.py
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

can remove all these comments

@@ -0,0 +1,348 @@
"""Common MCP handler functions shared between mcp.py and mcp_projects.py.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

maybe mcp_utils.py instead of support

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

We have a mcp.utils.py in a different folder, but happy to rename.


# Build full URL from settings
host = getattr(settings_service.settings, "host", "localhost")
port = getattr(settings_service.settings, "port", 3000)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why is this port hardcoded?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

thats the default value when the value is not available.Let me cross check this with the previous implementations.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It was the Port of the FE.

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.

The frontend port is only used in dev, though.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

On checking the current main found that this was utilised to frame the earlier versions of MCP URL.

Currently this is not used just kept for reverse compatibility , ideally in long run we need to deprecate the API in mcp.py

Comment thread src/backend/base/langflow/api/v1/mcp_support.py
msg = f"Error in listing tools: {e!s} from flow: {base_name}"
logger.warning(msg)
continue
except Exception as e:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is fine for now, but we should be aware that catching a generic exception in such a large block isn’t ideal. Better to use more targeted try-except blocks where possible.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Sure Adding as ToDo, post refactor changes

@github-actions github-actions Bot added the lgtm This PR has been approved by a maintainer label Jul 17, 2025
@ogabrielluiz ogabrielluiz changed the title ref: MCP-related functionality centralizing common utilities ref: refactor MCP-related functionality centralizing common utilities Jul 17, 2025
Renamed mcp_support.py to mcp_utils.py for clarity and updated all relevant import statements in mcp.py and mcp_projects.py to reflect the new module name.
@edwinjosechittilappilly edwinjosechittilappilly added this pull request to the merge queue Jul 17, 2025
Merged via the queue into main with commit e20ae03 Jul 17, 2025
35 checks passed
@edwinjosechittilappilly edwinjosechittilappilly deleted the mcp-ref-common-codes branch July 17, 2025 19:32
2getsandesh pushed a commit to 2getsandesh/langflow-IBM that referenced this pull request Aug 6, 2025
…langflow-ai#9059)

* reactor to have common mcp codes in mcp_support

* [autofix.ci] apply automated fixes

* Refactor MCP API argument passing and function signatures

Updated function calls in mcp_projects.py to use explicit keyword arguments for clarity. Refactored mcp_support.py to use more concise query assignment and added keyword-only arguments to handle_call_tool and handle_list_tools for improved code readability and maintainability.

* Rename mcp_support.py to mcp_utils.py and update imports

Renamed mcp_support.py to mcp_utils.py for clarity and updated all relevant import statements in mcp.py and mcp_projects.py to reflect the new module name.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
@coderabbitai coderabbitai Bot mentioned this pull request Sep 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request lgtm This PR has been approved by a maintainer size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants