Skip to main content
Glama
README.md
# Updation MCP Local Server

**Production-grade Model Context Protocol (MCP) server with LLM-agnostic architecture**

## 🌟 Key Features

- āœ… **LLM-Agnostic**: Seamlessly switch between OpenAI, Claude, Gemini, or Azure OpenAI
- āœ… **Production-Ready**: Structured logging, metrics, error handling, and observability
- āœ… **Scalable**: Redis-backed state management for horizontal scaling
- āœ… **Secure**: RBAC, rate limiting, input validation, and secret management
- āœ… **Modular**: Auto-discovery tool architecture for easy extensibility
- āœ… **Type-Safe**: Full Pydantic validation throughout
- āœ… **Resilient**: Circuit breakers, retries, and graceful degradation

## šŸ—ļø Architecture

```
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                    FastAPI Web Chat API                      │
│                    (Port 8002)                               │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                         │
                         ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                  LLM Orchestrator                            │
│  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”   │
│  │  LLM Provider Abstraction Layer                      │   │
│  │  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”            │   │
│  │  │ OpenAI   │ │ Claude   │ │ Gemini   │            │   │
│  │  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜            │   │
│  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜   │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                         │
                         ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                    MCP Server (Port 8050)                    │
│  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”   │
│  │  Auto-Discovery Tool Registry                        │   │
│  │  ā”œā”€ā”€ User Tools (subscriptions, bookings, etc.)     │   │
│  │  ā”œā”€ā”€ Organization Tools (locations, resources)      │   │
│  │  └── Payment Tools                                  │   │
│  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜   │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                         │
                         ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│              External Services                               │
│  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”      │
│  │ Updation API │  │    Redis     │  │  Prometheus  │      │
│  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜      │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
```

## šŸš€ Quick Start

### 1. Prerequisites

- **Python 3.11+**
- **Redis** (required for conversation memory - see setup below)
- **UV package manager** (recommended) or pip

### 2. Installation

```bash
# Clone or navigate to project
cd /Users/saimanvithmacbookair/Desktop/Updation_MCP_Local

# Create virtual environment
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install dependencies
pip install -e .

# Or with UV (faster)
uv pip install -e .
```

### 3. Install Redis (Mac M2)

**Redis is required for conversation memory to work!**

```bash
# Install Redis via Homebrew
brew install redis

# Start Redis (background service)
brew services start redis

# Verify it's running
redis-cli ping  # Should return: PONG
```

**See `REDIS_SETUP.md` for detailed instructions and troubleshooting.**

### 4. Configuration

```bash
# Copy environment template
cp .env.example .env

# Edit .env with your actual values
nano .env  # or use your favorite editor
```

**Required settings:**
```bash
# LLM Provider
LLM_PROVIDER=openai
OPENAI_API_KEY=your-key-here

# Laravel API
UPDATION_API_BASE_URL=http://127.0.0.1:8000/api

# Redis (should already be correct)
REDIS_ENABLED=true
REDIS_URL=redis://localhost:6379/0

# Enable auto-reload for development (optional)
WEB_CHAT_RELOAD=true  # Auto-restart on code changes
```

### 5. Run the Services

**Terminal 1: MCP Server**
```bash
source .venv/bin/activate
python -m src.mcp_server.server
```

**Terminal 2: Web Chat API (with auto-reload)**
```bash
source .venv/bin/activate
python -m src.web_chat.main
```

**Note:** With `WEB_CHAT_RELOAD=true`, Terminal 2 will auto-restart when you edit code!

# Terminal 3 (optional): Start metrics server
python -m src.observability.metrics_server
```

### 6. Test the Setup

**Quick health check:**
```bash
curl http://localhost:8002/health
```

**Test chat with Bearer token:**
```bash
# Replace with your actual Laravel token
TOKEN="11836|UAc9YiEKc9zO9MvNHKQqY9WwdkxW7qQyw3mqyNK5"

curl -X POST http://localhost:8002/chat \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"message": "What can I do?"}'
```

**Test conversation memory:**
```bash
# First message
curl -X POST http://localhost:8002/chat \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"message": "My name is John"}'

# Second message (should remember)
curl -X POST http://localhost:8002/chat \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"message": "What is my name?"}'
```

**Expected:** AI should respond "Your name is John" āœ…

**Check cache stats:**
```bash
# User cache (Bearer tokens)
curl http://localhost:8002/cache/stats

