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
18 changes: 18 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.git
.github
.ruff_cache
.env
*.egg-info
__pycache__
tests
docs
*.md
!README.md
LICENSE
SECURITY.md
CODE_OF_CONDUCT.md
CONTRIBUTING.md
docker-compose.yml
policy
.pre-commit-config.yaml
.gitignore
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ jobs:
images: ghcr.io/jrhuerta/secure-sql-mcp
tags: |
type=raw,value=${{ github.event.release.tag_name }}
type=raw,value=latest

- name: Build and push image
uses: docker/build-push-action@v7
Expand Down
5 changes: 3 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,9 @@ Run core security suites:
## Container Publishing

- GitHub Actions publishes container images to `ghcr.io/jrhuerta/secure-sql-mcp`.
- Images are published only when a GitHub Release is published (e.g. tag `v0.1.0`).
- Use the release tag to pull: `docker pull ghcr.io/jrhuerta/secure-sql-mcp:v0.1.0`.
- Images are published only when a GitHub Release is published.
- Each release pushes both the version tag (e.g. `v0.1.0`) and `latest`.
- Use `docker pull ghcr.io/jrhuerta/secure-sql-mcp:latest` or a specific version tag.

## Policy File Contract

Expand Down
23 changes: 14 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
FROM python:3.12-slim
FROM python:3.12-slim AS builder

ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1
WORKDIR /build
COPY pyproject.toml README.md ./
COPY src ./src

WORKDIR /app
RUN python -m venv /opt/venv \
&& /opt/venv/bin/pip install --no-cache-dir . \
&& find /opt/venv -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null; true

COPY pyproject.toml README.md /app/
COPY src /app/src
FROM python:3.12-slim

ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PATH="/opt/venv/bin:$PATH"

RUN pip install --no-cache-dir . \
&& useradd -r -s /usr/sbin/nologin appuser \
&& chown -R appuser:appuser /app
COPY --from=builder /opt/venv /opt/venv

RUN useradd -r -s /usr/sbin/nologin appuser
USER appuser

ENTRYPOINT ["python", "-m", "secure_sql_mcp.server"]
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ To use this server with Cursor, Claude Desktop, or other MCP clients, add it to
"--rm",
"--env-file", "/path/to/your/secrets",
"-v", "/path/to/your/policy:/run/policy:ro",
"ghcr.io/jrhuerta/secure-sql-mcp:v0.1.0"
"ghcr.io/jrhuerta/secure-sql-mcp:latest"
]
}
}
Expand All @@ -31,7 +31,7 @@ To use this server with Cursor, Claude Desktop, or other MCP clients, add it to

**Claude Desktop** (`claude_desktop_config.json`): same structure under `mcpServers`.

The `--env-file` should point to a file containing `DATABASE_URL` and `ALLOWED_POLICY_FILE=/run/policy/allowed_policy.txt` (see Environment Variables below). The volume mounts the policy directory read-only. Pull the image first: `docker pull ghcr.io/jrhuerta/secure-sql-mcp:v0.1.0`
The `--env-file` should point to a file containing `DATABASE_URL` and `ALLOWED_POLICY_FILE=/run/policy/allowed_policy.txt` (see Environment Variables below). The volume mounts the policy directory read-only. Pull the image first: `docker pull ghcr.io/jrhuerta/secure-sql-mcp:latest`

## Security Model

Expand Down Expand Up @@ -164,10 +164,10 @@ docker run -i --rm \

## Quick Start (GHCR Image)

Images are published when a GitHub Release is published (e.g. tag `v0.1.0`). Pull by release tag:
Images are published when a GitHub Release is created. Each release pushes both the version tag (e.g. `v0.1.0`) and `latest`:

```bash
docker pull ghcr.io/jrhuerta/secure-sql-mcp:v0.1.0
docker pull ghcr.io/jrhuerta/secure-sql-mcp:latest
```

Run with env file and read-only mounted policy:
Expand All @@ -176,7 +176,7 @@ Run with env file and read-only mounted policy:
docker run -i --rm \
--env-file .env \
-v "$(pwd)/policy:/run/policy:ro" \
ghcr.io/jrhuerta/secure-sql-mcp:v0.1.0
ghcr.io/jrhuerta/secure-sql-mcp:latest
```

Or with Docker Compose (builds from local Dockerfile):
Expand Down Expand Up @@ -280,8 +280,8 @@ After merging workflow/docs changes, verify:
- linear history, no force-push, no deletion
- CI workflow runs on PRs and on pushes to `main`
- GHCR image publish succeeds when a GitHub Release is published
- GHCR pull works (use release tag, e.g. `v0.1.0`):
- `docker pull ghcr.io/jrhuerta/secure-sql-mcp:v0.1.0`
- GHCR pull works:
- `docker pull ghcr.io/jrhuerta/secure-sql-mcp:latest`
- community docs are present:
- `CONTRIBUTING.md`
- `CODE_OF_CONDUCT.md`
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ license = "MIT"
requires-python = ">=3.11"
authors = [{ name = "jrhuerta" }]
dependencies = [
"mcp[cli]",
"mcp",
"sqlglot",
"sqlalchemy[asyncio]",
"asyncpg",
Expand All @@ -36,6 +36,7 @@ Issues = "https://github.com/jrhuerta/secure-sql-mcp/issues"

[project.optional-dependencies]
dev = [
"mcp[cli]",
"pre-commit",
"pytest",
"ruff",
Expand Down