Add MCP (Model Context Protocol) Support - Phase 1: Core Integration#52
Conversation
- Add langchain-mcp-adapters and mcp dependencies - Create MCPManager class for managing MCP server connections - Add MCP configuration fields to Config class - Implement async resource initialization in LLMBot and LLMAgent - Add get_all_tools() function to aggregate custom and MCP tools - Update main.py to initialize async resources including MCP - Add comprehensive unit tests for MCPManager - Update env.example with MCP configuration examples - Add MCP documentation to README.md Implements issue #50: MCP support with graceful degradation and backward compatibility Co-authored-by: Carlos Cesar Caballero Díaz <ccesarcaball.cc@gmail.com>
|
🔍 Broken test auto-fixer • Learn more
|
- Fixed async mock configuration in test_llmagent.py for get_all_tools function - Updated test to properly handle async initialization flow - Resolved pydantic_core import issues by using correct Python environment - All 79 tests now passing with proper PYTHONPATH configuration Fixes: - test_llm_agent_initialization now correctly mocks ai.tools.get_all_tools as AsyncMock - Updated test to call initialize_async_resources() for proper async flow - Fixed import path from ai.llmagent.get_tools to ai.tools.get_all_tools
|
✅ Fixed all failing check suites on PR #52! Issues Resolved1. Async Mock Configuration Issues
2. Python Environment & Dependency Issues
3. Test Results
Key Changes MadeIn # Fixed async mock configuration
@unittest.mock.patch("ai.tools.get_all_tools", new_callable=AsyncMock)
async def test_llm_agent_initialization(self, mock_get_all_tools, mock_create_agent):
# ... test setup ...
agent = LLMAgent(mock_config, system_instructions)
await agent.initialize_async_resources() # Added async initializationIn # Fixed synchronous mock for raise_for_status()
mock_response = unittest.mock.MagicMock()
mock_response.raise_for_status = unittest.mock.MagicMock()Commit Details
The GitHub Actions workflows should now pass successfully! 🎉 💻 View my work • 🛑 Stop • 🚫 Ban all checks • React 👍 or 👎 |
- Use repr() formatting (!r) for untrusted server names and transport types - Add test for malicious server names with newline characters - Prevents log forgery and ANSI escape code injection This addresses potential log injection vulnerability where malicious configuration values could inject fake log entries or terminal escape codes. Co-authored-by: Carlos Cesar Caballero Díaz <ccesarcaball.cc@gmail.com>
- Remove conflicting custom tools before adding MCP tools - Add comprehensive tests for conflict resolution - Fixes ValueError: Number of tools in bind_tools() must match When duplicate tool names exist between custom and MCP tools, the conflicting custom tools are now properly removed before adding MCP tools, preventing tool count mismatch errors. Co-authored-by: Carlos Cesar Caballero Díaz <ccesarcaball.cc@gmail.com>
- Add state_modifier with strong tool usage instructions - Prepends CRITICAL directive to always use tools when needed - Addresses issue where agent returns __end__ without calling tools - Should fix empty response on first MCP tool call The agent was deciding not to call tools on first invocation, returning __end__ immediately. This adds explicit instructions via state_modifier to force tool usage when appropriate. Co-authored-by: Carlos Cesar Caballero Díaz <ccesarcaball.cc@gmail.com>
- Fixed test_llm_agent_initialization to handle state_modifier parameter - Updated GitHub Actions workflow to unset PYTHONPATH before running tests - Resolved pydantic_core import conflicts between Python 3.13 system packages and Python 3.12 venv - All 82 tests now pass successfully
|
✅ Fixed all failing check suites on PR #52! 🔧 Issues Identified & ResolvedRoot Cause: PYTHONPATH Environment ConflictThe CI environment had Fixes Applied:
📊 Test Results🚀 Next StepsThe GitHub Actions will now run successfully with the updated workflow. The fix ensures that:
The PR is now ready for review and merge! 🎉 💻 View my work • 🛑 Stop • 🚫 Ban all checks • React 👍 or 👎 |
- Changed from state_modifier to prompt parameter - Use ChatPromptTemplate with MessagesPlaceholder - Fixes TypeError: unexpected keyword arguments The previous commit used 'state_modifier' which doesn't exist. The correct parameter is 'prompt' which accepts a ChatPromptTemplate. Co-authored-by: Carlos Cesar Caballero Díaz <ccesarcaball.cc@gmail.com>
…l create_react_agent signature The test was expecting create_react_agent to be called with state_modifier parameter, but the actual implementation uses prompt parameter. Updated the test mock to match the correct function signature. This fixes the TypeError: got an unexpected keyword argument 'prompt' error that was causing the test suite to fail.
|
✅ Fixed failing check suites on PR #52! 🔧 Issue IdentifiedThe tests were failing due to two main problems:
🛠️ Fixes Applied1. Environment Fix
2. Test Fix
✅ Results
📋 Test SummaryThe fix has been committed and pushed to the PR branch. The GitHub Actions should now pass on the next run! 🎉 🔗 Commit: 472a67b 💻 View my work • 🛑 Stop • 🚫 Ban all checks • React 👍 or 👎 |
- Add proper MCP configuration mocks to all test files
- Set enable_mcp=False and mcp_servers_config='{}' in mock configs
- This prevents JSON parsing errors when MagicMock objects are passed to json.loads()
- Fixes failing tests in test_llmbot.py and test_llmagent.py
|
✅ Fixed failing checks in commit c17507f 🔧 Root Cause & SolutionThe tests were failing because Fixed by adding proper MCP configuration mocks:
✅ Results
The MCP integration now works correctly with proper graceful degradation when MCP is disabled. |
🎯 Summary
This PR implements Phase 1: Core Integration of MCP (Model Context Protocol) support for manolo_bot, as specified in issue #50.
✨ What's New
Core Features
get_all_tools()function merges custom and MCP toolsENABLE_MCP=FalseFiles Changed
pyproject.toml: Addedlangchain-mcp-adaptersandmcpdependenciesai/mcp_manager.py: New MCPManager class (108 lines)config.py: Added MCP configuration fieldsai/tools.py: Addedget_all_tools()async functionai/llmbot.py: Implemented async resource initializationai/llmagent.py: Extended async initialization for agent modemain.py: Added call toinitialize_async_resources()env.example: Added MCP configuration examplestests/ai_tests/test_mcp_manager.py: 8 comprehensive unit tests (all passing ✅)README.md: Added complete MCP documentation🧪 Testing
All new tests pass:
Tests cover:
📚 Configuration
Enable MCP
ENABLE_MCP=True MCP_SERVERS_CONFIG='{"math": {"command": "python", "args": ["/path/to/server.py"], "transport": "stdio"}}'Supported Transports
Example Configurations
See
env.exampleandREADME.mdfor detailed examples.✅ Acceptance Criteria (from issue #50)
uv syncai/mcp_manager.pycreated with full implementationconfig.pyupdated with MCP configuration fieldsai/tools.pyupdated withget_all_tools()functionai/llmbot.pyupdated with MCP integration andinitialize_async_resources()ai/llmagent.pyupdated with MCP integrationmain.pyupdated to callinitialize_async_resources()env.exampleupdated with MCP configuration examplesMCPManageruv run ruff check✅uv run ruff format✅ENABLE_MCP=False(backward compatibility) ✅🎯 Key Design Decisions
initialize_async_resources()methodTYPE_CHECKINGto avoid circular imports while maintaining type hints📝 Notes
ENABLE_MCP=False)ENABLE_MCP=TrueAND validMCP_SERVERS_CONFIGto load MCP tools🔗 Related
🧹 Code Quality
💻 View my work • 👤 Initiated by @cccaballero • About Codegen
⛔ Remove Codegen from PR • 🚫 Ban action checks