Files
flyer-crawler.projectium.com/docs/tools/MCP-CONFIGURATION.md
Torben Sorensen eae0dbaa8e
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 19m11s
bugsink mcp and claude subagents - documentation and test fixes
2026-01-22 11:23:45 -08:00

893 lines
24 KiB
Markdown

# MCP Configuration Guide
This document provides comprehensive guidance for configuring Model Context Protocol (MCP) servers with Claude Code for the Flyer Crawler project.
## Table of Contents
1. [What is MCP](#what-is-mcp)
2. [Server Overview](#server-overview)
3. [Configuration Locations](#configuration-locations)
4. [Global Settings Configuration](#global-settings-configuration)
5. [Project-Level Configuration](#project-level-configuration)
6. [Server Setup Instructions](#server-setup-instructions)
7. [Bugsink MCP](#bugsink-mcp)
8. [PostgreSQL MCP](#postgresql-mcp)
9. [Gitea MCP](#gitea-mcp)
10. [Other MCP Servers](#other-mcp-servers)
11. [Troubleshooting](#troubleshooting)
12. [Best Practices](#best-practices)
---
## What is MCP
Model Context Protocol (MCP) is a standardized protocol that allows AI assistants like Claude to interact with external tools and services. MCP servers expose capabilities (tools) that Claude can invoke to:
- Query databases
- Manage containers
- Access file systems
- Interact with APIs (Gitea, Bugsink, etc.)
- Store and retrieve knowledge graph data
- Inspect caches and key-value stores
**Why We Use MCP:**
| Benefit | Description |
| ------------------ | ------------------------------------------------------------------------ |
| Direct Integration | Claude can directly query databases, inspect containers, and access APIs |
| Context Awareness | Tools provide real-time information without manual copy-paste |
| Automation | Complex workflows can be executed through tool chains |
| Consistency | Standardized interface across different services |
---
## Server Overview
The Flyer Crawler project uses the following MCP servers:
| Server | Tool Prefix | Purpose | Config Location |
| ------------------ | -------------------------- | -------------------------------------------------- | --------------- |
| `gitea-projectium` | `mcp__gitea-projectium__*` | Gitea API at gitea.projectium.com | Global |
| `gitea-torbonium` | `mcp__gitea-torbonium__*` | Gitea API at gitea.torbonium.com | Global |
| `podman` | `mcp__podman__*` | Container management | Global |
| `filesystem` | `mcp__filesystem__*` | File system access | Global |
| `memory` | `mcp__memory__*` | Knowledge graph persistence | Global |
| `redis` | `mcp__redis__*` | Redis cache inspection | Global |
| `bugsink` | `mcp__bugsink__*` | Production error tracking (bugsink.projectium.com) | Global |
| `localerrors` | `mcp__localerrors__*` | Dev container error tracking (localhost:8000) | Project |
| `devdb` | `mcp__devdb__*` | Development PostgreSQL database | Project |
---
## Configuration Locations
Claude Code uses **two separate configuration systems** for MCP servers:
### Global Configuration
**Location (Windows):**
```text
C:\Users\<username>\.claude\settings.json
```
**Used For:**
- Production services (HTTPS endpoints)
- Servers shared across all projects
- Container management (Podman)
- Knowledge graph (Memory)
### Project-Level Configuration
**Location:**
```text
<project-root>/.mcp.json
```
**Used For:**
- Localhost services (HTTP endpoints)
- Development databases
- Project-specific tools
### When to Use Each
| Scenario | Configuration |
| --------------------------------- | ---------------------- |
| Production APIs (HTTPS) | Global `settings.json` |
| Shared tools (memory, filesystem) | Global `settings.json` |
| Localhost services (HTTP) | Project `.mcp.json` |
| Development databases | Project `.mcp.json` |
| Per-project customization | Project `.mcp.json` |
**Important:** Localhost MCP servers work more reliably in project-level `.mcp.json` than in global `settings.json`. See [Troubleshooting](#localhost-servers-not-loading) for details.
---
## Global Settings Configuration
### File Format
```json
{
"mcpServers": {
"server-name": {
"command": "path/to/executable",
"args": ["arg1", "arg2"],
"env": {
"ENV_VAR": "value"
},
"disabled": true
}
}
}
```
**Configuration Options:**
| Field | Required | Description |
| ---------- | -------- | ----------------------------------------- |
| `command` | Yes | Path to executable or command |
| `args` | No | Array of command-line arguments |
| `env` | No | Environment variables for the server |
| `disabled` | No | Set to `true` to disable without removing |
### Example Global Configuration
```json
{
"mcpServers": {
"memory": {
"command": "D:\\nodejs\\npx.cmd",
"args": ["-y", "@modelcontextprotocol/server-memory"]
},
"filesystem": {
"command": "d:\\nodejs\\node.exe",
"args": [
"c:\\Users\\<user>\\AppData\\Roaming\\npm\\node_modules\\@modelcontextprotocol\\server-filesystem\\dist\\index.js",
"d:\\gitea"
]
},
"podman": {
"command": "D:\\nodejs\\npx.cmd",
"args": ["-y", "podman-mcp-server@latest"],
"env": {
"DOCKER_HOST": "npipe:////./pipe/podman-machine-default"
}
},
"redis": {
"command": "D:\\nodejs\\npx.cmd",
"args": ["-y", "@modelcontextprotocol/server-redis", "redis://localhost:6379"]
},
"bugsink": {
"command": "d:\\nodejs\\node.exe",
"args": ["d:\\gitea\\bugsink-mcp\\dist\\index.js"],
"env": {
"BUGSINK_URL": "https://bugsink.projectium.com",
"BUGSINK_TOKEN": "<40-char-hex-token>"
}
},
"gitea-projectium": {
"command": "d:\\gitea-mcp\\gitea-mcp.exe",
"args": ["run", "-t", "stdio"],
"env": {
"GITEA_HOST": "https://gitea.projectium.com",
"GITEA_ACCESS_TOKEN": "<your-token>"
}
},
"gitea-torbonium": {
"command": "d:\\gitea-mcp\\gitea-mcp.exe",
"args": ["run", "-t", "stdio"],
"env": {
"GITEA_HOST": "https://gitea.torbonium.com",
"GITEA_ACCESS_TOKEN": "<your-token>"
}
}
}
}
```
---
## Project-Level Configuration
### File Location
Create `.mcp.json` in the project root:
```text
d:\gitea\flyer-crawler.projectium.com\flyer-crawler.projectium.com\.mcp.json
```
### File Format
```json
{
"mcpServers": {
"server-name": {
"command": "path/to/executable",
"args": ["arg1", "arg2"],
"env": {
"ENV_VAR": "value"
}
}
}
}
```
### Current Project Configuration
```json
{
"mcpServers": {
"localerrors": {
"command": "d:\\nodejs\\node.exe",
"args": ["d:\\gitea\\bugsink-mcp\\dist\\index.js"],
"env": {
"BUGSINK_URL": "http://127.0.0.1:8000",
"BUGSINK_TOKEN": "<40-char-hex-token>"
}
},
"devdb": {
"command": "D:\\nodejs\\npx.cmd",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://postgres:postgres@127.0.0.1:5432/flyer_crawler_dev"
]
}
}
}
```
---
## Server Setup Instructions
### Memory (Knowledge Graph)
**Package:** `@modelcontextprotocol/server-memory`
**Purpose:** Persists knowledge across sessions - project context, credentials, known issues.
**Configuration:**
```json
"memory": {
"command": "D:\\nodejs\\npx.cmd",
"args": ["-y", "@modelcontextprotocol/server-memory"]
}
```
**Key Tools:**
- `mcp__memory__read_graph` - Read entire knowledge graph
- `mcp__memory__search_nodes` - Search for specific entities
- `mcp__memory__create_entities` - Add new knowledge
### Filesystem
**Package:** `@modelcontextprotocol/server-filesystem`
**Purpose:** Provides file system access to specified directories.
**Configuration:**
```json
"filesystem": {
"command": "d:\\nodejs\\node.exe",
"args": [
"c:\\Users\\<user>\\AppData\\Roaming\\npm\\node_modules\\@modelcontextprotocol\\server-filesystem\\dist\\index.js",
"d:\\gitea"
]
}
```
**Note:** The last argument(s) specify allowed directories.
### Podman/Docker
**Package:** `podman-mcp-server`
**Purpose:** Container management - list, start, stop, inspect containers.
**Configuration:**
```json
"podman": {
"command": "D:\\nodejs\\npx.cmd",
"args": ["-y", "podman-mcp-server@latest"],
"env": {
"DOCKER_HOST": "npipe:////./pipe/podman-machine-default"
}
}
```
**Key Tools:**
- `mcp__podman__container_list` - List running containers
- `mcp__podman__container_logs` - View container logs
- `mcp__podman__container_inspect` - Detailed container info
- `mcp__podman__image_list` - List images
### Redis
**Package:** `@modelcontextprotocol/server-redis`
**Purpose:** Inspect Redis cache, set/get values, list keys.
**Configuration:**
```json
"redis": {
"command": "D:\\nodejs\\npx.cmd",
"args": ["-y", "@modelcontextprotocol/server-redis", "redis://localhost:6379"]
}
```
**Key Tools:**
- `mcp__redis__get` - Get value by key
- `mcp__redis__set` - Set key-value pair
- `mcp__redis__list` - List keys matching pattern
- `mcp__redis__delete` - Delete key(s)
---
## Bugsink MCP
Bugsink is a self-hosted error tracking service. We run two instances:
| Instance | URL | MCP Server | Purpose |
| ----------- | -------------------------------- | ------------- | ---------------------------- |
| Production | `https://bugsink.projectium.com` | `bugsink` | Production error tracking |
| Development | `http://localhost:8000` | `localerrors` | Dev container error tracking |
### Installation
The `bugsink-mcp` package is **NOT published to npm**. Clone and build from source:
```bash
# Clone the repository
git clone https://github.com/j-shelfwood/bugsink-mcp.git d:\gitea\bugsink-mcp
# Install and build
cd d:\gitea\bugsink-mcp
npm install
npm run build
```
**Repository:** https://github.com/j-shelfwood/bugsink-mcp
### Configuration
**Production (Global `settings.json`):**
```json
"bugsink": {
"command": "d:\\nodejs\\node.exe",
"args": ["d:\\gitea\\bugsink-mcp\\dist\\index.js"],
"env": {
"BUGSINK_URL": "https://bugsink.projectium.com",
"BUGSINK_TOKEN": "<40-char-hex-token>"
}
}
```
**Development (Project `.mcp.json`):**
```json
"localerrors": {
"command": "d:\\nodejs\\node.exe",
"args": ["d:\\gitea\\bugsink-mcp\\dist\\index.js"],
"env": {
"BUGSINK_URL": "http://127.0.0.1:8000",
"BUGSINK_TOKEN": "<40-char-hex-token>"
}
}
```
**Required Environment Variables:**
| Variable | Description |
| --------------- | -------------------------------------------- |
| `BUGSINK_URL` | Full URL to Bugsink instance (with protocol) |
| `BUGSINK_TOKEN` | 40-character hex API token |
**Important:**
- Variable is `BUGSINK_TOKEN`, NOT `BUGSINK_API_TOKEN`
- Do NOT use `npx` - the package is not on npm
- Use `http://127.0.0.1:8000` not `http://localhost:8000` for localhost
### Creating API Tokens
Bugsink 2.0.11 does NOT have a "Settings > API Keys" menu in the UI. Tokens must be created via Django management command.
**For Dev Container (localhost:8000):**
```bash
MSYS_NO_PATHCONV=1 podman exec \
-e DATABASE_URL=postgresql://bugsink:bugsink_dev_password@postgres:5432/bugsink \
-e SECRET_KEY=dev-bugsink-secret-key-minimum-50-characters-for-security \
flyer-crawler-dev sh -c 'cd /opt/bugsink/conf && \
DJANGO_SETTINGS_MODULE=bugsink_conf \
PYTHONPATH=/opt/bugsink/conf:/opt/bugsink/lib/python3.10/site-packages \
/opt/bugsink/bin/python -m django create_auth_token'
```
**For Production (via SSH):**
```bash
ssh root@projectium.com "cd /opt/bugsink && bugsink-manage create_auth_token"
```
Both commands output a 40-character lowercase hex token (e.g., `a609c2886daa4e1e05f1517074d7779a5fb49056`).
### Key Tools
- `mcp__bugsink__test_connection` / `mcp__localerrors__test_connection` - Verify connection
- `mcp__bugsink__list_projects` - List all projects
- `mcp__bugsink__list_issues` - List issues for a project
- `mcp__bugsink__get_issue` - Get issue details
- `mcp__bugsink__get_stacktrace` - Get event stacktrace as Markdown
### Testing Connection
```typescript
// Production
mcp__bugsink__test_connection();
// Expected: "Connection successful: Connected successfully. Found N project(s)."
// Development
mcp__localerrors__test_connection();
// Expected: "Connection successful: Connected successfully. Found N project(s)."
```
---
## PostgreSQL MCP
**Package:** `@modelcontextprotocol/server-postgres`
**Purpose:** Execute SQL queries against the development database.
### Configuration
Add to project-level `.mcp.json`:
```json
"devdb": {
"command": "D:\\nodejs\\npx.cmd",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://postgres:postgres@127.0.0.1:5432/flyer_crawler_dev"
]
}
```
### Connection String Format
```text
postgresql://[user]:[password]@[host]:[port]/[database]
```
**Examples:**
```text
# Development (local container)
postgresql://postgres:postgres@127.0.0.1:5432/flyer_crawler_dev
# Test database
postgresql://flyer_crawler_test:password@127.0.0.1:5432/flyer_crawler_test
```
### Database Information
| Property | Value |
| --------------------- | ------------------------ |
| Container | `flyer-crawler-postgres` |
| Image | `postgis/postgis:15-3.4` |
| Host (from Windows) | `127.0.0.1` |
| Host (from container) | `postgres` |
| Port | `5432` |
| Database | `flyer_crawler_dev` |
| User | `postgres` |
| Password | `postgres` |
### Usage Examples
```typescript
// List all tables
mcp__devdb__query({ sql: "SELECT tablename FROM pg_tables WHERE schemaname = 'public'" });
// Count records
mcp__devdb__query({ sql: 'SELECT COUNT(*) FROM flyers' });
// Check table structure
mcp__devdb__query({
sql: "SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'flyers'",
});
// Find recent records
mcp__devdb__query({
sql: 'SELECT id, name, created_at FROM flyers ORDER BY created_at DESC LIMIT 10',
});
```
### Prerequisites
1. **PostgreSQL container must be running:**
```bash
podman ps | grep flyer-crawler-postgres
```
2. **Port 5432 must be mapped:**
```bash
podman port flyer-crawler-postgres
# Expected: 5432/tcp -> 0.0.0.0:5432
```
3. **Database must exist:**
```bash
podman exec flyer-crawler-postgres psql -U postgres -c "\l" | grep flyer_crawler_dev
```
---
## Gitea MCP
**Binary:** `gitea-mcp` (compiled Go binary)
**Purpose:** Interact with Gitea repositories, issues, pull requests.
### Configuration
```json
"gitea-projectium": {
"command": "d:\\gitea-mcp\\gitea-mcp.exe",
"args": ["run", "-t", "stdio"],
"env": {
"GITEA_HOST": "https://gitea.projectium.com",
"GITEA_ACCESS_TOKEN": "<your-token>"
}
}
```
### Getting Access Token
1. Log in to Gitea web interface
2. Go to **Settings > Applications**
3. Under **Generate New Token**, enter a name
4. Select required scopes (typically `read:user`, `write:repository`, `write:issue`)
5. Click **Generate Token**
6. Copy the token immediately (shown only once)
### Key Tools
- `mcp__gitea-projectium__list_my_repos` - List accessible repositories
- `mcp__gitea-projectium__list_repo_issues` - List issues in a repo
- `mcp__gitea-projectium__get_issue_by_index` - Get issue details
- `mcp__gitea-projectium__create_issue` - Create new issue
- `mcp__gitea-projectium__create_pull_request` - Create PR
- `mcp__gitea-projectium__get_file_content` - Read file from repo
- `mcp__gitea-projectium__list_branches` - List branches
### Example Operations
```typescript
// List repositories
mcp__gitea - projectium__list_my_repos({ page: 1, pageSize: 20 });
// Get issue
mcp__gitea -
projectium__get_issue_by_index({
owner: 'username',
repo: 'repository-name',
index: 42,
});
// Create issue
mcp__gitea -
projectium__create_issue({
owner: 'username',
repo: 'repository-name',
title: 'Bug: Something is broken',
body: '## Description\n\nSteps to reproduce...',
});
```
---
## Other MCP Servers
### Sequential Thinking
**Package:** `@modelcontextprotocol/server-sequential-thinking`
**Purpose:** Structured step-by-step reasoning for complex problems.
```json
"sequential-thinking": {
"command": "D:\\nodejs\\npx.cmd",
"args": ["-y", "@modelcontextprotocol/server-sequential-thinking"]
}
```
### Playwright (Browser Automation)
**Package:** `@anthropics/mcp-server-playwright`
**Purpose:** Browser automation for testing and scraping.
```json
"playwright": {
"command": "D:\\nodejs\\npx.cmd",
"args": ["-y", "@anthropics/mcp-server-playwright"]
}
```
### Sentry (Cloud Error Tracking)
**Package:** `@sentry/mcp-server`
**Purpose:** Error tracking for Sentry instances (NOT Bugsink).
```json
"sentry": {
"command": "D:\\nodejs\\npx.cmd",
"args": ["-y", "@sentry/mcp-server"],
"env": {
"SENTRY_AUTH_TOKEN": "<your-sentry-token>"
}
}
```
**Note:** Bugsink has a different API than Sentry. Use `bugsink-mcp` for Bugsink instances.
---
## Troubleshooting
### Localhost Servers Not Loading
**Symptoms:**
- `mcp__localerrors__*` or `mcp__devdb__*` tools not available
- No error messages in logs
- Server silently skipped during startup
**Root Cause:**
Claude Code's global `settings.json` has issues loading localhost stdio MCP servers on Windows. The exact cause may be related to:
- Multiple servers using the same underlying package
- Localhost URL filtering
- Windows-specific MCP loader bugs
**Solution:**
Use **project-level `.mcp.json`** for all localhost MCP servers. This bypasses the global config loader entirely.
**Working Pattern:**
- Global `settings.json`: Production HTTPS servers
- Project `.mcp.json`: Localhost HTTP servers
### Server Name Collision
**Symptoms:**
- Second server with similar name never starts
- No error logged - server silently filtered out
**Root Cause:**
Claude Code may skip MCP servers when names share prefixes (e.g., `bugsink` and `bugsink-dev`).
**Solution:**
Use completely distinct names:
- `bugsink` for production
- `localerrors` for development (NOT `bugsink-dev` or `devbugsink`)
### Connection Timed Out
**Error:** `Connection timed out after 30000ms`
**Causes:**
- Server takes too long to start
- npx download is slow
- Server crashes during initialization
**Solutions:**
1. Move important servers earlier in config
2. Use pre-installed packages instead of npx:
```json
"command": "d:\\nodejs\\node.exe",
"args": ["path/to/installed/package/dist/index.js"]
```
3. Check server can start manually
### Environment Variable Issues
**Common Mistakes:**
| Wrong | Correct |
| ----------------------- | ----------------------- |
| `BUGSINK_API_TOKEN` | `BUGSINK_TOKEN` |
| `http://localhost:8000` | `http://127.0.0.1:8000` |
**Verification:**
Test server manually with environment variables:
```bash
cd d:\gitea\bugsink-mcp
set BUGSINK_URL=http://127.0.0.1:8000
set BUGSINK_TOKEN=<your-token>
node dist/index.js
```
Expected output:
```
Bugsink MCP server started
Connected to: http://127.0.0.1:8000
```
### PostgreSQL Connection Refused
**Solutions:**
1. Check container is running:
```bash
podman ps | grep flyer-crawler-postgres
```
2. Verify port mapping:
```bash
podman port flyer-crawler-postgres
```
3. Test connection:
```bash
podman exec flyer-crawler-postgres psql -U postgres -d flyer_crawler_dev -c "SELECT 1"
```
4. Check for port conflicts:
```bash
netstat -an | findstr 5432
```
### Verifying Configuration
**List loaded servers:**
```bash
claude mcp list
```
**Check debug logs (Windows):**
```text
C:\Users\<username>\.claude\debug\*.txt
```
Look for MCP server startup messages. Missing servers indicate configuration problems.
---
## Best Practices
### 1. Keep Configs Organized
- **Global config:** Shared/production servers
- **Project config:** Local development servers
- **Never duplicate** the same server in both
### 2. Order Servers by Importance
Place essential servers first in configuration:
1. `memory` - Knowledge persistence
2. `filesystem` - File access
3. `podman` - Container management
4. Other servers...
### 3. Use Direct Node Execution
For faster startup, avoid npx and use direct node execution:
```json
// Slow (npx downloads on each start)
"command": "D:\\nodejs\\npx.cmd",
"args": ["-y", "package-name"]
// Fast (pre-installed)
"command": "d:\\nodejs\\node.exe",
"args": ["path/to/installed/dist/index.js"]
```
### 4. Disable Instead of Delete
Use `"disabled": true` to troubleshoot without losing configuration:
```json
"problem-server": {
"command": "...",
"disabled": true
}
```
### 5. Test Manually First
Before adding to config, verify server works:
```bash
cd /path/to/mcp-server
set ENV_VAR=value
node dist/index.js
```
### 6. Store Secrets Securely
- Use the memory MCP to store API tokens for future sessions
- Never commit `.mcp.json` with real tokens (add to `.gitignore`)
- Use environment variables where possible
### 7. Restart After Changes
MCP configuration changes require a full VS Code restart (not just window reload).
---
## Quick Reference
### Available MCP Packages
| Server | Package/Source | npm? |
| ------------------- | -------------------------------------------------- | ---------------------- |
| memory | `@modelcontextprotocol/server-memory` | Yes |
| filesystem | `@modelcontextprotocol/server-filesystem` | Yes |
| redis | `@modelcontextprotocol/server-redis` | Yes |
| postgres | `@modelcontextprotocol/server-postgres` | Yes |
| sequential-thinking | `@modelcontextprotocol/server-sequential-thinking` | Yes |
| podman | `podman-mcp-server` | Yes |
| gitea | `gitea-mcp` (binary) | No |
| bugsink | `j-shelfwood/bugsink-mcp` | No (build from source) |
| sentry | `@sentry/mcp-server` | Yes |
| playwright | `@anthropics/mcp-server-playwright` | Yes |
### Common Tool Prefixes
| Server | Tool Prefix | Example |
| -------------- | ------------------------- | -------------------------------------- |
| Memory | `mcp__memory__` | `mcp__memory__read_graph` |
| Filesystem | `mcp__filesystem__` | `mcp__filesystem__read_file` |
| Podman | `mcp__podman__` | `mcp__podman__container_list` |
| Redis | `mcp__redis__` | `mcp__redis__get` |
| Bugsink (prod) | `mcp__bugsink__` | `mcp__bugsink__list_issues` |
| Bugsink (dev) | `mcp__localerrors__` | `mcp__localerrors__list_issues` |
| PostgreSQL | `mcp__devdb__` | `mcp__devdb__query` |
| Gitea | `mcp__gitea-projectium__` | `mcp__gitea-projectium__list_my_repos` |
---
## Related Documentation
- [CLAUDE.md - MCP Servers Section](../../CLAUDE.md#mcp-servers)
- [DEV-CONTAINER-BUGSINK.md](../DEV-CONTAINER-BUGSINK.md)
- [BUGSINK-SYNC.md](../BUGSINK-SYNC.md)
- [sql/master_schema_rollup.sql](../../sql/master_schema_rollup.sql)
---
_Last updated: January 2026_