Skip to content

Enterprise upgrades: async operations, multi-client support, and documentation reorganization #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"permissions": {
"allow": [
"Bash(grep:*)",
"Bash(python:*)",
"Bash(find:*)",
"Bash(uv pip install:*)",
"Bash(ruff check:*)",
"Bash(uv run ruff:*)",
"Bash(uv run:*)",
"Bash(uv add:*)",
"Bash(mkdir:*)",
"Bash(chmod:*)",
"Bash(timeout:*)",
"Bash(git add:*)",
"Bash(git commit:*)",
"Bash(git push:*)",
"Bash(git checkout:*)"
],
"deny": []
}
}
16 changes: 15 additions & 1 deletion .env.browser.example
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ SNOWFLAKE_ROLE=your_role
# Note: No private key path is needed for external browser authentication
# A browser window will open automatically for login when you start the server

# Connection Pooling Settings
# Connection Pooling Settings (Legacy - for compatibility)
# Time interval in hours between automatic connection refreshes (default: 8)
SNOWFLAKE_CONN_REFRESH_HOURS=8

# Async Connection Pool Configuration (Phase 1 - New)
# Minimum number of connections to maintain in the pool
SNOWFLAKE_POOL_MIN_SIZE=2
# Maximum number of connections in the pool
SNOWFLAKE_POOL_MAX_SIZE=10
# Minutes of inactivity before a connection is retired
SNOWFLAKE_POOL_MAX_INACTIVE_MINUTES=30
# Minutes between health check cycles
SNOWFLAKE_POOL_HEALTH_CHECK_MINUTES=5
# Connection timeout in seconds
SNOWFLAKE_POOL_CONNECTION_TIMEOUT=30.0
# Number of retry attempts for failed connections
SNOWFLAKE_POOL_RETRY_ATTEMPTS=3
176 changes: 176 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
# Snowflake MCP Server Environment Configuration
# Copy this file to .env and fill in your actual values

# ============================================================================
# Snowflake Connection Configuration
# ============================================================================

# Snowflake account identifier (required)
# Format: account-identifier.snowflakecomputing.com
SNOWFLAKE_ACCOUNT=your-account.snowflakecomputing.com

# Snowflake username (required)
SNOWFLAKE_USER=your-username

# ============================================================================
# Authentication Method 1: Private Key Authentication (Recommended for production)
# ============================================================================

# Path to your private key file (PEM format)
SNOWFLAKE_PRIVATE_KEY_PATH=/path/to/your/private_key.pem

# Private key passphrase (if your key is encrypted)
SNOWFLAKE_PRIVATE_KEY_PASSPHRASE=your-passphrase

# Alternatively, provide the private key content directly (base64 encoded)
# SNOWFLAKE_PRIVATE_KEY=LS0tLS1CRUdJTi...

# ============================================================================
# Authentication Method 2: External Browser Authentication (Development/Interactive)
# ============================================================================

# Enable external browser authentication (true/false)
# SNOWFLAKE_AUTH_TYPE=external_browser

# ============================================================================
# Connection Pool Configuration
# ============================================================================

# Connection refresh interval in hours (default: 8)
SNOWFLAKE_CONN_REFRESH_HOURS=8

# Minimum pool size (default: 2)
SNOWFLAKE_POOL_MIN_SIZE=2

# Maximum pool size (default: 10)
SNOWFLAKE_POOL_MAX_SIZE=10

# Connection timeout in seconds (default: 30)
SNOWFLAKE_CONN_TIMEOUT=30

# Health check interval in minutes (default: 5)
SNOWFLAKE_HEALTH_CHECK_INTERVAL=5

# Maximum inactive connection time in minutes (default: 30)
SNOWFLAKE_MAX_INACTIVE_TIME=30

# ============================================================================
# HTTP Server Configuration
# ============================================================================

# HTTP server host (default: 0.0.0.0)
MCP_HTTP_HOST=0.0.0.0

# HTTP server port (default: 8000)
MCP_HTTP_PORT=8000

# CORS allowed origins (comma-separated, default: *)
MCP_CORS_ORIGINS=*

# Maximum request size in MB (default: 10)
MCP_MAX_REQUEST_SIZE=10

# Request timeout in seconds (default: 300)
MCP_REQUEST_TIMEOUT=300

# ============================================================================
# Logging Configuration
# ============================================================================

# Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
LOG_LEVEL=INFO

