Skip to content
GitHub (opens in a new tab)

Databases · MCP Firewall integration

Keep MySQL credentials private. Keep AI queries under control.

Use GateRook’s MCP Firewall to separate MySQL read access from changes that need your review. Follow the local walkthrough to configure a scoped login, store its password in GateRook, approve one update, and inspect the recorded outcome.

Step-by-step walkthrough

Control AI queries to MySQL with GateRook’s MCP Firewall

GateRook’s MCP Firewall gives an AI app controlled access to MySQL without putting the database password in its SQL tool calls. You choose the database, expose the connection through an endpoint, and keep changes behind approval. Activity shows the request, the authorization decision, and the outcome.

This walkthrough uses GateRook 0.7.0, MySQL 8.4.10 in Docker Desktop on macOS, and Codex connected to the showcase development endpoint. We create a separate mysql-demo connection and use four fictional orders to demonstrate discovery, reads, an update request, and auditing.

New to GateRook? Set up your endpoint and AI app first.

1. Start an isolated MySQL server

Keep Docker Desktop and GateRook running. This example assumes that showcase already exists and your AI app is connected to it. It uses a separate container and host port, so an existing MySQL server on port 3306 can keep running.

Create a local working directory and generate independent passwords for the administrator and tutorial user. Keep the resulting environment file private and outside version control.

Shell commands
mkdir -p ~/gaterook-mysql-demo
cd ~/gaterook-mysql-demo
umask 077

python3 - <<'PY'
from pathlib import Path
import secrets

path = Path("mysql.env")
with path.open("x") as output:
    output.write(
        "MYSQL_ROOT_PASSWORD=" + secrets.token_hex(24) + "\n"
        "MYSQL_DATABASE=gaterook_demo\n"
        "MYSQL_USER=demo_agent\n"
        "MYSQL_PASSWORD=" + secrets.token_hex(24) + "\n"
    )
path.chmod(0o600)
PY

Create init.sql in that directory:

Shell commands
cat > init.sql <<'SQL'
USE gaterook_demo;

CREATE TABLE orders (
    id INT PRIMARY KEY,
    customer_name VARCHAR(100) NOT NULL,
    status VARCHAR(20) NOT NULL,
    total DECIMAL(10,2) NOT NULL,
    CONSTRAINT orders_status
        CHECK (status IN ('pending', 'paid', 'shipped'))
);

INSERT INTO orders VALUES
    (1001, 'Avery Stone', 'pending', 129.90),
    (1002, 'Morgan Reed', 'paid', 89.00),
    (1003, 'Riley Chen', 'pending', 249.00),
    (1004, 'Jordan Lee', 'shipped', 49.50);

REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'demo_agent'@'%';
GRANT SELECT, UPDATE ON gaterook_demo.orders TO 'demo_agent'@'%';
SQL

The image creates demo_agent from the environment variables. The initialization script replaces its initial database privileges with SELECT and UPDATE on this one table. It does not grant INSERT, DELETE, or schema changes. See the official MySQL image documentation for environment variables and initialization scripts.

Start the container:

Shell commands
docker run -d \
  --name gaterook-mysql-showcase \
  -p 127.0.0.1:13306:3306 \
  --env-file mysql.env \
  --mount "type=bind,source=$(pwd)/init.sql,target=/docker-entrypoint-initdb.d/01-demo.sql,readonly" \
  --health-cmd='MYSQL_PWD="$MYSQL_PASSWORD" mysql --protocol=TCP -h 127.0.0.1 -u "$MYSQL_USER" -D "$MYSQL_DATABASE" -Nse "SELECT COUNT(*) FROM orders"' \
  --health-interval=2s \
  --health-timeout=3s \
  --health-retries=30 \
  mysql:8.4.10

docker inspect --format '{{.State.Health.Status}}' \
  gaterook-mysql-showcase

Wait until the health status is healthy. The check authenticates as the tutorial user over TCP and reads the sample table. The published address is 127.0.0.1:13306, available only from this computer. Choose a different name or port if either is already in use.

The initialization script runs when the container initializes an empty data directory. Editing the file or environment variables later does not reset an existing database. Keep the container for the stop/start commands at the end of this tutorial.

2. Choose the MySQL connector

