319 lines
8.5 KiB
Markdown
319 lines
8.5 KiB
Markdown
# PostgreSQL MCP Server Setup
|
|
|
|
This document describes the configuration and troubleshooting for the PostgreSQL MCP server integration with Claude Code.
|
|
|
|
## Status
|
|
|
|
✅ **WORKING** - Successfully configured and tested on 2026-01-22
|
|
|
|
- **Server Name**: `devdb`
|
|
- **Database**: `flyer_crawler_dev` (68 tables)
|
|
- **Connection**: Verified working
|
|
- **Tool Prefix**: `mcp__devdb__*`
|
|
- **Configuration**: Project-level `.mcp.json`
|
|
|
|
## Overview
|
|
|
|
The PostgreSQL MCP server (`@modelcontextprotocol/server-postgres`) provides database query capabilities directly from Claude Code, enabling:
|
|
|
|
- Running SQL queries against the development database
|
|
- Exploring database schema and tables
|
|
- Testing queries before implementation
|
|
- Debugging data issues
|
|
|
|
## Configuration
|
|
|
|
### Project-Level Configuration (Recommended)
|
|
|
|
The PostgreSQL MCP server is configured in the project-level `.mcp.json` file:
|
|
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"devdb": {
|
|
"command": "D:\\nodejs\\npx.cmd",
|
|
"args": [
|
|
"-y",
|
|
"@modelcontextprotocol/server-postgres",
|
|
"postgresql://postgres:postgres@127.0.0.1:5432/flyer_crawler_dev"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Key Configuration Details:**
|
|
|
|
| Parameter | Value | Notes |
|
|
| ----------- | --------------------------------------- | --------------------------------------- |
|
|
| Server Name | `devdb` | Distinct name to avoid collision issues |
|
|
| Package | `@modelcontextprotocol/server-postgres` | Official MCP PostgreSQL server |
|
|
| Host | `127.0.0.1` | Use IP address, not `localhost` |
|
|
| Port | `5432` | Default PostgreSQL port |
|
|
| Database | `flyer_crawler_dev` | Development database name |
|
|
| User | `postgres` | Default superuser for dev |
|
|
| Password | `postgres` | Default password for dev |
|
|
|
|
### Why Project-Level Configuration?
|
|
|
|
Based on troubleshooting experience with other MCP servers (documented in `BUGSINK-MCP-TROUBLESHOOTING.md`), **localhost MCP servers work more reliably in project-level `.mcp.json`** than in global `settings.json`.
|
|
|
|
Issues observed with global configuration:
|
|
|
|
- MCP servers silently not loading
|
|
- No error messages in logs
|
|
- Tools not appearing in available tool list
|
|
|
|
Project-level configuration bypasses these issues entirely.
|
|
|
|
### Connection String Format
|
|
|
|
```
|
|
postgresql://[user]:[password]@[host]:[port]/[database]
|
|
```
|
|
|
|
Examples:
|
|
|
|
```
|
|
# Development (local container)
|
|
postgresql://postgres:postgres@127.0.0.1:5432/flyer_crawler_dev
|
|
|
|
# Test database (if needed)
|
|
postgresql://flyer_crawler_test:password@127.0.0.1:5432/flyer_crawler_test
|
|
```
|
|
|
|
## Available Tools
|
|
|
|
Once configured, the following tools become available (prefix `mcp__devdb__`):
|
|
|
|
| Tool | Description |
|
|
| ------- | -------------------------------------- |
|
|
| `query` | Execute SQL queries and return results |
|
|
|
|
## Usage Examples
|
|
|
|
### Basic Query
|
|
|
|
```typescript
|
|
// List all tables
|
|
mcp__devdb__query("SELECT tablename FROM pg_tables WHERE schemaname = 'public'");
|
|
|
|
// Count records in a table
|
|
mcp__devdb__query('SELECT COUNT(*) FROM flyers');
|
|
|
|
// Check table structure
|
|
mcp__devdb__query(
|
|
"SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'flyers'",
|
|
);
|
|
```
|
|
|
|
### Debugging Data Issues
|
|
|
|
```typescript
|
|
// Find recent flyers
|
|
mcp__devdb__query('SELECT id, name, created_at FROM flyers ORDER BY created_at DESC LIMIT 10');
|
|
|
|
// Check job queue status
|
|
mcp__devdb__query('SELECT state, COUNT(*) FROM bullmq_jobs GROUP BY state');
|
|
|
|
// Verify user data
|
|
mcp__devdb__query("SELECT id, email, created_at FROM users WHERE email LIKE '%test%'");
|
|
```
|
|
|
|
## Prerequisites
|
|
|
|
### 1. PostgreSQL Container Running
|
|
|
|
The PostgreSQL container must be running and healthy:
|
|
|
|
```bash
|
|
# Check container status
|
|
podman ps | grep flyer-crawler-postgres
|
|
|
|
# Expected output shows "healthy" status
|
|
# flyer-crawler-postgres ... Up N hours (healthy) ...
|
|
```
|
|
|
|
### 2. Port Accessible from Host
|
|
|
|
PostgreSQL port 5432 must be mapped to the host:
|
|
|
|
```bash
|
|
# Verify port mapping
|
|
podman port flyer-crawler-postgres
|
|
# Expected: 5432/tcp -> 0.0.0.0:5432
|
|
```
|
|
|
|
### 3. Database Exists
|
|
|
|
Verify the database exists:
|
|
|
|
```bash
|
|
podman exec flyer-crawler-postgres psql -U postgres -c "\l" | grep flyer_crawler_dev
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Tools Not Available
|
|
|
|
**Symptoms:**
|
|
|
|
- `mcp__devdb__*` tools not in available tool list
|
|
- No error messages displayed
|
|
|
|
**Solutions:**
|
|
|
|
1. **Restart Claude Code** - MCP config changes require restart
|
|
2. **Check container status** - Ensure PostgreSQL container is running
|
|
3. **Verify port mapping** - Confirm port 5432 is accessible
|
|
4. **Test connection manually**:
|
|
```bash
|
|
podman exec flyer-crawler-postgres psql -U postgres -d flyer_crawler_dev -c "SELECT 1"
|
|
```
|
|
|
|
### Connection Refused
|
|
|
|
**Symptoms:**
|
|
|
|
- Connection error when using tools
|
|
- "Connection refused" in error message
|
|
|
|
**Solutions:**
|
|
|
|
1. **Check container health**:
|
|
|
|
```bash
|
|
podman ps | grep flyer-crawler-postgres
|
|
```
|
|
|
|
2. **Restart the container**:
|
|
|
|
```bash
|
|
podman restart flyer-crawler-postgres
|
|
```
|
|
|
|
3. **Check for port conflicts**:
|
|
```bash
|
|
netstat -an | findstr 5432
|
|
```
|
|
|
|
### Authentication Failed
|
|
|
|
**Symptoms:**
|
|
|
|
- "password authentication failed" error
|
|
|
|
**Solutions:**
|
|
|
|
1. **Verify credentials** in container environment:
|
|
|
|
```bash
|
|
podman exec flyer-crawler-dev env | grep DB_
|
|
```
|
|
|
|
2. **Check PostgreSQL users**:
|
|
|
|
```bash
|
|
podman exec flyer-crawler-postgres psql -U postgres -c "\du"
|
|
```
|
|
|
|
3. **Update connection string** in `.mcp.json` if credentials differ
|
|
|
|
### Database Does Not Exist
|
|
|
|
**Symptoms:**
|
|
|
|
- "database does not exist" error
|
|
|
|
**Solutions:**
|
|
|
|
1. **List available databases**:
|
|
|
|
```bash
|
|
podman exec flyer-crawler-postgres psql -U postgres -c "\l"
|
|
```
|
|
|
|
2. **Create database if missing**:
|
|
```bash
|
|
podman exec flyer-crawler-postgres createdb -U postgres flyer_crawler_dev
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
### Development Only
|
|
|
|
The default credentials (`postgres:postgres`) are for **development only**. Never use these in production.
|
|
|
|
### Connection String in Config
|
|
|
|
The connection string includes the password in plain text. This is acceptable for:
|
|
|
|
- Local development
|
|
- Container environments
|
|
|
|
For production MCP access (if ever needed):
|
|
|
|
- Use environment variables
|
|
- Consider connection pooling
|
|
- Implement proper access controls
|
|
|
|
### Query Permissions
|
|
|
|
The MCP server executes queries as the configured user (`postgres` in dev). Be aware that:
|
|
|
|
- `postgres` is a superuser with full access
|
|
- For restricted access, create a dedicated MCP user with limited permissions:
|
|
|
|
```sql
|
|
-- Example: Create read-only MCP user
|
|
CREATE USER mcp_reader WITH PASSWORD 'secure_password';
|
|
GRANT CONNECT ON DATABASE flyer_crawler_dev TO mcp_reader;
|
|
GRANT USAGE ON SCHEMA public TO mcp_reader;
|
|
GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_reader;
|
|
```
|
|
|
|
## Database Information
|
|
|
|
### Development Environment
|
|
|
|
| Property | Value |
|
|
| --------------------- | ------------------------- |
|
|
| Container | `flyer-crawler-postgres` |
|
|
| Image | `postgis/postgis:15-3.4` |
|
|
| Host (from Windows) | `127.0.0.1` / `localhost` |
|
|
| Host (from container) | `postgres` |
|
|
| Port | `5432` |
|
|
| Database | `flyer_crawler_dev` |
|
|
| User | `postgres` |
|
|
| Password | `postgres` |
|
|
|
|
### Schema Reference
|
|
|
|
The database uses PostGIS for geographic data. Key tables include:
|
|
|
|
- `users` - User accounts
|
|
- `stores` - Store definitions
|
|
- `store_locations` - Store geographic locations
|
|
- `flyers` - Uploaded flyer metadata
|
|
- `flyer_items` - Extracted deal items
|
|
- `watchlists` - User watchlists
|
|
- `shopping_lists` - User shopping lists
|
|
- `recipes` - Recipe definitions
|
|
|
|
For complete schema, see `sql/master_schema_rollup.sql`.
|
|
|
|
## Related Documentation
|
|
|
|
- [CLAUDE.md - MCP Servers Section](../CLAUDE.md#mcp-servers)
|
|
- [BUGSINK-MCP-TROUBLESHOOTING.md](./BUGSINK-MCP-TROUBLESHOOTING.md) - Similar MCP setup patterns
|
|
- [sql/master_schema_rollup.sql](../sql/master_schema_rollup.sql) - Database schema
|
|
|
|
## Changelog
|
|
|
|
### 2026-01-21
|
|
|
|
- Initial configuration added to project-level `.mcp.json`
|
|
- Server named `devdb` to avoid naming collisions
|
|
- Using `127.0.0.1` instead of `localhost` based on Bugsink MCP experience
|
|
- Documentation created
|