# Log format (json, text)
LOG_FORMAT=text

# Enable structured logging with correlation IDs (true/false)
STRUCTURED_LOGGING=true

# Log file rotation size in MB (default: 100)
LOG_FILE_MAX_SIZE=100

# Number of log files to keep (default: 5)
LOG_FILE_BACKUP_COUNT=5

# ============================================================================
# Performance and Resource Configuration
# ============================================================================

# Maximum concurrent requests per client (default: 10)
MAX_CONCURRENT_REQUESTS=10

# Default query row limit (default: 100)
DEFAULT_QUERY_LIMIT=100

# Maximum query row limit (default: 10000)
MAX_QUERY_LIMIT=10000

# Enable query result caching (true/false)
ENABLE_QUERY_CACHE=false

# Query cache TTL in minutes (default: 5)
QUERY_CACHE_TTL=5

# ============================================================================
# Security Configuration
# ============================================================================

# Enable API key authentication (true/false)
ENABLE_API_AUTH=false

# API keys (comma-separated)
# API_KEYS=key1,key2,key3

# Enable SQL injection protection (true/false)
ENABLE_SQL_PROTECTION=true

# Enable request rate limiting (true/false)
ENABLE_RATE_LIMITING=false

# Rate limit: requests per minute per client (default: 60)
RATE_LIMIT_PER_MINUTE=60

# ============================================================================
# Monitoring and Health Checks
# ============================================================================

# Enable Prometheus metrics (true/false)
ENABLE_METRICS=false

# Metrics endpoint path (default: /metrics)
METRICS_ENDPOINT=/metrics

# Health check timeout in seconds (default: 10)
HEALTH_CHECK_TIMEOUT=10

# Enable detailed health checks (true/false)
DETAILED_HEALTH_CHECKS=true

# ============================================================================
# Development and Debug Configuration
# ============================================================================

# Enable debug mode (true/false)
DEBUG=false

# Enable SQL query logging (true/false)
LOG_SQL_QUERIES=false

# Enable performance profiling (true/false)
ENABLE_PROFILING=false

# Mock Snowflake responses for testing (true/false)
MOCK_SNOWFLAKE=false

# ============================================================================
# Environment-Specific Overrides
# ============================================================================

# Environment name (development, staging, production)
ENVIRONMENT=production

# Application version (auto-detected if not set)
# APP_VERSION=0.2.0

# Deployment timestamp (auto-set during deployment)
# DEPLOYMENT_TIMESTAMP=2024-01-16T10:30:00Z
16 changes: 15 additions & 1 deletion .env.private_key.example
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ SNOWFLAKE_ROLE=your_role
# Private Key Authentication Parameters
SNOWFLAKE_PRIVATE_KEY_PATH=/absolute/path/to/your/private_key.p8

# Connection Pooling Settings
# Connection Pooling Settings (Legacy - for compatibility)
# Time interval in hours between automatic connection refreshes (default: 8)
SNOWFLAKE_CONN_REFRESH_HOURS=8

# Async Connection Pool Configuration (Phase 1 - New)
# Minimum number of connections to maintain in the pool
SNOWFLAKE_POOL_MIN_SIZE=2
# Maximum number of connections in the pool
SNOWFLAKE_POOL_MAX_SIZE=10
# Minutes of inactivity before a connection is retired
SNOWFLAKE_POOL_MAX_INACTIVE_MINUTES=30
# Minutes between health check cycles
SNOWFLAKE_POOL_HEALTH_CHECK_MINUTES=5
# Connection timeout in seconds
SNOWFLAKE_POOL_CONNECTION_TIMEOUT=30.0
# Number of retry attempts for failed connections
SNOWFLAKE_POOL_RETRY_ATTEMPTS=3
34 changes: 33 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,36 @@ credentials/
dmypy.json

# Ruff
.ruff_cache/
.ruff_cache/

# Claude Code IDE
.claude/
CLAUDE.md

# Credentials and secrets
.credentials/
credentials/
*.credentials
.secret/
secrets/
*.secret

# Logs
logs/
*.log
log/

# Node.js (PM2)
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# PM2
.pm2/

# Runtime data
pids/
*.pid
*.seed
*.pid.lock
86 changes: 70 additions & 16 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,82 @@
# CLAUDE.md - MCP Server Snowflake (Python)
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview
This is a Model Context Protocol (MCP) server for Snowflake that enables Claude to perform read-only operations against Snowflake databases. The server is built with Python 3.12+ and uses stdio-based communication for integration with Claude Desktop.