Open Connections → Add connection. In this capture, the connection list is filtered to mysql-demo so that unrelated server addresses and credential references stay out of view. An empty result is expected before creating the connection.

Connections filtered to mysql-demo, with Add connection available.
Connections filtered to mysql-demo, with Add connection available.

Select MySQL, then Continue. The built-in connector exposes four SQL tools.

The MySQL connector selected in the Add connection wizard.
The MySQL connector selected in the Add connection wizard.

3. Enter the server and credentials

Fill in these fields:

FieldValue
Namemysql-demo
Host127.0.0.1
Port13306
Secret sourceEncrypted here
Userdemo_agent
PasswordThe generated MYSQL_PASSWORD value in your private mysql.env file
EnvironmentDEV Development

Use the tutorial user's password, not MYSQL_ROOT_PASSWORD. Copy only the value after MYSQL_PASSWORD= into GateRook; do not paste the environment file or password into your AI conversation.

The connection name is the identifier used in tool calls and Activity filters. Choose it before saving: the saved name cannot be edited because calls and policies refer to it.

The mysql-demo name and local server address on port 13306.
The mysql-demo name and local server address on port 13306.

GateRook's core connects from this computer. Encrypted here stores the credential encrypted with the local master key, and the connector supplies it when connecting to MySQL. The AI's later tool arguments contain the connection name, database, and SQL, without the password.

Encrypted here selected, demo_agent entered, and the password masked.
Encrypted here selected, demo_agent entered, and the password masked.

4. Configure encryption and the database allowlist

Expand Advanced and use:

FieldValue in this example
SSL modeEncrypt, don't verify (require)
CA certificateEmpty for this disposable local server
Database allowlistAdd gaterook_demo as a chip using the + button
Allow public key retrievalUnchecked
Statement timeoutLeave empty to use the environment policy
Pool size2
Connect timeout5000 ms
Functions reads may callLeave empty

This MySQL container supports TLS. The selected mode requires encryption, but does not verify the server certificate or host name. It is the setting used for this loopback-only fixture. For a remote database, configure a trusted certificate and use Verify the CA and host name (verify-full); supply a private CA certificate when needed. The distinction between encryption and server identity verification is explained in MySQL's Connector/J security settings.

Public key retrieval is unnecessary for this TLS connection and is left off. In MySQL, a schema is a database; use gaterook_demo here rather than PostgreSQL's public schema name.

MySQL settings requiring encryption, allowing only gaterook_demo, and disabling public key retrieval.
MySQL settings requiring encryption, allowing only gaterook_demo, and disabling public key retrieval.

5. Load and select the database

Select Load databases, then tick gaterook_demo. The example shows 1 databases available · 1 selected. Database discovery and selection are separate: a discovered database must be selected before agents can use it through this connection.

Keep DEV Development selected. Its description explicitly says that mutations still wait for approval. Reload the database list if you change the server, credentials, or transport settings.

gaterook_demo selected, the password masked, and the DEV environment retained.
gaterook_demo selected, the password masked, and the DEV environment retained.

6. Test the connection

Select Continue. GateRook tests the configuration and displays the MySQL version and the user's permissions.

The actual result in this run was Connected · MySQL 8.4.10. The permissions summary reported:

  • SELECT on one table.
  • UPDATE on gaterook_demo.orders.
  • No CREATE or ownership for schema changes.

The write warning is expected: this tutorial needs one update to demonstrate approval. For a connection that only needs analytics, grant only the necessary read privileges at the database level. An approval never grants database privileges that the login does not already have.

Successful MySQL connection test with SELECT and UPDATE privileges on the sample table.
Successful MySQL connection test with SELECT and UPDATE privileges on the sample table.

7. Add the connection to showcase

Continue to Add to endpoint. Untick default and tick only showcase. Select Save connection after reviewing the tool modes.

The saved page confirms Healthy, 1 endpoint, and 4 tools on showcase · Codex. The password appears as Encrypted version 1, with no readable value.

The saved mysql-demo connection, healthy status, encrypted credential, and showcase attachment.
The saved mysql-demo connection, healthy status, encrypted credential, and showcase attachment.

8. Understand how a call reaches MySQL

Open Endpoints → showcase. The diagram shows Codex calling the endpoint, which applies its modes and development policy before using a connection. In this workspace, showcase now contains the existing PostgreSQL demo and the new MySQL demo.