# Redis conversation keys
redis-cli keys "conversation:*"
```

**See `BEARER_TOKEN_AUTH.md` for complete API documentation.**

## šŸ“ Project Structure

```
Updation_MCP_Local/
ā”œā”€ā”€ src/
│   ā”œā”€ā”€ config/              # Configuration management
│   │   ā”œā”€ā”€ __init__.py
│   │   └── settings.py      # Pydantic settings with validation
│   │
│   ā”œā”€ā”€ core/                # Core shared utilities
│   │   ā”œā”€ā”€ __init__.py
│   │   ā”œā”€ā”€ envelope.py      # Standard response envelope
│   │   ā”œā”€ā”€ exceptions.py    # Custom exceptions
│   │   └── security.py      # RBAC and auth helpers
│   │
│   ā”œā”€ā”€ llm/                 # LLM abstraction layer
│   │   ā”œā”€ā”€ __init__.py
│   │   ā”œā”€ā”€ base.py          # Abstract base provider
│   │   ā”œā”€ā”€ openai.py        # OpenAI implementation
│   │   ā”œā”€ā”€ anthropic.py     # Claude implementation
│   │   ā”œā”€ā”€ google.py        # Gemini implementation
│   │   └── factory.py       # Provider factory
│   │
│   ā”œā”€ā”€ mcp_server/          # MCP server implementation
│   │   ā”œā”€ā”€ __init__.py
│   │   ā”œā”€ā”€ server.py        # Main MCP server
│   │   └── tools/           # Tool modules
│   │       ā”œā”€ā”€ __init__.py  # Auto-discovery
│   │       ā”œā”€ā”€ users/       # User-related tools
│   │       ā”œā”€ā”€ organizations/ # Org-related tools
│   │       └── payments/    # Payment tools
│   │
│   ā”œā”€ā”€ orchestrator/        # LLM orchestration
│   │   ā”œā”€ā”€ __init__.py
│   │   ā”œā”€ā”€ client.py        # MCP client wrapper
│   │   ā”œā”€ā”€ processor.py     # Query processing logic
│   │   └── policy.py        # RBAC policies
│   │
│   ā”œā”€ā”€ web_chat/            # FastAPI web interface
│   │   ā”œā”€ā”€ __init__.py
│   │   ā”œā”€ā”€ main.py          # FastAPI app
│   │   ā”œā”€ā”€ routes/          # API routes
│   │   ā”œā”€ā”€ middleware/      # Custom middleware
│   │   └── dependencies.py  # FastAPI dependencies
│   │
│   ā”œā”€ā”€ observability/       # Logging, metrics, tracing
│   │   ā”œā”€ā”€ __init__.py
│   │   ā”œā”€ā”€ logging.py       # Structured logging setup
│   │   ā”œā”€ā”€ metrics.py       # Prometheus metrics
│   │   └── tracing.py       # Distributed tracing
│   │
│   └── storage/             # State management
│       ā”œā”€ā”€ __init__.py
│       ā”œā”€ā”€ redis_client.py  # Redis wrapper
│       └── memory.py        # In-memory fallback
│
ā”œā”€ā”€ tests/                   # Test suite
│   ā”œā”€ā”€ unit/
│   ā”œā”€ā”€ integration/
│   └── e2e/
│
ā”œā”€ā”€ scripts/                 # Utility scripts
│   ā”œā”€ā”€ setup_redis.sh
│   └── health_check.sh
│
ā”œā”€ā”€ .env.example            # Environment template
ā”œā”€ā”€ .gitignore
ā”œā”€ā”€ pyproject.toml          # Dependencies
ā”œā”€ā”€ README.md
└── docker-compose.yml      # Local development stack
```

## šŸ”§ Configuration

All configuration is managed through environment variables (see `.env.example`).

### Switching LLM Providers

Simply change the `LLM_PROVIDER` environment variable:

```bash
# Use OpenAI
LLM_PROVIDER=openai
OPENAI_API_KEY=sk-...

# Use Claude
LLM_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...

# Use Gemini
LLM_PROVIDER=google
GOOGLE_API_KEY=...
```

No code changes required! The system automatically routes to the correct provider.

## šŸ› ļø Development

### Running Tests

```bash
# Install dev dependencies
pip install -e ".[dev]"

# Run all tests
pytest

# Run with coverage
pytest --cov=src --cov-report=html

# Run specific test file
pytest tests/unit/test_llm_providers.py
```

### Code Quality

```bash
# Format code
ruff format .

# Lint
ruff check .

# Type checking
mypy src/
```

## šŸ“Š Monitoring

### Metrics

Prometheus metrics available at `http://localhost:9090/metrics`:

- `mcp_requests_total` - Total requests by tool and status
- `mcp_request_duration_seconds` - Request latency histogram
- `mcp_active_connections` - Current active connections
- `llm_api_calls_total` - LLM API calls by provider
- `llm_tokens_used_total` - Token usage tracking

### Logs

Structured JSON logs with trace IDs for correlation:

```json
{
  "timestamp": "2024-01-15T10:30:00Z",
  "level": "info",
  "event": "tool_executed",
  "tool_name": "get_user_subscriptions",
  "user_id": 123,
  "duration_ms": 245,
  "trace_id": "abc-123-def"
}
```

## šŸ”’ Security

- **RBAC**: Role-based access control for all tools
- **Rate Limiting**: Per-user and global rate limits
- **Input Validation**: Pydantic schemas for all inputs
- **Secret Management**: Never log or expose API keys
- **CORS**: Configurable allowed origins
- **HTTPS**: Enforce HTTPS in production

## 🚢 Deployment

### Docker

```bash
docker build -t updation-mcp:latest .
docker run -p 8050:8050 -p 8002:8002 --env-file .env updation-mcp:latest
```

### Docker Compose

```bash
docker-compose up -d
```

## šŸ“ Adding New Tools

1. Create tool module in `src/mcp_server/tools/your_domain/`
2. Implement `tool.py` with `register(mcp)` function
3. Add schemas in `schemas.py`
4. Add business logic in `service.py`
5. Auto-discovery handles the rest!

Example:
```python
# src/mcp_server/tools/your_domain/tool.py
from mcp.server.fastmcp import FastMCP

def register(mcp: FastMCP) -> None:
    @mcp.tool()
    async def your_tool(param: str):
        \"\"\"Tool description for LLM.\"\"\"
        return {"result": "data"}
```

## šŸ¤ Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes with tests
4. Run quality checks: `ruff check . && pytest`
5. Submit a pull request

## šŸ“„ License

[Your License Here]

## šŸ†˜ Support

For issues or questions:
- GitHub Issues: [Your Repo]
- Email: [Your Email]
- Docs: [Your Docs URL]

Maintenance

ActivityInactive
ResponsivenessNo issues