This guide walks you through upgrading from ContextForge v0.6.0 to v0.7.0 that implements comprehensive multi-tenancy, team management, and RBAC.
Install to Claude Code
npx -y skills add tools-only/X-Skills --skill 2751-migration-070_0d56b710 --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of 2751 Migration 070 0d56b710?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/tools-only-2751-migration-070-0d56b710)More formats (shields.io, HTML) on the badges page.
# Migration Guide: Upgrading to Multi-Tenancy (v0.6.0 to v0.7.0)
This guide walks you through upgrading from ContextForge v0.6.0 to v0.7.0 that implements comprehensive multi-tenancy, team management, and RBAC.
## Overview
Version 0.7.0 introduces major architectural changes:
- **Multi-tenant architecture** with team-based resource isolation
- **Email-based authentication** alongside existing basic auth
- **Personal teams** automatically created for each user
- **Role-Based Access Control (RBAC)** with granular permissions
- **Team visibility controls** (private/public teams, private/team/public resources)
- **SSO integration** with GitHub, Google, and generic OIDC providers
## 🛠️ Migration Tools
This migration includes **2 essential scripts** to help you:
### `scripts/verify_multitenancy_0_7_0_migration.py`
- **Purpose**: Verify v0.6.0 → v0.7.0 migration completed successfully
- **Checks**: Admin user, personal team, resource assignments, visibility settings
- **When**: Run after migration to confirm everything worked
### `scripts/fix_multitenancy_0_7_0_resources.py`
- **Purpose**: Fix resources missing team assignments after v0.6.0 → v0.7.0 upgrade
- **Fixes**: Assigns orphaned servers/tools/resources to admin's personal team
- **When**: Use if verification shows unassigned resources
## Pre-Migration Checklist
### 1. Backup Your Database & Configuration
**⚠️ CRITICAL: Always backup your database AND configuration before upgrading**
#### Database Backup
```bash
# For SQLite (default)
cp mcp.db mcp.db.backup.$(date +%Y%m%d_%H%M%S)
# For PostgreSQL
pg_dump -h localhost -U postgres -d mcp > mcp_backup_$(date +%Y%m%d_%H%M%S).sql
# For MySQL
mysqldump -u mysql -p mcp > mcp_backup_$(date +%Y%m%d_%H%M%S).sql
```
#### Environment Configuration Backup
```bash
# Backup existing .env file before updating
cp .env .env.bak
```
#### Configuration Export (Recommended)
**💡 Export your current configuration via the Admin UI before migration:**
```bash
# 1. Start your current ContextForge
make dev # or however you normally run it
# 2. Access the admin UI
open http://localhost:4444/admin
# 3. Navigate to Export/Import section
# 4. Click "Export Configuration"
# 5. Save the JSON file (contains servers, tools, resources, etc.)
# Or use direct API call (if you have a bearer token):
curl -H "Authorization: Bearer YOUR_TOKEN" \
"http://localhost:4444/admin/export/configuration" \
-o mcp_config_backup_$(date +%Y%m%d_%H%M%S).json
# Or with basic auth:
curl -u admin:changeme \
"http://localhost:4444/admin/export/configuration" \
-o mcp_config_backup_$(date +%Y%m%d_%H%M%S).json
```
**✅ Benefits**:
- Preserves all your servers, tools, resources, and settings
- Can be imported after migration if needed
- Human-readable JSON format
### 2. Setup Environment Configuration
**⚠️ CRITICAL: You must setup your `.env` file before running the migration**
The migration uses your `.env` configuration to create the platform admin user.
#### If you don't have a `.env` file:
```bash
# Copy the example file
cp .env.example .env
# Edit .env to set your admin credentials
nano .env # or your preferred editor
```
#### If you already have a `.env` file:
```bash
# Backup your current .env (already done above)
cp .env .env.bak
# Update with new settings from .env.example
cp .env.example .env.new
# Then manually merge your existing settings into .env.new and rename:
# mv .env.new .env
# Or check if you have the required settings and add manually
grep -E "PLATFORM_ADMIN_EMAIL|PLATFORM_ADMIN_PASSWORD|EMAIL_AUTH_ENABLED" .env
# If missing, add them or merge from .env.example
```
### 3. Configure Required Settings
**⚠️ REQUIRED: Configure these settings in your `.env` file before migration**
```bash
# Platform Administrator (will be created by migration)
PLATFORM_ADMIN_EMAIL=your-admin@yourcompany.com
PLATFORM_ADMIN_PASSWORD=your-secure-password
PLATFORM_ADMIN_FULL_NAME="Your Name"
# Enable email authentication (required for multi-tenancy)
EMAIL_AUTH_ENABLED=true
# Personal team settings (recommended defaults)
AUTO_CREATE_PERSONAL_TEAMS=true
PERSONAL_TEAM_PREFIX=personal
```
**💡 Tips**:
- Use a **real email address** for `PLATFORM_ADMIN_EMAIL` (you'll use this to log in)
- Choose a **strong password** (minimum 8 characters)
- Set `EMAIL_AUTH_ENABLED=true` to enable the multitenancy features
**🔍 Verify your configuration**:
```bash
# Check your settings are loaded correctly
python3 -c "
from mcpgateway.config import settings
print(f'Admin email: {settings.platform_admin_email}')
print(f'Email auth: {settings.email_auth_enabled}')
print(f'Personal teams: {settings.auto_create_personal_teams}')
"
```
## Migration Process
> **🚨 IMPORTANT**: Before starting the migration, you **must** have a properly configured `.env` file with `PLATFORM_ADMIN_EMAIL` and other required settings. The migration will use these settings to create your admin user. See the Pre-Migration Checklist above.
### Step 1: Update Codebase
```bash
# Pull the latest changes
git fetch origin main
git checkout main
git pull origin main
# Update dependencies
make install-dev
```
### Step 2: Run Database Migration
The migration process is automated and handles:
- Creating multi-tenancy database schema
- Creating platform admin user and personal team
- **Migrating existing servers** to the admin's personal team
- Setting up default RBAC roles
**⚠️ PREREQUISITE**: Ensure `.env` file is configured with `PLATFORM_ADMIN_EMAIL` etc. (see step 3 above)
**✅ Configuration**: Uses your `.env` settings automatically
**✅ Database Compatibility**: Works with **SQLite**, **PostgreSQL**, and **MySQL**
```bash
# IMPORTANT: Setup .env first (if not already done)
# Backup existing .env first, then copy new template
cp .env .env.bak
cp .env.example .env # then edit with your admin credentials
# Run the migration (uses settings from your .env file)
python3 -m mcpgateway.bootstrap_db
# Or using make
make dev # This runs bootstrap_db automatically
# Verify migration completed successfully
python3 scripts/verify_multitenancy_0_7_0_migration.py
```
### Step 3: Verify Migration Results
After migration, verify the results using our verification script:
```bash
# Run comprehensive verification
python3 scripts/verify_multitenancy_0_7_0_migration.py
```
This will check:
- ✅ Platform admin user creation
- ✅ Personal team creation and membership
- ✅ Resource team assignments
- ✅ Visibility settings
- ✅ Database integrity
**Expected Output**: All checks should pass. If any fail, see the troubleshooting section below.
## Post-Migration Configuration
### 1. Verify Server Visibility
Old servers should now be visible in the Virtual Servers list. They will be:
- **Owned by**: Your platform admin user
- **Assigned to**: Admin's personal team
- **Visibility**: Public (visible to all authenticated users)
### 2. Import Configuration (If Needed)
If you exported your configuration before migration and need to restore specific settings:
```bash
# Access the admin UI
open http://localhost:4444/admin
# Navigate to Export/Import section → Import Configuration
# Upload your backup JSON file from step 1
# Or use API:
curl -X POST "http://localhost:4444/admin/import/configuration" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d @mcp_config_backup_YYYYMMDD_HHMMSS.json
# Or with basic auth:
curl -X POST "http://localhost:4444/admin/import/configuration" \
-u admin:changeme \
-H "Content-Type: application/json" \
-d @mcp_config_backup_YYYYMMDD_HHMMSS.json
```
**📋 Import Options**:
- **Merge**: Adds missing resources without overwriting existing ones
- **Replace**: Overwrites existing resources with backup versions
- **Selective**: Choose specific servers/tools/resources to import
### 2. Configure SSO (Optional)
If you want to enable SSO authentication:
```bash
# In .env file - Example for GitHub
SSO_ENABLED=true
SSO_PROVIDERS=["github"]
# GitHub configuration
GITHUB_CLIENT_ID=your-github-app-id
GITHUB_CLIENT_SECRET=your-github-app-secret
# Admin assignment (optional)
SSO_AUTO_ADMIN_DOMAINS=["yourcompany.com"]
SSO_GITHUB_ADMIN_ORGS=["your-org"]
```
### 3. Create Additional Teams
After migration, you can create organizational teams:
```bash
# Via API (with admin token)
curl -X POST http://localhost:4444/admin/teams \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Engineering Team",
"description": "Development and engineering resources",
"visibility": "private"
}'
# Or use the Admin UI at http://localhost:4444/admin
```
## Understanding the Migration
### What Happened to My Old Data?
The consolidated migration automatically handles your existing resources in a single, seamless process:
1. **Schema Creation**: Creates all multitenancy tables (users, teams, roles, token management, SSO, etc.)
2. **Column Addition**: Adds `team_id`, `owner_email`, and `visibility` columns to existing resource tables
3. **Admin User Creation**: Creates platform admin user (from `PLATFORM_ADMIN_EMAIL`)
4. **Personal Team Creation**: Creates personal team for the admin user
5. **Data Population**: **Automatically assigns old resources** to admin's personal team with "public" visibility
### Database Tables Created
The migration creates **15 new tables** for the multitenancy system:
**Core Authentication:**
- `email_users` - User accounts and authentication
- `email_auth_events` - Authentication event logging
- `email_api_tokens` - API token management with scoping
- `token_usage_logs` - **Token usage tracking and analytics**
- `token_revocations` - Token revocation blacklist
**Team Management:**
- `email_teams` - Team definitions and settings
- `email_team_members` - Team membership and roles
- `email_team_invitations` - Team invitation workflow
- `email_team_join_requests` - Public team join requests
- `pending_user_approvals` - SSO user approval workflow
**RBAC System:**
- `roles` - Role definitions and permissions
- `user_roles` - User role assignments
- `permission_audit_log` - Permission access auditing
**SSO Integration:**
- `sso_providers` - OAuth2/OIDC provider configuration
- `sso_auth_sessions` - SSO authentication session tracking
This all happens in the consolidated migration `cfc3d6aa0fb2`, so no additional steps are needed.
### Team Assignment Logic
```
Old Server (pre-migration):
├── team_id: NULL
├── owner_email: NULL
└── visibility: NULL
Migrated Server (post-migration):
├── team_id: "admin-personal-team-id"
├── owner_email: "your-admin@yourcompany.com"
└── visibility: "public"
```
### Why "Public" Visibility?
Old servers are set to "public" visibility to ensure they remain accessible to all users immediately after migration. You can adjust visibility per resource:
- **Private**: Only the owner can access
- **Team**: All team members can access
- **Public**: All authenticated users can access
## Customizing Resource Ownership
### Reassign Resources to Specific Teams
After migration, you may want to move resources to appropriate teams:
```bash
# Example: Move a server to a specific team
curl -X PUT http://localhost:4444/admin/servers/SERVER_ID \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"team_id": "target-team-id",
"visibility": "team"
}'
```
### Change Resource Visibility
```bash
# Make a resource private (owner only)
curl -X PUT http://localhost:4444/admin/servers/SERVER_ID \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"visibility": "private"}'
# Make it visible to team members
curl -X PUT http://localhost:4444/admin/servers/SERVER_ID \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"visibility": "team"}'
```
## Troubleshooting
### Issue: Servers Not Visible After Migration
**Problem**: Old servers don't appear in the Virtual Servers list.
**Solution**: This should not happen with the current migration. If it does, check:
```bash
# Check if servers have team assignments
python3 -c "
from mcpgateway.db import SessionLocal, Server
with SessionLocal() as db:
total_servers = db.query(Server).count()
servers_without_team = db.query(Server).filter(Server.team_id == None).count()
print(f'Total servers: {total_servers}')
print(f'Servers without team: {servers_without_team}')
if servers_without_team > 0:
print('ISSUE: Some servers lack team assignment')
print('Re-run the migration: python3 -m mcpgateway.bootstrap_db')
else:
print('✓ All servers have team assignments')
"
```
**Root Cause**: The consolidated migration should handle this automatically. If you still see issues:
1. **First, try the fix script** (recommended):
```bash
python3 scripts/fix_multitenancy_0_7_0_resources.py
```
2. **If that doesn't work**, ensure `PLATFORM_ADMIN_EMAIL` is set and re-run migration:
```bash
export PLATFORM_ADMIN_EMAIL="your-admin@company.com"
python3 -m mcpgateway.bootstrap_db
```
### Issue: Migration Uses Wrong Admin Email
**Problem**: Migration created admin user with default email (`admin@example.com`) instead of your configured email.
**Root Cause**: `.env` file not properly configured before migration.
**Solution**:
1. **Check your `.env` configuration**:
```bash
# Verify your settings are loaded
python3 -c "
from mcpgateway.config import settings
print(f'Admin email: {settings.platform_admin_email}')
print(f'Email auth enabled: {settings.email_auth_enabled}')
"
```
2. **If settings are wrong, update `.env` and re-run**:
```bash
# Edit your .env file
nano .env # Set PLATFORM_ADMIN_EMAIL=your-email@company.com
# Re-run migration
python3 -m mcpgateway.bootstrap_db
```
### Issue: Admin User Not Created
**Problem**: Platform admin user was not created during migration.
**Solution**: Check configuration and re-run:
```bash
# First, verify .env configuration
python3 -c "
from mcpgateway.config import settings
print(f'Admin email: {settings.platform_admin_email}')
print(f'Email auth: {settings.email_auth_enabled}')
"
# If EMAIL_AUTH_ENABLED=false, the admin won't be created
# Set EMAIL_AUTH_ENABLED=true in .env and re-run:
python3 -m mcpgateway.bootstrap_db
# Or manually create using bootstrap function:
python3 -c "
import asyncio
from mcpgateway.bootstrap_db import bootstrap_admin_user
asyncio.run(bootstrap_admin_user())
"
```
### Issue: Personal Team Not Created
**Problem**: Admin user exists but has no personal team.
**Solution**: Create personal team manually:
```bash
python3 -c "
import asyncio
from mcpgateway.db import SessionLocal, EmailUser
from mcpgateway.services.personal_team_service import PersonalTeamService
async def create_admin_team():
with SessionLocal() as db:
# Replace with your admin email
admin_email = 'admin@example.com'
admin = db.query(EmailUser).filter(EmailUser.email == admin_email).first()
if admin:
service = PersonalTeamService(db)
team = await service.create_personal_team(admin)
print(f'Created personal team: {team.name} (id: {team.id})')
asyncio.run(create_admin_team())
"
```
### Issue: Migration Fails During Execution
**Problem**: Migration encounters errors during execution, often with SQLite I/O errors.
**Solution**: Use the comprehensive SQLite troubleshooting guide:
```bash
# 1. Run comprehensive SQLite diagnostics
./scripts/diagnose_sqlite.sh
# 2. Test basic database access
python3 scripts/test_db_access.py
# 3. Test with your exact configuration
python3 scripts/test_sqlalchemy.py
```
**Common SQLite issues during migration:**
- **"disk I/O error"**: File permissions or disk space issues
- **"database is locked"**: Another process using the database
- **macOS version conflicts**: Old system SQLite vs newer requirements
**Quick fixes:**
```bash
# Kill any hanging processes
pkill -f mcpgateway
# Remove corrupted WAL files
rm -f mcp.db-wal mcp.db-shm mcp.db-journal
# macOS: Update SQLite
brew install sqlite3 && brew link --force sqlite3
# Check database connectivity
python3 -c "
from mcpgateway.db import engine
try:
with engine.connect() as conn:
result = conn.execute('SELECT 1')
print('Database connection: OK')
except Exception as e:
print(f'Database error: {e}')
"
# Run migration with verbose output
export LOG_LEVEL=DEBUG
python3 -m mcpgateway.bootstrap_db
```
**📋 For complete SQLite troubleshooting**: See [scripts/troubleshoot-sqlite.md](scripts/troubleshoot-sqlite.md)
## Rollback Procedure
If you need to rollback the migration:
### 1. Restore Database Backup
```bash
# For SQLite
cp mcp.db.backup.YYYYMMDD_HHMMSS mcp.db
# For PostgreSQL
dropdb mcp
createdb mcp
psql -d mcp < mcp_backup_YYYYMMDD_HHMMSS.sql
# For MySQL
mysql -u mysql -p -e "DROP DATABASE mcp; CREATE DATABASE mcp;"
mysql -u mysql -p mcp < mcp_backup_YYYYMMDD_HHMMSS.sql
```
### 2. Revert Environment Configuration
```bash
# Restore previous environment from backup
cp .env.bak .env
# Or manually disable email auth if you want to go back to basic auth only
# Edit .env file and set:
# EMAIL_AUTH_ENABLED=false
```
### 3. Use Previous Codebase Version
```bash
# Check out the previous version
git checkout v0.6.0 # or your previous version tag
# Reinstall dependencies
make install-dev
```
## Verification Checklist
After completing the migration, verify using the automated verification script:
```bash
# Run comprehensive verification
python3 scripts/verify_multitenancy_0_7_0_migration.py
```
Manual checks (if needed):
- [ ] Database migration completed without errors
- [ ] Platform admin user created successfully
- [ ] Personal team created for admin user
- [ ] Old servers are visible in Virtual Servers list
- [ ] Admin UI accessible at `/admin` endpoint
- [ ] Authentication works (email + password)
- [ ] Basic auth still works (if `AUTH_REQUIRED=true`)
- [ ] API endpoints respond correctly
- [ ] Resource creation works and assigns to teams
**If verification fails**: Use the fix script:
```bash
python3 scripts/fix_multitenancy_0_7_0_resources.py
```
## Getting Help
If you encounter issues during migration:
1. **Check the logs**: Set `LOG_LEVEL=DEBUG` for verbose output
2. **Review troubleshooting section** above for common issues
3. **File an issue**: https://github.com/IBM/mcp-context-forge/issues
4. **Include information**: Database type, error messages, relevant logs
## Next Steps
After successful migration:
1. **Review team structure**: Plan how to organize your teams
2. **Configure SSO**: Set up integration with your identity provider
3. **Set up RBAC**: Configure roles and permissions as needed
4. **Train users**: Introduce team-based workflows
5. **Monitor usage**: Use the new audit logs and metrics
The multi-tenant architecture provides much more flexibility and security for managing resources across teams and users. Take time to explore the new admin UI and team management features.
## Quick Reference
### Essential Commands
```bash
# 1. BACKUP (before migration)
cp mcp.db mcp.db.backup.$(date +%Y%m%d_%H%M%S)
cp .env .env.bak
curl -u admin:changeme "http://localhost:4444/admin/export/configuration" -o config_backup.json
# 2. SETUP .ENV (required)
cp .env.example .env # then edit with your admin credentials
# 3. VERIFY CONFIG
python3 -c "from mcpgateway.config import settings; print(f'Admin: {settings.platform_admin_email}')"
# 4. MIGRATE
python3 -m mcpgateway.bootstrap_db
# 5. VERIFY SUCCESS
python3 scripts/verify_multitenancy_0_7_0_migration.py
# 6. FIX IF NEEDED
python3 scripts/fix_multitenancy_0_7_0_resources.py
```
### Important URLs
- **Admin UI**: http://localhost:4444/admin
- **Export Config**: http://localhost:4444/admin/export/configuration
- **Import Config**: http://localhost:4444/admin/import/configuration
---
## SQLite Troubleshooting Guide
> **Common Issue**: `sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) disk I/O error`
This section helps diagnose and fix SQLite database issues, especially with ContextForge v0.7.0 multitenancy.
### Quick Diagnosis Commands
#### 1. Check if database is corrupted
```bash
sqlite3 mcp.db "PRAGMA integrity_check;"
# Expected: "ok"
# If corrupted: Shows specific errors
```
#### 2. Check if database is locked
```bash
sqlite3 mcp.db "PRAGMA locking_mode;"
# Expected: "normal"
# Problem: "exclusive" or hangs
```
#### 3. Check database file permissions and size
```bash
ls -la mcp.db
file mcp.db
# Expected: readable/writable by user, "SQLite 3.x database"
# Problem: no write permissions, 0 bytes, or "data" instead of SQLite
```
#### 4. Try to open database manually
```bash
sqlite3 mcp.db ".tables"
# Expected: List of tables (gateways, tools, etc.)
# Test basic queries
sqlite3 mcp.db "SELECT COUNT(*) FROM gateways;"
sqlite3 mcp.db "SELECT * FROM email_users LIMIT 1;" # v0.7.0 only
```
#### 5. Check for WAL/Journal files
```bash
ls -la mcp.db*
# Look for: mcp.db-wal, mcp.db-shm, mcp.db-journal
# These can cause corruption if process was killed
```
#### 6. Check SQLite versions
```bash
# System SQLite version
/usr/bin/sqlite3 --version
sqlite3 --version
# Python SQLite version
python3 -c "import sqlite3; print(f'Python SQLite: {sqlite3.sqlite_version}')"
python3 -c "import sqlite3; print(f'Python module: {sqlite3.version}')"
```
### System Resource Checks
#### 7. Check disk space
```bash
df -h .
df -i . # Check inodes too
```
#### 8. Check file descriptor limits (ulimit)
```bash
ulimit -n # File descriptors
ulimit -u # Max processes
ulimit -a # All limits
# Increase if needed (add to ~/.zshrc or ~/.bash_profile)
ulimit -n 4096
ulimit -u 2048
```
#### 9. Check for process locks
```bash
# Check if any process has the DB open
lsof mcp.db
fuser mcp.db # Linux only
# Kill hanging processes
pkill -f mcpgateway
pkill -f gunicorn
pkill -f python
```
### Platform-Specific Checks
#### macOS Specific
```bash
# Check for quarantine attributes
xattr -l mcp.db
xattr -l .
# Remove quarantine if present
xattr -d com.apple.quarantine mcp.db 2>/dev/null || true
# Check if in sandboxed directory
pwd # Avoid ~/Desktop, ~/Documents
# Check SQLite version conflict (common on macOS)
/usr/bin/sqlite3 --version # System SQLite (usually old)
/opt/homebrew/bin/sqlite3 --version 2>/dev/null || echo "Homebrew SQLite not installed"
# Update SQLite via Homebrew (recommended)
brew install sqlite3
brew link --force sqlite3
# Verify updated version
which sqlite3
sqlite3 --version
# Use Homebrew Python with updated SQLite
brew install python3
/opt/homebrew/bin/python3 -c "import sqlite3; print(f'Python SQLite: {sqlite3.sqlite_version}')"
```
##### Filesystem location pitfalls (macOS)
- Avoid storing `mcp.db` under synced or special folders (iCloud Drive, Dropbox, OneDrive, Google Drive), external exFAT drives, or network shares. These can break SQLite's journaling/locking and trigger `disk I/O error`.
- Prefer a local APFS path and an absolute `DATABASE_URL`:
```bash
mkdir -p "$HOME/Library/Application Support/mcpgateway"
# Note the four slashes for absolute path and the space in the folder name
export DATABASE_URL="sqlite:////Users/$USER/Library/Application Support/mcpgateway/mcp.db"
```
Alternatively, keep the repository and database in a simple home directory folder (avoids iCloud-managed Documents/Desktop):
```bash
mkdir -p "$HOME/mcp-context-forge/data"
export DATABASE_URL="sqlite:////Users/$USER/mcp-context-forge/data/mcp.db"
```
### Common Fixes
#### Fix 1: Remove corrupted WAL files
```bash
# Stop all processes first
pkill -f mcpgateway
# Remove WAL/journal files
rm -f mcp.db-wal mcp.db-shm mcp.db-journal
# Force WAL checkpoint if DB is accessible
sqlite3 mcp.db "PRAGMA wal_checkpoint(FULL);" || echo "DB not accessible"
```
#### Fix 2: Repair corrupted database
```bash
# Backup first
cp mcp.db mcp.db.corrupted
# Try to dump and restore
sqlite3 mcp.db.corrupted ".dump" | sqlite3 mcp.db.recovered
mv mcp.db.recovered mcp.db
# Or recreate from scratch (LOSES DATA)
rm mcp.db
python3 -m mcpgateway.bootstrap_db
```
#### Fix 3: Fix permissions
```bash
# Fix file permissions
chmod 664 mcp.db
chmod 755 $(dirname mcp.db)
chown $USER:$USER mcp.db
# For macOS - remove extended attributes
xattr -c mcp.db 2>/dev/null || true
```
#### Fix 4: Update SQLite on macOS
```bash
# macOS often ships with old SQLite - update via Homebrew
brew install sqlite3
brew link --force sqlite3
# Update Python to use newer SQLite
brew install python3
# Recreate virtual environment with updated Python/SQLite
deactivate # if in venv
rm -rf ~/.venv/mcpgateway
/opt/homebrew/bin/python3 -m venv ~/.venv/mcpgateway
source ~/.venv/mcpgateway/bin/activate
pip install -e ".[dev]"
# Verify versions
python3 -c "import sqlite3; print(f'SQLite: {sqlite3.sqlite_version}')"
sqlite3 --version
```
#### Fix 5: Reduce startup concurrency (single worker)
SQLite is file-based. Running migrations and first-queries concurrently across multiple Gunicorn workers can stress macOS filesystems:
```bash
# Run production server with a single worker while validating the environment
GUNICORN_WORKERS=1 make serve
# Or run the dev server (single-process)
make dev
```
If this eliminates errors, the underlying issue is filesystem/locking. Keep the DB on a safe path and gradually raise workers.
### Environment Configuration for v0.7.0
#### Enhanced SQLite settings for multitenancy
```bash
# In .env file - v0.7.0 needs WAL mode for better concurrency
DATABASE_URL="sqlite:///./mcp.db?check_same_thread=false&journal_mode=WAL&synchronous=NORMAL&cache_size=10000&timeout=60"
# Connection pool settings
DB_POOL_SIZE=10
DB_MAX_OVERFLOW=5
DB_POOL_TIMEOUT=60
DB_POOL_RECYCLE=3600
DB_MAX_RETRIES=5
DB_RETRY_INTERVAL_MS=2000
```
#### macOS Specific .env Settings
```bash
# Increase timeouts for macOS filesystem
DATABASE_URL="sqlite:///./mcp.db?timeout=60&journal_mode=WAL"
DB_POOL_TIMEOUT=60
DB_MAX_RETRIES=10
DB_RETRY_INTERVAL_MS=5000
# Optionally reduce pool pressure during troubleshooting
DB_POOL_SIZE=10
DB_MAX_OVERFLOW=0
```
#### Optional: In-process mode (bypass file-lock leadership)
To simplify troubleshooting and remove file-lock leadership competition on macOS, temporarily use in-process mode for cache/session management:
```bash
export CACHE_TYPE=none
```
### Test Database Access
Run the comprehensive test script:
```bash
python3 scripts/test_sqlite.py --verbose
# If using a custom path, pass it explicitly
python3 scripts/test_sqlite.py --database-url "sqlite:////Users/$USER/Library/Application Support/mcpgateway/mcp.db" --verbose
```
This script tests:
- Direct SQLite access
- SQLAlchemy engine with ContextForge settings
- System diagnostics and recommendations
### Quick Reference Table
| Issue | Quick Fix |
|-------|-----------|
| **"disk I/O error"** | Check permissions/disk space: `ls -la mcp.db && df -h .` |
| **"database is locked"** | `pkill -f mcpgateway && rm -f mcp.db-wal mcp.db-shm` |
| **macOS version conflicts** | `brew install sqlite3 && brew link --force sqlite3` |
| **WAL file corruption** | `rm -f mcp.db-wal mcp.db-shm && sqlite3 mcp.db "PRAGMA wal_checkpoint(FULL);"` |
| **Low ulimits** | `ulimit -n 8192 && ulimit -u 128000` |
| **v0.7.0 multitenancy issues** | Add WAL mode: `DATABASE_URL="sqlite:///./mcp.db?journal_mode=WAL"` |
Scanned 5/31/2026
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!