The showcase endpoint diagram with Codex connected and mysql-demo healthy.
The showcase endpoint diagram with Codex connected and mysql-demo healthy.

Under Tools & policies, scroll to mysql-demo:

ToolModeWhat it does
sql_list_schemasRead onlyLists accessible schemas/databases and tables.
sql_describe_tableRead onlyDescribes columns, keys, indexes, and constraints.
sql_queryRead onlyExecutes a validated read query.
sql_executeApprovalRequests a data change for a person to review.

Keep sql_execute in Approval. Bypass would remove the approval step for future calls and is not used here. The gateway's own discovery tools can appear separately in Off mode; they are not the four MySQL connector tools.

MySQL's three read tools in Read only and sql_execute in Approval mode.
MySQL's three read tools in Read only and sql_execute in Approval mode.

A call identifies mysql-demo and gaterook_demo. GateRook checks access, mode, policy, and limits, uses the stored credential inside the connector, and records the result in Activity. The existing Codex session successfully used the new connection in this run. If your client retains an old tool catalog, refresh its MCP tools or reconnect it before retrying discovery.

9. Discover the table and read its rows

Ask your connected AI app:

Through showcase, use mysql-demo and database gaterook_demo. List the tables, describe orders, show all four orders sorted by id, and summarize the order count and total by status.

The discovery calls returned one table, gaterook_demo.orders, with an integer primary key, a customer name, a status, and a DECIMAL(10,2) total. The status check permits pending, paid, and shipped.

The first read used:

Tool arguments
{
  "connection": "mysql-demo",
  "database": "gaterook_demo",
  "sql": "SELECT id, customer_name, status, total FROM orders ORDER BY id",
  "limit": 10
}

It returned:

idcustomer_namestatustotal
1001Avery Stonepending129.90
1002Morgan Reedpaid89.00
1003Riley Chenpending249.00
1004Jordan Leeshipped49.50

The grouped query was:

SQL query
SELECT status, COUNT(*) AS order_count, SUM(total) AS total_amount
FROM orders
GROUP BY status
ORDER BY status;
statusorder_counttotal_amount
paid189.00
pending2378.90
shipped149.50

For MySQL, sql_query runs a validated read in a read-only transaction and rolls it back after reading. The advertised limit in this configuration is 1,000 rows and five seconds; these examples request only ten rows. Send one SQL statement per MySQL call.

Open Activity → Agent calls, enter the following filter, and press Enter:

Activity filter
endpoint:showcase connection:mysql-demo

Select the initial sql_query event. Request identifies Codex and showcase. Arguments shows the exact SELECT, database, connection, and requested row limit.

The initial MySQL SELECT in Activity, including its client, endpoint, and arguments.
The initial MySQL SELECT in Activity, including its client, endpoint, and arguments.

Scroll down. Policy decision says Allowed and explains that the read ran immediately. Result shows four rows, a response summary, size, hash, and zero masked fields in this fictional dataset. Timing separates resource execution from gateway overhead.

The allowed read decision, four-row result summary, hash, masking count, and timing.
The allowed read decision, four-row result summary, hash, masking count, and timing.

10. Request a change and review the exact action

Ask the AI to mark order 1001 as shipped only if it is still pending. The sql_execute request in this run used:

SQL query
UPDATE orders
SET status = 'shipped'
WHERE id = 1001 AND status = 'pending';

GateRook returned a pending approval handle: the SQL had not executed. The AI displays the approval card once and polls that handle instead of submitting the UPDATE again.

In Approvals, review the following before deciding:

  • The connection mysql-demo, DEV environment, and showcase endpoint.
  • The exact table, assigned status, and both conditions in the WHERE clause.
  • The matched rule dev.sql.write-approval.
  • The impact preview: target orders, an estimate of 1 row from EXPLAIN, a transaction rolled back on error, and a five-second statement timeout.

The row estimate is a preview; the execution result establishes the actual affected-row count. Add an optional comment, then select Approve and run to execute this exact action, or Deny to refuse it. Only a person can approve in GateRook. Opening the chat card does not approve anything. An unanswered request expires after its displayed deadline.

