Repository navigation
feat(docker): mysql-mcp images with component_mcp_guard and the tool pack (RFC 0001 Phase 3) #244
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
d33dba6
feat(docker): mysql-mcp images with component_mcp_guard and the tool …
askdba 177b70b
fix(docker): base mysql-mcp images on the guard's exact build release
askdba f888106
fix(docker): review of #244 — required release, TCP healthcheck, NO_B…
askdba 5badedf
fix(docker): health check without root logins, on the server's port
askdba 7f33318
Merge remote-tracking branch 'origin/main' into feat/mysql-mcp-images
askdba File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # mysql-mcp: the official MySQL image with the MCP components of RFC 0001 | ||
| # (askdba/mysql-mcp-server): component_mcp_guard and the mysql_mcp SQL tool pack. | ||
| # Published as ghcr.io/askdba/mysql-mcp:<8.4|9.7|26.10> by docker-publish.yml. | ||
| # Build context: the repository root, with component_mcp_guard-<arch>.so staged there. | ||
| # MYSQL_VERSION (required, no default) must be the exact release the component was built | ||
| # against, for example 8.4.8: a component built for another patch release can crash the | ||
| # server. | ||
| ARG MYSQL_VERSION | ||
|
|
||
| FROM mysql:${MYSQL_VERSION} | ||
| ARG TARGETARCH | ||
|
|
||
| LABEL org.opencontainers.image.title="mysql-mcp" \ | ||
| org.opencontainers.image.description="MySQL with component_mcp_guard and the mysql_mcp tool pack for mysql-mcp-server" \ | ||
| org.opencontainers.image.source="https://github.com/askdba/myvector" \ | ||
| org.opencontainers.image.documentation="https://github.com/askdba/myvector/blob/main/docs/MCP_COMPONENTS.md" \ | ||
| org.opencontainers.image.licenses="GPL-2.0-only AND Apache-2.0" | ||
|
|
||
| # Statically linked against libstdc++/libgcc and built in oraclelinux:9, this image's base. | ||
| COPY component_mcp_guard-${TARGETARCH}.so /usr/lib64/mysql/plugin/component_mcp_guard.so | ||
| COPY sql/mcp/mysql_mcp.sql sql/mcp/uninstall.sql sql/mcp/LICENSE /usr/share/mysql-mcp/ | ||
| COPY docker/mysql-mcp/mysql-mcp-init.sh /docker-entrypoint-initdb.d/50-mysql-mcp.sh | ||
| COPY docker/mysql-mcp/mysql-mcp-healthcheck.sh /usr/local/bin/mysql-mcp-healthcheck | ||
|
|
||
| # checkov:skip=CKV_DOCKER_3:MySQL entrypoint needs root for initialization | ||
| # Healthy only after first-start setup, on the server's port, without touching root's | ||
| # login (see the script). | ||
| HEALTHCHECK --interval=30s --timeout=5s --retries=5 CMD ["/usr/local/bin/mysql-mcp-healthcheck"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| #!/bin/sh | ||
| # Health check of the mysql-mcp image: is mysqld up and done with first-start setup? | ||
| # | ||
| # - TCP: the entrypoint's temporary setup server does not listen on TCP, so the check | ||
| # passes only once the real server runs. | ||
| # - The port mysqld was started with (--port=N or --port N on its command line; else 3306). | ||
| # - As a user that does not exist, with no password: ping reports a running server even | ||
| # when access is denied, and a nonexistent account cannot be locked by failed logins | ||
| # (probing as root could lock out administrators with FAILED_LOGIN_ATTEMPTS). | ||
| port=$(tr '\0' '\n' </proc/1/cmdline 2>/dev/null | awk ' | ||
| prev == "--port" || prev == "-P" { p = $0 } | ||
| /^--port=/ { p = substr($0, 8) } | ||
| { prev = $0 } | ||
| END { print p }') | ||
| exec mysqladmin ping --protocol=TCP -h127.0.0.1 -P"${port:-3306}" \ | ||
| -umysql-mcp-healthcheck --connect-timeout=3 --silent |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| #!/bin/bash | ||
| # First-start setup of the mysql-mcp image. Sourced by the official entrypoint (it is not | ||
| # executable), so docker_process_sql and mysql_note are available. | ||
| # | ||
| # - installs component_mcp_guard and gives root MCP_ADMIN (to change mcp.* settings); | ||
| # - installs the mysql_mcp SQL tool pack; | ||
| # - MYSQL_MCP_USER / MYSQL_MCP_PASSWORD: creates an account for mysql-mcp-server that | ||
| # holds MCP_USER (so the guard applies to it), EXECUTE on mysql_mcp and SELECT, SHOW | ||
| # VIEW on MYSQL_MCP_DATABASES (comma-separated; default MYSQL_DATABASE); | ||
| # - MYSQL_MCP_ALLOWED_SCHEMAS, MYSQL_MCP_MAX_EXECUTION_TIME_MS: persisted as | ||
| # mcp.allowed_schemas and mcp.max_execution_time_ms. | ||
|
|
||
| # Batches with literals start with this, so _mcp_sql_literal's escaping holds even when | ||
| # the server runs with NO_BACKSLASH_ESCAPES. | ||
| _mcp_backslash_escapes="SET SESSION sql_mode = REPLACE(@@SESSION.sql_mode, 'NO_BACKSLASH_ESCAPES', '');" | ||
| _mcp_sql_literal() { # a single-quoted SQL string literal (with backslash escapes) | ||
| local s=${1//\\/\\\\} | ||
| printf "'%s'" "${s//\'/\'\'}" | ||
| } | ||
| _mcp_sql_ident() { # a backquoted identifier | ||
| printf '`%s`' "${1//\`/\`\`}" | ||
| } | ||
|
|
||
| mysql_note "mysql-mcp: installing component_mcp_guard" | ||
| docker_process_sql --database=mysql <<<"INSTALL COMPONENT 'file://component_mcp_guard'" | ||
| # Dynamic privileges registered after root was created: grant them to every root account. | ||
| _mcp_roots=$(docker_process_sql --database=mysql -N -B <<<"SELECT CONCAT(QUOTE(user), '@', QUOTE(host)) FROM mysql.user WHERE user = 'root'") | ||
| for _mcp_root in $_mcp_roots; do | ||
| docker_process_sql --database=mysql <<<"GRANT MCP_ADMIN ON *.* TO $_mcp_root" | ||
| done | ||
|
|
||
| mysql_note "mysql-mcp: installing the mysql_mcp tool pack" | ||
| docker_process_sql --database=mysql </usr/share/mysql-mcp/mysql_mcp.sql | ||
|
|
||
| _mcp_settings=$_mcp_backslash_escapes | ||
| if [ -n "${MYSQL_MCP_ALLOWED_SCHEMAS:-}" ]; then | ||
| _mcp_settings+="SET PERSIST mcp.allowed_schemas = $(_mcp_sql_literal "$MYSQL_MCP_ALLOWED_SCHEMAS");" | ||
| fi | ||
| if [ -n "${MYSQL_MCP_MAX_EXECUTION_TIME_MS:-}" ]; then | ||
| case "$MYSQL_MCP_MAX_EXECUTION_TIME_MS" in | ||
| *[!0-9]*) mysql_error "MYSQL_MCP_MAX_EXECUTION_TIME_MS must be a number of milliseconds" ;; | ||
| esac | ||
| _mcp_settings+="SET PERSIST mcp.max_execution_time_ms = $MYSQL_MCP_MAX_EXECUTION_TIME_MS;" | ||
| fi | ||
| [ "$_mcp_settings" = "$_mcp_backslash_escapes" ] || docker_process_sql --database=mysql <<<"$_mcp_settings" | ||
|
|
||
| if [ -n "${MYSQL_MCP_USER:-}" ]; then | ||
| [ -n "${MYSQL_MCP_PASSWORD:-}" ] || mysql_error "MYSQL_MCP_USER is set but MYSQL_MCP_PASSWORD is not" | ||
| [ "$MYSQL_MCP_USER" != root ] || mysql_error "MYSQL_MCP_USER cannot be root" | ||
| _mcp_account="$(_mcp_sql_literal "$MYSQL_MCP_USER")@'%'" | ||
| mysql_note "mysql-mcp: creating MCP account $MYSQL_MCP_USER" | ||
| _mcp_grants="$_mcp_backslash_escapes | ||
| CREATE USER $_mcp_account IDENTIFIED BY $(_mcp_sql_literal "$MYSQL_MCP_PASSWORD"); | ||
| GRANT MCP_USER ON *.* TO $_mcp_account; | ||
| GRANT EXECUTE ON mysql_mcp.* TO $_mcp_account;" | ||
| IFS=',' read -r -a _mcp_dbs <<<"${MYSQL_MCP_DATABASES:-${MYSQL_DATABASE:-}}" | ||
| for _mcp_db in "${_mcp_dbs[@]}"; do | ||
| _mcp_db=${_mcp_db#"${_mcp_db%%[![:space:]]*}"} # trim | ||
| _mcp_db=${_mcp_db%"${_mcp_db##*[![:space:]]}"} | ||
| [ -n "$_mcp_db" ] || continue | ||
| # Escape _ and % so the grant names exactly this schema (as the entrypoint does). | ||
| _mcp_pattern=${_mcp_db//\\/\\\\} | ||
| _mcp_pattern=${_mcp_pattern//_/\\_} | ||
| _mcp_pattern=${_mcp_pattern//%/\\%} | ||
| _mcp_grants+=" | ||
| GRANT SELECT, SHOW VIEW ON $(_mcp_sql_ident "$_mcp_pattern").* TO $_mcp_account;" | ||
| done | ||
| docker_process_sql --database=mysql <<<"$_mcp_grants" | ||
| fi | ||
| unset _mcp_backslash_escapes _mcp_roots _mcp_root _mcp_settings _mcp_account _mcp_grants _mcp_dbs _mcp_db _mcp_pattern | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.