A Python application that hosts AI assistants (OpenAI GPT or Claude) with Model Context Protocol (MCP) integration, allowing AI to use external tools and services. Now with library-like architecture for easy integration into other applications!
- π€ Multi-AI Support: Works with both OpenAI GPT and Claude
- π§ MCP Integration: Connect to various MCP servers for extended functionality
- π― Tool Calling: AI can automatically use available MCP tools
- βοΈ Configurable: Easy JSON-based configuration
- π¬ Interactive CLI: Chat interface with command support
- π Extensible: Add new MCP servers easily
- π Library-like: Core chat functionality can be used programmatically in other applications
# Clone the repository
git clone <repository-url>
cd ai-mcp-host
# Quick setup with Makefile (recommended)
make install
# Or manual setup:
# pip install -r requirements.txt
# Install Node.js (required for MCP servers)
# On macOS: brew install node
# On Ubuntu: sudo apt install nodejs npmNote: Configuration files are automatically created when you run make install.
Set up your API keys by creating a .env file:
# Create .env file with your API keys
cat > .env << EOF
# Choose one or both AI providers
ANTHROPIC_API_KEY=your-anthropic-api-key-here
OPENAI_API_KEY=your-openai-api-key-here
# Optional: MCP server tokens (configure as needed)
# SLACK_MCP_XOXP_TOKEN=your-slack-bot-token
# SLACK_TEAM_ID=your-slack-team-id
# NOTION_API_KEY=your-notion-api-key
# SUPABASE_ACCESS_TOKEN=your-supabase-token
EOFImportant: Never commit .env files to git. They are automatically ignored by .gitignore.
Configure MCP servers by editing mcp_config.json:
# Copy the example file (done automatically by make install)
cp mcp_config.example.json mcp_config.json
# Edit mcp_config.json to configure your desired MCP serversExample configuration:
{
"ai": {
"provider": "openai",
"model": "gpt-4",
"api_key_env": "OPENAI_API_KEY"
},
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
"disabled": false,
"autoApprove": []
}
}
}# Using Makefile (recommended)
make run
# Or directly
python mcp-use-cli.py
# Or using the run script
./run_mcp_use.shThe project includes a comprehensive Makefile for easy development:
# Setup and installation
make install # Complete setup (dependencies, venv, env)
make setup # Alias for install
# Development
make run # Start the application
make dev # Alias for run
make test # Run tests
make lint # Run linting checks
make format # Format code with black
make check # Run lint + test
# Utilities
make clean # Clean cache files
make clean-all # Clean everything including venv
make status # Show system status
make logs # Show recent logs
make update # Update dependencies
# Quick shortcuts
make i # Quick install
make r # Quick run
make c # Quick clean
make t # Quick test
make l # Quick lint
make f # Quick format
# Help
make help # Show all available commandsThe configuration includes several pre-configured MCP servers:
- Filesystem: File system operations
- Brave Search: Web search capabilities
- SQLite: Database operations
- GitHub: GitHub repository access
- PostgreSQL: PostgreSQL database operations
Enable them by setting "disabled": false and providing required API keys.
help- Show available commandsclear- Clear conversation historytools- List available MCP toolsstatus- Show MCP connection statusquit- Exit application
You: Can you search for information about Python async programming?
π€ Assistant: I'll search for information about Python async programming for you.
π§ Calling tool: brave_search
β
Tool result: {...}
Based on my search, here's what I found about Python async programming...
{
"ai": {
"provider": "openai", // "openai" or "claude"
"model": "gpt-4", // Model name
"api_key_env": "OPENAI_API_KEY" // Environment variable name
}
}{
"mcpServers": {
"server_name": {
"command": "npx", // Command to run
"args": ["-y", "package-name"], // Command arguments
"env": { // Environment variables
"API_KEY": "your-key"
},
"disabled": false, // Enable/disable server
"autoApprove": ["tool_name"] // Auto-approve specific tools
}
}
}- Find an MCP server package (usually npm packages)
- Add configuration to
mcp_config.json - Set required environment variables
- Enable the server and restart
Example:
{
"my_custom_mcp": {
"command": "python",
"args": ["-m", "my_mcp_server"],
"env": {
"CUSTOM_API_KEY": "key-here"
},
"disabled": false,
"autoApprove": ["safe_tool_name"]
}
}-
MCP Server Not Starting
- Check if Node.js is installed
- Verify command and arguments in config
- Check environment variables
-
AI API Errors
- Verify API key is set correctly
- Check internet connection
- Ensure sufficient API credits
-
Tool Calls Failing
- Check MCP server logs
- Verify tool parameters
- Ensure MCP server is connected
Enable debug logging by setting:
export PYTHONPATH=.
python -c "import logging; logging.basicConfig(level=logging.DEBUG)"
python mcp-use-cli.pyThe application now features a library-like architecture where core chat functionality is separated from interface-specific code, making it easy to integrate into other applications.
βββββββββββββββββββ
β CLI Interface β β All chat logic embedded here
β β β Tightly coupled to console
β β’ User input β β Hard to reuse elsewhere
β β’ AI calls β
β β’ Tool calls β
β β’ History mgmt β
βββββββββββββββββββ
βββββββββββββββββββ βββββββββββββββββββ
β CLI Interface βββββΆβ ChatService β β Core library
β β β (Library) β β Reusable
βββββββββββββββββββ βββββββββββββββββββ
β²
βββββββββββββββββββ β
β API Interface βββββββββββββ
β β
βββββββββββββββββββ
β²
βββββββββββββββββββ β
β Custom App βββββββββββββ
β β
βββββββββββββββββββ
The main library that handles all chat functionality:
class ChatService:
def __init__(self, ai_client, mcp_manager, verbose=False, output_handler=None):
# Core dependencies
self.ai_client = ai_client # AI/LLM client
self.mcp_manager = mcp_manager # MCP tools manager
self.verbose = verbose # Detail level
self.output_handler = output_handler # Custom output handling@dataclass
class ChatMessage:
role: str # 'user', 'assistant', 'system'
content: str # Message content
tool_calls: List # Any tool calls made
usage: Dict # Token usage info
@dataclass
class ChatResponse:
message: ChatMessage # AI's response
tool_calls_executed: List # Tools that were executed
success: bool # Whether chat succeeded
error: Optional[str] # Any error messageAllows different interfaces to handle output differently:
def custom_output_handler(message_type: str, content: str, data=None):
if message_type == "assistant_response":
# CLI: print to console
# API: add to JSON response
# GUI: update chat window
elif message_type == "tool_call":
# Handle tool execution notificationsHere's what happens when you send a message:
1. User Message
β
2. ChatService.chat(message)
β
3. Format available MCP tools for AI
β
4. Call AI client with message + tools
β
5. AI responds with content Β± tool calls
β
6. If tool calls exist:
ββ Execute tools via MCP manager
ββ Get tool results
ββ Send results back to AI
ββ Get follow-up AI response
β
7. Return structured ChatResponse
β
8. Output handler displays results
# In cli_interface.py
self.chat_service = ChatService(ai_client, mcp_manager, verbose=self.verbose)
response = await self.chat_service.chat(user_input)
# Output automatically handled by default console handler# In your own code
from chat_service import ChatService
# Initialize
chat_service = ChatService(ai_client, mcp_manager, verbose=True)
# Use directly
response = await chat_service.chat("What tools do you have?")
print(f"AI said: {response.message.content}")
print(f"Tools used: {len(response.tool_calls_executed)}")# In a web API
async def handle_chat_request(message: str):
# Custom output handler for API responses
api_output = []
def api_handler(msg_type, content, data=None):
api_output.append({"type": msg_type, "content": content})
chat_service = ChatService(ai_client, mcp_manager,
output_handler=api_handler)
response = await chat_service.chat(message)
return {
"response": response.message.content,
"tools_used": response.tool_calls_executed,
"output_log": api_output
}- ChatService: Core chat logic, AI interactions, tool management
- CLIInterface: User interface, command parsing, console output
- Other interfaces: Can focus on their specific UI/API concerns
- Same chat logic works in CLI, web APIs, desktop apps, etc.
- No code duplication
- Consistent behavior across interfaces
- CLI: Prints to console with colors/emojis
- API: Collects output for JSON responses
- GUI: Updates chat windows/notifications
- Custom: Whatever you need
- ChatService can be tested independently
- Mock output handlers for testing
- Clear separation makes debugging easier
To add a new interface (e.g., web API):
- Create your interface class
- Initialize ChatService with custom output handler
- Call
chat_service.chat(message)for interactions - Handle the structured response as needed
The core chat functionality remains the same - you just change how input comes in and output goes out!
mcp-use-cli.py- Application entry point using mcp-use librarychat_service.py- Core chat library (NEW) - reusable chat functionalityai_client.py- AI provider abstraction (OpenAI/Claude)mcp_manager.py- MCP connection and tool managementcli_interface.py- Interactive command-line interface (now uses ChatService)mcp_config.json- Configuration file
- Fork the repository
- Create a feature branch
- Make changes and test
- Submit a pull request
MIT License - see LICENSE file for details.