Skip to content
Merged
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
11 changes: 9 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,20 @@ DOCS_ALLOW_BASIC_AUTH=false

# Database Configuration
# Optimized for v0.7.0 multitenancy with enhanced connection pooling and timeouts
# macOS note:
# If you see "sqlite3.OperationalError: disk I/O error" on macOS when running

# SQLite (default) - good for development and small deployments
# macOS note: If you see "sqlite3.OperationalError: disk I/O error" on macOS when running
# `make serve`, move the DB to a safe APFS path (avoid iCloud/Dropbox/OneDrive/Google Drive,
# network shares, or external exFAT) and use an absolute path, for example:
# DATABASE_URL=sqlite:////Users/$USER/Library/Application Support/mcpgateway/mcp.db
DATABASE_URL=sqlite:///./mcp.db

# PostgreSQL - recommended for production deployments
# DATABASE_URL=postgresql://postgres:mysecretpassword@localhost:5432/mcp

# MariaDB/MySQL - fully supported for production
# For container deployment: mysql+pymysql://mysql:changeme@mariadb:3306/mcp
# For localhost: mysql+pymysql://mysql:changeme@localhost:3306/mcp
# DATABASE_URL=mysql+pymysql://mysql:changeme@localhost:3306/mcp

# Database Connection Pool Configuration (optimized for v0.7.0 multitenancy)
Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
DB_POOL_TIMEOUT=30 # Seconds to wait for connection before timeout (default: 30)
DB_POOL_RECYCLE=3600 # Seconds before recreating connection (default: 3600)
```
* **Complete MariaDB & MySQL Database Support** (#925) - Full production support for MariaDB and MySQL backends:
```bash
# MariaDB (recommended MySQL-compatible option):
DATABASE_URL=mysql+pymysql://mysql:changeme@localhost:3306/mcp

# Docker deployment with MariaDB 12.0.2-ubi10:
DATABASE_URL=mysql+pymysql://mysql:changeme@mariadb:3306/mcp
```
- **36+ database tables** fully compatible with MariaDB 12.0+ and MySQL 8.4+
- All **VARCHAR length issues** resolved for MySQL compatibility
- **Container support**: MariaDB and MySQL drivers included in all container images
- **Complete feature parity** with SQLite and PostgreSQL backends
- **Production ready**: Supports all MCP Gateway features including federation, caching, and A2A agents

* **Enhanced JWT Configuration** - Audience, issuer claims, and improved token validation:
```bash
# New JWT configuration options:
Expand Down
2 changes: 1 addition & 1 deletion Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ COPY . /app
# Including observability packages for OpenTelemetry support
RUN python3 -m venv /app/.venv && \
/app/.venv/bin/python3 -m pip install --upgrade pip setuptools pdm uv && \
/app/.venv/bin/python3 -m uv pip install ".[redis,postgres,alembic,observability]"
/app/.venv/bin/python3 -m uv pip install ".[redis,postgres,mysql,alembic,observability]"

# update the user permissions
RUN chown -R 1001:0 /app && \
Expand Down
2 changes: 1 addition & 1 deletion Containerfile.lite
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ COPY pyproject.toml /app/
RUN set -euo pipefail \
&& python3 -m venv /app/.venv \
&& /app/.venv/bin/pip install --no-cache-dir --upgrade pip setuptools wheel pdm uv \
&& /app/.venv/bin/uv pip install ".[redis,postgres,observability]" \
&& /app/.venv/bin/uv pip install ".[redis,postgres,mysql,observability]" \
&& /app/.venv/bin/pip uninstall --yes uv pip setuptools wheel pdm \
&& rm -rf /root/.cache /var/cache/dnf \
&& find /app/.venv -name "*.dist-info" -type d \
Expand Down
20 changes: 14 additions & 6 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ services:
# MCP Gateway - the main API server for the MCP stack
# ──────────────────────────────────────────────────────────────────────
gateway:
#image: ghcr.io/ibm/mcp-context-forge:0.6.0 # Use the release MCP Context Forge image
image: ${IMAGE_LOCAL:-mcpgateway/mcpgateway:latest} # Use the local latest image. Run `make docker-prod` to build it.
image: ghcr.io/ibm/mcp-context-forge:0.6.0 # Use the release MCP Context Forge image
#image: ${IMAGE_LOCAL:-mcpgateway/mcpgateway:latest} # Use the local latest image. Run `make docker-prod` to build it.
build:
context: .
dockerfile: Containerfile # Same one the Makefile builds
Expand All @@ -41,7 +41,7 @@ services:
- HOST=0.0.0.0
- PORT=4444
- DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD:-mysecretpassword}@postgres:5432/mcp
# - DATABASE_URL=mysql+pymysql://mysql:${MYSQL_PASSWORD:-changeme}@mysql:3306/mcp
# - DATABASE_URL=mysql+pymysql://mysql:${MYSQL_PASSWORD:-changeme}@mariadb:3306/mcp
# - DATABASE_URL=mysql+pymysql://admin:${MARIADB_PASSWORD:-changeme}@mariadb:3306/mcp
# - DATABASE_URL=mongodb://admin:${MONGO_PASSWORD:-changeme}@mongodb:27017/mcp
- CACHE_TYPE=redis # backend for caching (memory, redis, database, or none)
Expand Down Expand Up @@ -120,15 +120,23 @@ services:
# volumes: [mariadbdata:/var/lib/mysql]
# networks: [mcpnet]