## Build & Run Commands
- Setup: `uv pip install -e .` or `uv pip install -r requirements.txt`
- Start server: `python -m mcp_server_snowflake.main`
- Development mode: `uvicorn mcp_server_snowflake.main:app --reload`
- Setup: `uv pip install -e .`
- Start server: `uv run snowflake-mcp` or `uv run snowflake-mcp-stdio`
- Alternative: `python -m snowflake_mcp_server.main`

## Test Commands
- Run all tests: `pytest`
- Run single test: `pytest tests/test_file.py::test_function`
- Test coverage: `pytest --cov=mcp_server_snowflake`
- Test coverage: `pytest --cov=snowflake_mcp_server`

## Lint & Format
- Lint: `ruff check .`
- Format code: `ruff format .`
- Type check: `mypy mcp_server_snowflake/`
- Type check: `mypy snowflake_mcp_server/`

## Architecture Overview

### Core Components
- **snowflake_mcp_server/main.py**: Main MCP server implementation with tool handlers for database operations (list_databases, list_views, describe_view, query_view, execute_query)
- **snowflake_mcp_server/utils/snowflake_conn.py**: Connection management with singleton pattern, authentication handling, and background connection refresh
- **snowflake_mcp_server/utils/template.py**: Template utilities for SQL query formatting

### Authentication System
The server supports two authentication methods:
- **Private Key Auth**: Service account with RSA private key (non-interactive)
- **External Browser Auth**: Interactive browser-based authentication

Configuration is managed through environment variables loaded from `.env` files with examples provided for both auth types.

### Connection Management
Uses `SnowflakeConnectionManager` singleton for:
- Persistent connection pooling with configurable refresh intervals (default 8 hours)
- Background connection health monitoring and automatic reconnection
- Thread-safe connection access with proper locking
- Exponential backoff retry logic for connection failures

### Security Features
- Read-only operations enforced via SQL parsing with sqlglot
- Automatic LIMIT clause injection to prevent large result sets
- SQL injection prevention through parameterized queries
- Input validation using Pydantic models

### MCP Tools Available
- `list_databases`: List accessible Snowflake databases
- `list_views`: List views in specified database/schema
- `describe_view`: Get view structure and DDL definition
- `query_view`: Query view data with optional row limits
- `execute_query`: Execute custom read-only SQL with result formatting

## Configuration
- Environment variables in `.env` file for Snowflake credentials
- Connection refresh interval configurable via `SNOWFLAKE_CONN_REFRESH_HOURS`
- Default query limits: 10 rows for view queries, 100 rows for custom queries
- See `CONFIGURATION_GUIDE.md` for detailed configuration options

## Documentation Structure
- **Root Directory**: Setup, configuration, and migration guides
- `CONFIGURATION_GUIDE.md` - Complete server configuration reference
- `MIGRATION_GUIDE.md` - Migration instructions and compatibility notes
- `README.md` - Project overview and quick start
- **docs/**: Detailed documentation, operational guides, and development phases
- `OPERATIONS_RUNBOOK.md` - Production operations and troubleshooting
- `BACKUP_RECOVERY.md` - Backup and disaster recovery procedures
- `CAPACITY_PLANNING.md` - Scaling and capacity planning guide
- `SCALING_GUIDE.md` - Performance optimization and scaling strategies
- `PHASE2_COMPLETION_SUMMARY.md` - Enterprise upgrade completion summary
- `phase-breakdown/` - Detailed implementation phases and technical specifications

## Code Style Guidelines
- Use Python 3.10+ type annotations everywhere
- Format with Ruff, line length 88 characters
- Organize imports with Ruff (stdlib, third-party, first-party)
- Use async/await for Snowflake queries via snowflake-connector-python
- Prefer dataclasses or Pydantic models for structured data
- Follow PEP8 naming: snake_case for functions/variables, PascalCase for classes
- Document public functions with docstrings (Google style preferred)
- Handle database exceptions with proper logging and client-safe messages
- Parameterize all SQL queries to prevent injection vulnerabilities
- Use environment variables for configuration with pydantic-settings
- Python 3.12+ with full type annotations
- Ruff formatting with 88-character line length
- Async/await pattern for all database operations
- Pydantic models for configuration and data validation
- Google-style docstrings for public functions
- Exception handling with client-safe error messages
Loading