@hechtcarmel/vertica-mcp
Version:
MCP (Model Context Protocol) server for readonly Vertica database operations
644 lines (495 loc) ⢠19 kB
Markdown
# Vertica MCP Server
A Model Context Protocol (MCP) server for readonly communication with Vertica databases. This server enables AI assistants like Claude to interact with Vertica databases safely through a comprehensive set of readonly operations.
## Features
- š **Readonly Operations Only** - Ensures database safety with SELECT, SHOW, DESCRIBE, EXPLAIN, and WITH queries only
- šļø **Comprehensive Schema Discovery** - List tables, views, and indexes with detailed metadata
- š **Table Structure Analysis** - Get detailed column information, data types, and constraints
- š **Query Execution** - Execute custom SQL queries with parameter support
- š **Streaming Support** - Handle large result sets efficiently with batch streaming
- ā” **High Performance** - Connection pooling and query optimization for Vertica
- š”ļø **Type Safety** - Full TypeScript implementation with comprehensive error handling
- š **MCP Standard Compliance** - Built with official `@modelcontextprotocol/sdk` following MCP best practices
## Prerequisites
- Node.js 18.x or higher
- pnpm package manager
- Access to a Vertica database
- Environment variables for database connection
## Installation
### From npm (Recommended)
The easiest way to use this MCP server is via npm:
```bash
# Run directly with npx (no installation required)
npx @hechtcarmel/vertica-mcp
# Run with custom environment file
npx @hechtcarmel/vertica-mcp --env-file /path/to/your/.env
# Or install globally
npm install -g @hechtcarmel/vertica-mcp
vertica-mcp --env-file /path/to/your/.env
```
### From Source
1. Clone the repository:
```bash
git clone <repository-url>
cd vertica-mcp
```
2. Install dependencies:
```bash
pnpm install
```
3. Build the project:
```bash
pnpm run build
```
### Environment Configuration
Create a `.env` file in the project root with your Vertica connection details:
```env
# Required: Vertica Database Connection
VERTICA_HOST=localhost
VERTICA_PORT=5433
VERTICA_DATABASE=VMart
VERTICA_USER=dbadmin
VERTICA_PASSWORD=your_password
# Optional: Connection Pool Settings
VERTICA_CONNECTION_LIMIT=10
VERTICA_QUERY_TIMEOUT=30000
# Optional: SSL Settings
VERTICA_SSL=false
VERTICA_SSL_REJECT_UNAUTHORIZED=true
# Optional: Default Schema
VERTICA_DEFAULT_SCHEMA=public
```
## Usage
### Running the Server
```bash
# Start the MCP server (uses .env in current directory)
pnpm start
# Start with custom environment file
node dist/index.js --env-file /path/to/custom.env
# Or for development with auto-rebuild
pnpm run dev
# Show help and available options
npx @hechtcarmel/vertica-mcp --help
# Show version
npx @hechtcarmel/vertica-mcp --version
```
### Claude Desktop Configuration
Add the following to your Claude Desktop configuration file:
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows**: `%APPDATA%/Claude/claude_desktop_config.json`
#### Option 1: Using npx with custom .env file (Recommended)
```json
{
"mcpServers": {
"vertica-mcp": {
"command": "npx",
"args": ["@hechtcarmel/vertica-mcp", "--env-file", "/absolute/path/to/your/.env"]
}
}
}
```
#### Option 2: Using npx with .env file in working directory
```json
{
"mcpServers": {
"vertica-mcp": {
"command": "npx",
"args": ["@hechtcarmel/vertica-mcp"],
"cwd": "/path/to/your/env/file/directory"
}
}
}
```
Then create a `.env` file in the specified directory:
```env
# Required: Vertica Database Connection
VERTICA_HOST=localhost
VERTICA_PORT=5433
VERTICA_DATABASE=VMart
VERTICA_USER=dbadmin
VERTICA_PASSWORD=your_password
# Optional: Connection Pool Settings
VERTICA_CONNECTION_LIMIT=10
VERTICA_QUERY_TIMEOUT=30000
# Optional: SSL Settings
VERTICA_SSL=false
VERTICA_SSL_REJECT_UNAUTHORIZED=true
# Optional: Default Schema
VERTICA_DEFAULT_SCHEMA=public
```
#### Option 3: Using npx with inline environment variables
```json
{
"mcpServers": {
"vertica-mcp": {
"command": "npx",
"args": ["@hechtcarmel/vertica-mcp"],
"env": {
"VERTICA_HOST": "localhost",
"VERTICA_PORT": "5433",
"VERTICA_DATABASE": "VMart",
"VERTICA_USER": "dbadmin",
"VERTICA_PASSWORD": "your_password"
}
}
}
}
```
#### Option 4: From source (development)
```json
{
"mcpServers": {
"vertica-mcp": {
"command": "node",
"args": ["/absolute/path/to/vertica-mcp/dist/index.js", "--env-file", "/path/to/.env"],
"env": {
"VERTICA_HOST": "localhost",
"VERTICA_PORT": "5433",
"VERTICA_DATABASE": "VMart",
"VERTICA_USER": "dbadmin",
"VERTICA_PASSWORD": "your_password"
}
}
}
}
```
### Using with Cursor
#### Option 1: Using npx with custom .env file (Recommended)
1. Create a `.env` file anywhere on your system (e.g., `~/.config/vertica/production.env`)
2. Add your Vertica connection details to the `.env` file
3. In Cursor settings, add a new MCP server:
- **Name**: `vertica-mcp`
- **Command**: `npx`
- **Arguments**: `["@hechtcarmel/vertica-mcp", "--env-file", "/absolute/path/to/your/.env"]`
#### Option 1b: Using npx with .env file in working directory
1. Create a `.env` file in a directory (e.g., `~/.cursor/vertica.env`)
2. Add your Vertica connection details to the `.env` file
3. In Cursor settings, add a new MCP server:
- **Name**: `vertica-mcp`
- **Command**: `npx`
- **Arguments**: `["@hechtcarmel/vertica-mcp"]`
- **Working Directory**: Path to directory containing your `.env` file
#### Option 2: Using npx with inline environment variables
1. Open Cursor settings
2. Navigate to Features ā MCP Servers
3. Add a new server with:
- **Name**: `vertica-mcp`
- **Command**: `npx`
- **Arguments**: `["@hechtcarmel/vertica-mcp"]`
- **Environment variables**: Add your database connection details
#### Option 3: From source (development)
1. Open Cursor settings
2. Navigate to Features ā MCP Servers
3. Add a new server with:
- **Name**: `vertica-mcp`
- **Command**: `node`
- **Arguments**: `["/path/to/vertica-mcp/dist/index.js", "--env-file", "/path/to/.env"]`
- **Environment variables**: Add your database connection details (optional if using --env-file)
## Available Tools
### 1. execute_query
Execute readonly SQL queries against the Vertica database.
**Parameters:**
- `sql` (string, required): SQL query to execute
- `params` (array, optional): Parameters for parameterized queries
**Example:**
```sql
SELECT customer_key, customer_name, customer_state
FROM public.customer_dimension
WHERE customer_state = ?
LIMIT 10
```
### 2. stream_query
Stream large query results in manageable batches.
**Parameters:**
- `sql` (string, required): SQL query to execute
- `batchSize` (number, optional): Rows per batch (default: 1000, max: 10000)
- `maxRows` (number, optional): Maximum total rows to fetch
**Example:**
```sql
SELECT * FROM public.store_sales_fact ORDER BY sale_date_key
```
### 3. get_table_structure
Get detailed structure information for a specific table.
**Parameters:**
- `tableName` (string, required): Name of the table to analyze
- `schemaName` (string, optional): Schema name (defaults to configured schema)
**Example:**
```json
{
"tableName": "customer_dimension",
"schemaName": "public"
}
```
### 4. list_tables
List all tables in a schema with metadata.
**Parameters:**
- `schemaName` (string, optional): Schema name (defaults to configured schema)
### 5. list_views
List all views in a schema with their definitions.
**Parameters:**
- `schemaName` (string, optional): Schema name (defaults to configured schema)
### 6. list_indexes
List indexes (projections) for a specific table.
**Parameters:**
- `tableName` (string, required): Name of the table
- `schemaName` (string, optional): Schema name (defaults to configured schema)
**Note:** In Vertica, indexes are implemented as projections, which provide similar functionality for query optimization.
## Vertica-Specific Features
### Projections as Indexes
Vertica uses projections instead of traditional indexes. The `list_indexes` tool provides information about projections that serve similar purposes to indexes in other databases.
### System Catalogs
The server leverages Vertica's system catalogs (`v_catalog.*`) for metadata discovery:
- `v_catalog.tables` - Table information
- `v_catalog.columns` - Column details
- `v_catalog.views` - View definitions
- `v_catalog.projections` - Projection information
### Query Optimization
- Uses connection pooling for efficient resource management
- Implements query timeouts to prevent long-running operations
- Supports batch processing for large result sets
- Leverages Vertica's columnar storage advantages
## Security & Safety
### Readonly Enforcement
The server enforces readonly operations by validating that all queries start with approved keywords:
- `SELECT` - Data retrieval
- `SHOW` - Metadata display
- `DESCRIBE` - Structure information
- `EXPLAIN` - Query plan analysis
- `WITH` - Common table expressions
### Input Validation
- All inputs are validated using Zod schemas
- SQL injection protection through parameterized queries
- Connection limits and timeouts prevent resource exhaustion
- Comprehensive error handling with detailed logging
### Connection Security
- Supports SSL/TLS connections to Vertica
- Connection pooling with configurable limits
- Automatic connection cleanup and timeout handling
- Password masking in logs for security
## Development
### Project Structure
```
vertica-mcp/
āāā src/
ā āāā base/ # Base classes and abstractions
ā āāā config/ # Configuration management
ā āāā constants/ # Application constants
ā āāā services/ # Database service layer
ā āāā tools/ # MCP tool implementations
ā āāā types/ # TypeScript type definitions
ā āāā utils/ # Utility functions and helpers
ā āāā index.ts # Main server entry point
āāā dist/ # Compiled output
āāā package.json # Dependencies and scripts
āāā tsconfig.json # TypeScript configuration
āāā README.md # This file
```
### Code Architecture
This project follows modern TypeScript best practices and clean architecture principles:
#### **Official MCP SDK Integration**
- All tools implement the `MCPTool` interface using the official `@modelcontextprotocol/sdk`
- Uses standard JSON Schema format for tool input validation
- Implements proper MCP protocol message handling and tool registration
- Full compatibility with npx execution and all MCP clients including Claude Desktop
#### **Utility Modules**
- `response-formatter.ts`: Standardized API response formatting
- `table-helpers.ts`: Reusable table and schema operations
- Constants are centralized to eliminate magic numbers/strings
#### **Error Handling**
- Structured error types with detailed context
- Consistent error responses across all tools
- Proper TypeScript error typing
- Graceful service cleanup in finally blocks
#### **Code Quality Features**
- **MCP Compliance**: Full adherence to official MCP SDK patterns and protocol specification
- **Type Safety**: Comprehensive TypeScript types with Zod schema validation
- **Separation of Concerns**: Clean architecture with tools, services, utilities, and configuration layers
- **Input Validation**: Robust validation using Zod schemas for all tool inputs
- **Resource Management**: Automatic cleanup of database connections and proper error handling
### Building
```bash
# Clean and build
pnpm run clean
pnpm run build
# Type checking only
pnpm run typecheck
# Development with watch mode
pnpm run dev
# Check code quality (typecheck + build)
pnpm run check
# Test connection with local settings
pnpm run test:connection
```
### Testing
Test the server locally:
```bash
# Build and start
pnpm run build
pnpm start
# Test with environment variables
VERTICA_HOST=testhost pnpm start
```
## Troubleshooting
### Common Issues
```bash
# Update to latest version
npx @hechtcarmel/vertica-mcp@latest
# Or check your current version
npx @hechtcarmel/vertica-mcp --version
```
If you're still having issues:
1. Clear npm cache: `npm cache clean --force`
2. Try running with explicit version: `npx @hechtcarmel/vertica-mcp@1.0.9`
#### "Client is not a constructor" Error
**Problem:** Getting error `"Failed to connect to Vertica: Client is not a constructor"`
**Solution:** This was a known issue with the Vertica Node.js client import. It has been fixed in this version. If you still encounter this error:
1. Ensure you're using the latest version of this MCP server
2. Verify your Node.js version is 18.x or higher
3. Try rebuilding the project:
```bash
pnpm run clean
pnpm run build
```
#### Connection Issues
1. **Verify database connectivity:**
```bash
# Test connection manually
vsql -h localhost -p 5433 -d VMart -U dbadmin
```
2. **Verify MCP server builds correctly:**
```bash
pnpm run build
pnpm start
```
3. **Check environment variables:**
- Ensure all required variables are set
- Verify credentials are correct
- Check network connectivity to Vertica host
4. **SSL Configuration:**
- If using SSL, ensure certificates are properly configured
- Try disabling SSL for testing: `VERTICA_SSL=false`
### Query Execution Issues
1. **Permission Errors:**
- Ensure the database user has SELECT permissions on target schemas
- Check that the user can access system catalogs (`v_catalog.*`)
2. **Query Timeouts:**
- Increase `VERTICA_QUERY_TIMEOUT` for complex queries
- Use `stream_query` for large result sets
3. **Schema Access:**
- Verify schema names are correct (case-sensitive)
- Check that tables exist in the specified schema
### Performance Optimization
1. **Connection Pooling:**
- Adjust `VERTICA_CONNECTION_LIMIT` based on workload
- Monitor connection usage in Vertica system tables
2. **Query Performance:**
- Use appropriate WHERE clauses to limit result sets
- Leverage Vertica's columnar storage with projection-aware queries
- Use `EXPLAIN` to analyze query plans
3. **Batch Size Tuning:**
- Adjust `batchSize` in `stream_query` based on memory constraints
- Monitor network latency and adjust accordingly
## Contributing
1. Fork the repository
2. Create a feature branch: `git checkout -b feature/new-feature`
3. Make your changes following the existing code style and architecture
4. Run code quality checks: `pnpm run check`
5. Test thoroughly with a real Vertica database
6. Submit a pull request with a clear description
### Development Guidelines
When contributing to this project, please follow these guidelines:
- **Follow MCP patterns**: All new tools should extend `MCPTool<InputType>` and use proper schema format
- **Use proper schemas**: Define schemas with `type` and `description` properties as per mcp-framework
- **Add constants**: Put magic numbers/strings in `src/constants/index.ts`
- **Create utilities**: Extract reusable logic into `src/utils/` modules
- **Type everything**: Use TypeScript types extensively, define proper input interfaces
- **Validate inputs**: Use the validation utilities in `table-helpers.ts`
- **Handle errors properly**: Use structured error types and proper cleanup in finally blocks
- **Test with npx**: Always test tools work correctly when run via `npx` before publishing
## Changelog
### v1.1.0 (Latest)
- **š Major**: Migrated to official MCP SDK (`@modelcontextprotocol/sdk`) for improved compatibility
- **š§ Enhanced**: All tools now use proper JSON Schema validation with Zod
- **š¦ Improved**: Better error handling and type safety throughout the codebase
- **šļø Architecture**: Maintained clean separation of concerns while adopting official SDK patterns
- **ā” Performance**: Improved protocol compliance and message handling
- **š Future-proof**: Now uses the official SDK ensuring long-term compatibility and support
### v1.0.9
- **š§ Fixed**: MCP framework compatibility issues that prevented tools from loading
- **š§ Fixed**: NPX execution now works correctly with all MCP clients
- **š§ Fixed**: Tool discovery and registration following proper mcp-framework patterns
- **š§ Fixed**: Schema format updated to use correct `type` and `description` properties
- **ā»ļø Refactored**: Removed custom BaseTool class in favor of standard MCPTool implementation
- **š¦ Improved**: Better error handling with proper service cleanup
- **š Updated**: Documentation to reflect new architecture and troubleshooting steps
### v1.0.0
- **š Initial**: First release with basic Vertica MCP server functionality
- **ā ļø Known Issue**: Tools not loading correctly with npx (fixed in v1.0.9)
## License
MIT License - see LICENSE file for details.
## Support
For issues and questions:
1. Check the troubleshooting section above
2. Review Vertica documentation for database-specific issues
3. Open an issue on the project repository with detailed information
## Quick Start Examples
### Example 1: Cursor with custom .env file (Recommended)
1. Create `~/.config/vertica/production.env`:
```env
VERTICA_HOST=your-vertica-host.com
VERTICA_PORT=5433
VERTICA_DATABASE=your_database
VERTICA_USER=your_username
VERTICA_PASSWORD=your_password
VERTICA_DEFAULT_SCHEMA=public
```
2. Edit `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"vertica-mcp": {
"command": "npx",
"args": ["@hechtcarmel/vertica-mcp", "--env-file", "/Users/yourusername/.config/vertica/production.env"]
}
}
}
```
### Example 2: Claude Desktop with custom .env file
1. Create `~/.config/claude/vertica.env`:
```env
VERTICA_HOST=your-vertica-host.com
VERTICA_PORT=5433
VERTICA_DATABASE=your_database
VERTICA_USER=your_username
VERTICA_PASSWORD=your_password
VERTICA_DEFAULT_SCHEMA=public
```
2. Edit `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"vertica-mcp": {
"command": "npx",
"args": ["@hechtcarmel/vertica-mcp", "--env-file", "/Users/yourusername/.config/claude/vertica.env"]
}
}
}
```
### Example 3: Direct usage
```bash
# Using custom env file
npx @hechtcarmel/vertica-mcp --env-file /path/to/your/.env
# Using environment variables
export VERTICA_HOST=your-host.com
export VERTICA_PORT=5433
export VERTICA_DATABASE=your_db
export VERTICA_USER=your_user
export VERTICA_PASSWORD=your_password
# Run the MCP server (latest version)
npx @hechtcarmel/vertica-mcp@latest
# Or specify exact version with custom env file
npx @hechtcarmel/vertica-mcp@1.0.9 --env-file /path/to/production.env
# Show help
npx @hechtcarmel/vertica-mcp --help
```
---
**Note:** This server provides readonly access only. It cannot modify data, structure, or permissions in your Vertica database, ensuring safety for production environments.