# mysql:
# image: mysql:8
# mariadb:
# image: registry.redhat.io/rhel9/mariadb-106:12.0.2-ubi10
# environment:
# - MYSQL_ROOT_PASSWORD=mysecretpassword
# - MYSQL_DATABASE=mcp
# - MYSQL_USER=mysql
# - MYSQL_PASSWORD=changeme
# volumes: [mysqldata:/var/lib/mysql]
# volumes: ["mariadbdata:/var/lib/mysql"]
# networks: [mcpnet]
# ports:
# - "3306:3306"
# healthcheck:
# test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-pmysecretpassword"]
# interval: 30s
# timeout: 10s
# retries: 5
# start_period: 30s

# mongodb:
# image: mongo:7
Expand Down
20 changes: 14 additions & 6 deletions docs/docs/deployment/compose.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,23 @@ curl http://localhost:4444/health # {"status":"ok"}

Uncomment one service block in `docker-compose.yml` and align `DATABASE_URL`:

| Service block | Connection string |
| --------------------- | --------------------------------------------- |
| `postgres:` (default) | `postgresql://postgres:...@postgres:5432/mcp` |
| `mariadb:` | `mysql+pymysql://admin:...@mariadb:3306/mcp` |
| `mysql:` | `mysql+pymysql://mysql:...@mysql:3306/mcp` |
| `mongodb:` | `mongodb://admin:...@mongodb:27017/mcp` |
| Service block | Connection string | Notes |
| --------------------- | --------------------------------------------- | ------------------------------ |
| `postgres:` (default) | `postgresql://postgres:...@postgres:5432/mcp` | Recommended for production |
| `mariadb:` | `mysql+pymysql://mysql:...@mariadb:3306/mcp` | **Fully supported** - MariaDB 12.0+ |
| `mysql:` | `mysql+pymysql://admin:...@mysql:3306/mcp` | Alternative MySQL variant |
| `mongodb:` | `mongodb://admin:...@mongodb:27017/mcp` | NoSQL option |

Named volumes (`pgdata`, `mariadbdata`, `mysqldata`, `mongodata`) isolate persistent data.

!!! info "MariaDB & MySQL Full Support"
MariaDB and MySQL are **fully supported** alongside SQLite and PostgreSQL:

- **36+ database tables** work perfectly with MariaDB 12.0+ and MySQL 8.4+
- All **VARCHAR length issues** have been resolved for MariaDB/MySQL compatibility
- Simply uncomment the `mariadb:` service block in `docker-compose.yml`
- Use connection string: `mysql+pymysql://mysql:changeme@mariadb:3306/mcp`

---

## 🔄 Lifecycle cheatsheet
Expand Down
141 changes: 139 additions & 2 deletions docs/docs/deployment/kubernetes.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,151 @@ spec:

You can load your `.env` as a ConfigMap:

```bash
kubectl create configmap mcpgateway-env --from-env-file=.env
=== "With SQLite (Default)"
```bash
# Create .env file
cat > .env << EOF
HOST=0.0.0.0
PORT=4444
DATABASE_URL=sqlite:///./mcp.db
JWT_SECRET_KEY=your-secret-key
BASIC_AUTH_USER=admin
BASIC_AUTH_PASSWORD=changeme
MCPGATEWAY_UI_ENABLED=true
MCPGATEWAY_ADMIN_API_ENABLED=true
EOF

kubectl create configmap mcpgateway-env --from-env-file=.env
```

=== "With MariaDB"
```bash
# Create .env file
cat > .env << EOF
HOST=0.0.0.0
PORT=4444
DATABASE_URL=mysql+pymysql://mysql:changeme@mariadb-service:3306/mcp
JWT_SECRET_KEY=your-secret-key
BASIC_AUTH_USER=admin
BASIC_AUTH_PASSWORD=changeme
MCPGATEWAY_UI_ENABLED=true
MCPGATEWAY_ADMIN_API_ENABLED=true
EOF