The Approvals screen is protected from automated screenshots. The screenshot below instead shows the actual client-side approval card supplied by the operator after the decision; the protection was left enabled.

The person approved the request at 10:25:03 on November 3, 2026 (Europe/Madrid). Polling the original handle returned completed, with a committed transaction and 1 row updated.

The GateRook approval card in Codex showing Completed for sql_execute on mysql-demo.
The GateRook approval card in Codex showing Completed for sql_execute on mysql-demo.

11. Verify the saved change

After approval, read the row again through the same endpoint and connection:

SQL query
SELECT id, customer_name, status, total
FROM orders
WHERE id = 1001;

The follow-up sql_query returned:

idcustomer_namestatustotal
1001Avery Stoneshipped129.90

This verifies the database state independently of the approval message. The follow-up read is also recorded in Activity.

The verification SELECT recorded in Activity, showing order 1001 with status shipped.
The verification SELECT recorded in Activity, showing order 1001 with status shipped.

12. Follow the audit trail

Return to Activity → Agent calls and use:

Activity filter
endpoint:showcase connection:mysql-demo

Choose a time range covering the test and select Refresh. The walkthrough made six calls: schema discovery, table description, the initial SELECT, the grouped SELECT, the approved UPDATE, and the verification SELECT. Read calls run immediately; the UPDATE passes through the approval workflow.

Activity filtered to showcase and mysql-demo, with five Allowed reads and one Approved update.
Activity filtered to showcase and mysql-demo, with five Allowed reads and one Approved update.

Open the sql_execute event to inspect Arguments, Policy decision, Approval, Result, and Timing. These sections connect the requested SQL to the policy, the person's decision, and the actual execution. The affected-row count distinguishes the actual outcome from the estimate shown before approval.

The Approved sql_execute event with the exact UPDATE, mysql-demo connection, and showcase endpoint.
The Approved sql_execute event with the exact UPDATE, mysql-demo connection, and showcase endpoint.

Scroll to the approval timeline. This event records the request at 10:20:33, the person's approval at 10:25:03, and execution in 17 ms with 1 row affected. The executed action matches the approved action byte for byte, with the approved action's SHA-256 displayed beside the timeline. The result contains committed: true and rowsAffected: 1.

The approval timeline, exact-action match, and committed one-row UPDATE result.
The approval timeline, exact-action match, and committed one-row UPDATE result.

Use the filters to answer practical questions: Which client used this connection? What did it request? Why was it allowed or sent for approval? Was the exact action approved? Did it succeed, and how many rows changed?

Result detail depends on the tool. The read event shown above contains a compact text summary, response size, and hash; Activity should not be treated as a complete database-result archive. Masking follows the configured policies. The fictional records in this example returned zero masked fields; that does not establish that arbitrary personal data would be masked automatically.

Keep or stop the demo

The new connection is attached only to showcase, with reads enabled and writes requiring approval. You can keep the container running for further exploration.

To pause access while retaining configuration, turn the connection's On switch off; that affects this connection across endpoints. Turning an endpoint off pauses access through that endpoint. Previous calls remain available in Activity.

Stop the database without deleting its data:

Shell commands
docker stop gaterook-mysql-showcase

Resume it later:

Shell commands
docker start gaterook-mysql-showcase

Wait for healthy, then use Test connection in GateRook. Keep the private environment file and initialization file in their local working directory, and do not commit their credentials or paste them into chat.

Useful access. Explicit control.

What you can do with MySQL and AI

Understand an unfamiliar schema

Ask the agent to list the available tables, describe their columns and follow foreign keys before it proposes a join. The database allowlist keeps the exploration inside the databases you selected.

Investigate an application issue

Read the status of a specific order or compare grouped counts with a limited SELECT. Pair the endpoint with Redis or HTTP access to compare persisted state with the cache or API response.

Review a proposed correction

Let the agent prepare a targeted UPDATE through sql_execute. GateRook shows the exact statement for approval; the database account and environment policy still decide which changes are possible.

Connection settings

Configure MySQL in GateRook

These are example values for the connection form. Enter credentials into GateRook’s secret fields, not into an AI prompt. Requirements and alternatives are noted per field.

