A Model Context Protocol (MCP) Server that provides unified access to multiple external APIs through a single, consistent interface. Built for AI agents and LLMs, this server aggregates weather, news, and financial data into standardized tool calls.
- ✅ MCP Protocol Compliant: Full JSON-RPC 2.0 support with proper tool discovery
- ✅ Multiple API Integrations: Weather, news, and stock market data
- ✅ Unified Error Handling: Consistent error responses across all APIs
- ✅ Type-Safe: Full type hints and Pydantic validation
- ✅ Async Support: High-performance async/await throughout
- ✅ Structured Logging: Rich, structured logs for monitoring
- ✅ Environment-Based Config: Secure API key management
# Clone the repository
git clone <repository-url>
cd api-aggregator-mcp
# Install dependencies
pip install -r requirements.txt
Create a .env
file with your API keys:
# Required for weather data
OPENWEATHER_API_KEY=your_openweather_api_key_here
# Required for news data
NEWS_API_KEY=your_news_api_key_here
# Required for stock data
ALPHA_VANTAGE_API_KEY=your_alpha_vantage_api_key_here
# Optional server configuration
MCP_SERVER_HOST=localhost
MCP_SERVER_PORT=8000
MCP_SERVER_DEBUG=true
LOG_LEVEL=INFO
- OpenWeatherMap: Get free API key
- News API: Get free API key
- Alpha Vantage: Get free API key
python -m src.main
The server will start at http://localhost:8000
Get current weather information for any city.
Parameters:
city
(required): City namecountry
(optional): Country code (e.g., "US", "GB")units
(optional): Temperature units - "metric" (default), "imperial", or "kelvin"
Example:
{
"city": "London",
"country": "GB",
"units": "metric"
}
Response:
{
"location": {
"city": "London",
"country": "GB",
"coordinates": {"latitude": 51.5074, "longitude": -0.1278}
},
"weather": {
"condition": "Clouds",
"description": "overcast clouds"
},
"temperature": {
"current": 15.2,
"feels_like": 14.8,
"unit": "°C"
},
"humidity": "73%",
"wind": {"speed": "3.5 m/s", "direction": "240°"}
}
Get latest news headlines by topic or region.
Get current stock prices and financial data.
GET /
GET /tools
POST /tools/{tool_name}
Content-Type: application/json
{
"city": "New York",
"units": "imperial"
}
POST /mcp
Content-Type: application/json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": {
"city": "Tokyo",
"country": "JP"
}
},
"id": "1"
}
api-aggregator-mcp/
├── src/
│ ├── main.py # Application entry point
│ ├── server.py # MCP server implementation
│ ├── tools/ # API tool implementations
│ │ ├── weather.py # Weather API integration
│ │ ├── news.py # News API integration (TODO)
│ │ └── stock.py # Stock API integration (TODO)
│ └── utils/
│ ├── config.py # Configuration management
│ └── errors.py # Error handling utilities
├── tests/ # Unit tests
├── requirements.txt # Dependencies
└── README.md # This file
pytest tests/
# Format code
black src/
# Lint code
flake8 src/
# Type checking
mypy src/
- Create a new file in
src/tools/
- Implement the service class and handler function
- Define the tool schema
- Register in
src/main.py
Example tool template:
# src/tools/example.py
async def example_handler(parameters: Dict[str, Any]) -> Dict[str, Any]:
"""Handler for example tool."""
# Validate parameters
# Call external API
# Return normalized data
pass
EXAMPLE_TOOL_SCHEMA = {
"type": "object",
"properties": {
"param1": {"type": "string", "description": "..."},
},
"required": ["param1"],
}
All errors are returned in JSON-RPC format:
{
"jsonrpc": "2.0",
"error": {
"code": -32001,
"message": "API key missing for OpenWeatherMap",
"data": {"api": "OpenWeatherMap"}
},
"id": "1"
}
Common error codes:
-32001
: API key missing-32002
: API key invalid-32003
: External API error-32004
: Rate limit exceeded-32602
: Invalid parameters
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
MIT License - see LICENSE file for details.