kubectl create configmap mcpgateway-env --from-env-file=.env
```

=== "With MySQL"
```bash
# Create .env file
cat > .env << EOF
HOST=0.0.0.0
PORT=4444
DATABASE_URL=mysql+pymysql://mysql:changeme@mysql-service:3306/mcp
JWT_SECRET_KEY=your-secret-key
BASIC_AUTH_USER=admin
BASIC_AUTH_PASSWORD=changeme
MCPGATEWAY_UI_ENABLED=true
MCPGATEWAY_ADMIN_API_ENABLED=true
EOF

kubectl create configmap mcpgateway-env --from-env-file=.env
```

=== "With PostgreSQL"
```bash
# Create .env file
cat > .env << EOF
HOST=0.0.0.0
PORT=4444
DATABASE_URL=postgresql://postgres:changeme@postgres-service:5432/mcp
JWT_SECRET_KEY=your-secret-key
BASIC_AUTH_USER=admin
BASIC_AUTH_PASSWORD=changeme
MCPGATEWAY_UI_ENABLED=true
MCPGATEWAY_ADMIN_API_ENABLED=true
EOF

kubectl create configmap mcpgateway-env --from-env-file=.env
```

> Make sure it includes `JWT_SECRET_KEY`, `AUTH_REQUIRED`, etc.

---

## 🗄 Database Deployment Examples

### MySQL Deployment

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8
env:
- name: MYSQL_ROOT_PASSWORD
value: mysecretpassword
- name: MYSQL_DATABASE
value: mcp
- name: MYSQL_USER
value: mysql
- name: MYSQL_PASSWORD
value: changeme
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-storage
persistentVolumeClaim:
claimName: mysql-pvc
---
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
```

!!! info "MariaDB & MySQL Kubernetes Support"
MariaDB and MySQL are **fully supported** in Kubernetes deployments:

- **36+ database tables** work perfectly with MariaDB 12.0+ and MySQL 8.4+
- All **VARCHAR length issues** resolved for MariaDB/MySQL compatibility
- Use connection string: `mysql+pymysql://mysql:changeme@mariadb-service:3306/mcp`

---

## 💡 OpenShift Considerations

* Use `Route` instead of Ingress
Expand Down
63 changes: 63 additions & 0 deletions docs/docs/deployment/local.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,69 @@ make dev # hot-reload (Uvicorn) on :8000

---

## 🗄 Database Configuration

By default, MCP Gateway uses SQLite for simplicity. You can configure alternative databases via the `DATABASE_URL` environment variable:

=== "SQLite (Default)"
```bash
# .env file
DATABASE_URL=sqlite:///./mcp.db
```

=== "MariaDB"
```bash
# .env file
DATABASE_URL=mysql+pymysql://mysql:changeme@localhost:3306/mcp
```

!!! info "MariaDB Setup"
Install and configure MariaDB server:
```bash
# Ubuntu/Debian
sudo apt update && sudo apt install mariadb-server

# Create database and user
sudo mariadb -e "CREATE DATABASE mcp;"
sudo mariadb -e "CREATE USER 'mysql'@'localhost' IDENTIFIED BY 'changeme';"
sudo mariadb -e "GRANT ALL PRIVILEGES ON mcp.* TO 'mysql'@'localhost';"
sudo mariadb -e "FLUSH PRIVILEGES;"
```

=== "MySQL"
```bash
# .env file
DATABASE_URL=mysql+pymysql://mysql:changeme@localhost:3306/mcp
```

!!! info "MySQL Setup"
Install and configure MySQL server:
```bash
# Ubuntu/Debian
sudo apt update && sudo apt install mysql-server

# Create database and user
sudo mysql -e "CREATE DATABASE mcp;"
sudo mysql -e "CREATE USER 'mysql'@'localhost' IDENTIFIED BY 'changeme';"
sudo mysql -e "GRANT ALL PRIVILEGES ON mcp.* TO 'mysql'@'localhost';"
sudo mysql -e "FLUSH PRIVILEGES;"
```

=== "PostgreSQL"
```bash
# .env file
DATABASE_URL=postgresql://postgres:changeme@localhost:5432/mcp
```

!!! tip "MariaDB & MySQL Full Compatibility"
MariaDB and MySQL are **fully supported** with:

- **36+ database tables** working perfectly with MariaDB 12.0+ and MySQL 8.4+
- All **VARCHAR length issues** resolved for MariaDB/MySQL compatibility
- Complete feature parity with SQLite and PostgreSQL

---

## 🧪 Health Test

```bash
Expand Down
1 change: 1 addition & 0 deletions docs/docs/manage/.pages
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
nav:
- index.md
- configuration.md
- backup.md
- bulk-import.md
- metadata-tracking.md
Expand Down
Loading
Loading