MySQL connection configuration
SettingExampleHow to use it
Connector typeMySQLChoose the built-in connector in Connections.
Name / environmentmysql-demo / DEV DevelopmentUse this connection name in tool calls and Activity filters. Keep writes behind approval.
Host / port127.0.0.1 / 13306The tutorial container publishes MySQL only on the loopback interface of the computer running GateRook.
Database selection / allowlistgaterook_demoAdd the allowlist chip in Advanced, then load the databases and select gaterook_demo. In MySQL, a schema is a database.
User / passworddemo_agent / Your generated MYSQL_PASSWORDChoose Encrypted here and enter the generated password in GateRook. The tutorial login has only SELECT and UPDATE on gaterook_demo.orders.
SSL modeEncrypt, don't verify (require)Requires encryption for this local fixture without verifying server identity. For remote databases, use verify-full with a trusted certificate and supply a private CA when needed.
Allow public key retrievalUncheckedPublic key retrieval is not needed for this TLS connection.
Endpoint / tool modesshowcase / Read only + ApprovalSelect only showcase. Keep the three read tools in Read only and sql_execute in Approval; leave Bypass unselected.

Know what you expose

MySQL tools and access boundaries

The connector defines available operations. GateRook’s MCP Firewall enforces endpoint modes and connection policies before an AI client can use them.

Available tools and access behavior
ToolPurposeAccess behavior
sql_list_schemasDiscover the schemas, databases and tables visible to the connection user.Read only
sql_describe_tableInspect columns, types, indexes and foreign keys before writing a query.Read only
sql_queryRun a read query or EXPLAIN in a read-only transaction, with endpoint limits.Read only
sql_executePropose INSERT, UPDATE or DELETE. You review and approve the exact SQL before execution.Approval

Before you enable access

  • sql_query runs reads in a read-only transaction. sql_execute is a separate tool and requires approval for changes; a read-only database login still cannot write after approval.
  • The endpoint caps rows and execution time. Do not treat a truncated result as the full dataset.
  • Unknown user-defined functions are not automatically trusted as reads: they require approval, and are refused on prod unless allowed by policy.
  • A query result can contain application data. Choose tables, columns and access scope deliberately before exposing them to an AI app.

GateRook stores local connection secrets encrypted and resolves them for connectors. Allowed tool results are returned to your AI client and may be processed by its provider. Scope the data you expose as well as the actions you allow.

Practical answers

MySQL connection questions

Use Test connection to isolate service access problems. Use Playground and Activity to inspect endpoint permissions and tool calls.

Is GateRook a MySQL MCP server or an AI client?

GateRook connects to MySQL and exposes selected database tools through an MCP endpoint. Your AI app is the MCP client. It receives the endpoint configuration, while the database password stays with the GateRook connection.

Can the AI change database records?

In this walkthrough, sql_execute uses Approval mode. The policy must permit the statement, the database user must have permission, and you must approve the exact action. Keep Bypass unselected to preserve this review step.

Does the MySQL connector also support MariaDB?

Yes. The MySQL dialect explicitly handles MySQL and MariaDB, including their different statement timeout settings. Use MySQL in the connection picker for either server; the MariaDB guide describes that setup.

Do I need to expose the database to the public internet?

No. The local GateRook core connects from your computer, so an existing VPN and private network route can be used. The database must be reachable by that computer.

Keep exploring

PostgreSQL

Put PostgreSQL behind GateRook’s MCP Firewall. Follow the illustrated setup, scope AI queries, approve an UPDATE and inspect its Activity audit trail.

MariaDB

Protect MariaDB access with GateRook’s MCP Firewall. Follow the Docker tutorial to scope SQL queries, approve an update and inspect the Activity record.

Redis

Protect Redis access with scoped, read-only MCP tools. Follow the GateRook Docker tutorial to approve a value read and inspect its Activity record.

Browse all integration guides

Your MCP Firewall. Your access rules.

Control AI access to MySQL.

Start with read-only access. Approve changes. Inspect the audit trail.

Read the getting started guide

Get GateRook

Download GateRook 0.9.2 for your Mac, or get the Windows app from Microsoft Store.

macOS

Version 0.9.2 for Apple Silicon (arm64). This download does not support Intel Macs.

Open the DMG and drag GateRook to Applications.

Windows

Available for free from Microsoft Store. Install GateRook and receive updates through the Store.

macOS release notes and checksums (opens in a new tab)