|
| 1 | +# MySQL MCP Server (mysql_mcp_server.py) |
| 2 | + |
| 3 | +A Python-based MCP (Model Context Protocol) server that provides a suite of tools for managing and interacting with MySQL AI and MySQL HeatWave database resources. This MCP server is not intended for production use but as a proof of concept for exploring models using MCP Servers. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +`mysql_mcp_server.py` is a FastMCP-based server that provides tools for managing MySQL connections, executing SQL, using MySQL AI ML/AI features, and working with OCI Object Storage. |
| 8 | + |
| 9 | +## Features |
| 10 | + |
| 11 | +- **Database Connection Management** |
| 12 | + - Load connection configs from JSON or environment variables |
| 13 | + - List all configured database connections |
| 14 | + - Validate connectivity and resolve provider mode (MySQL AI vs. OCI) |
| 15 | + |
| 16 | +- **Database Operations** |
| 17 | + - Execute SQL queries |
| 18 | + |
| 19 | +- **MySQL AI ML and AI Tools** |
| 20 | + - `ml_generate`: Text generation with MySQL AI GenAI |
| 21 | + - `ragify_column`: Create/populate vector columns for embeddings |
| 22 | + - `ask_ml_rag`: Retrieval-augmented generation from vector stores |
| 23 | + |
| 24 | +- **Vector Store Management** |
| 25 | + - List files in `secure_file_priv` (local mode) |
| 26 | + - Load documents into vector stores from local file system |
| 27 | + - Load documents from OCI Object Storage into vector stores |
| 28 | + |
| 29 | +- **OCI Object Store Tools** |
| 30 | + - List all compartments |
| 31 | + - Get compartment by name |
| 32 | + - List buckets in a compartment |
| 33 | + - List objects in a bucket |
| 34 | + |
| 35 | +## Prerequisites |
| 36 | + |
| 37 | +- Python 3.x |
| 38 | +- `fastmcp` |
| 39 | +- `oci` SDK |
| 40 | +- `mysql-connector-python` SDK |
| 41 | +- Valid database connection file. Resolution order: |
| 42 | + 1) Path specified by environment variable `MYSQL_MCP_CONFIG` (absolute or relative to this module) |
| 43 | + 2) `src/mysql-mcp-server/local_config.json` (default) |
| 44 | +- Valid OCI configuration file (`~/.oci/config`) or environment variables |
| 45 | + |
| 46 | +## Installation |
| 47 | + |
| 48 | +1. Clone this repository. |
| 49 | +2. Install required dependencies using pip: |
| 50 | + ``` |
| 51 | + pip install -r requirements.txt |
| 52 | + ``` |
| 53 | + This will install `oci`, `fastmcp`, `mysql-connector-python`, and all other dependencies. |
| 54 | +3. Set up your OCI config file at ~/.oci/config |
| 55 | + |
| 56 | +## OCI Configuration |
| 57 | + |
| 58 | +The server requires a valid OCI config file with proper credentials. |
| 59 | +The default location is ~/.oci/config. For instructions on setting up this file, |
| 60 | +see the [OCI SDK documentation](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdkconfig.htm). |
| 61 | + |
| 62 | +## Required Python Packages |
| 63 | + |
| 64 | +- `oci` |
| 65 | +- `requests` |
| 66 | +- `fastmcp` |
| 67 | +- `mysql-connector-python` |
| 68 | + |
| 69 | +## Supported Database Modes |
| 70 | + |
| 71 | +- **MYSQL_AI** (local MySQL AI AI mode) |
| 72 | +- **OCI** (Oracle Cloud Infrastructure-managed databases) |
| 73 | + |
| 74 | +## MCP Server Configuration |
| 75 | + |
| 76 | +Installation is dependent on the MCP Client being used, it usually consists of adding the MCP Server invocation in a json config file, for example with Claude UI on windows it looks like this: |
| 77 | +```json |
| 78 | +{ |
| 79 | + "mcpServers": { |
| 80 | + "mysqltools": { |
| 81 | + "command": "C:\\Python\\python.exe", |
| 82 | + "args": [ |
| 83 | + "C:\\Users\\user1\\mysql-mcp-server\\mysql_mcp_server.py" |
| 84 | + ] |
| 85 | + } |
| 86 | + } |
| 87 | +} |
| 88 | +``` |
| 89 | + |
| 90 | + |
| 91 | + |
| 92 | +Example with TENANCY_ID_OVERRIDE:: |
| 93 | +```json |
| 94 | +{ |
| 95 | + "mcpServers": { |
| 96 | + "mysqltools": { |
| 97 | + "command": "C:\\Python\\python.exe", |
| 98 | + "args": [ |
| 99 | + "C:\\Users\\user1\\mysql-mcp-server\\mysql_mcp_server.py" |
| 100 | + ], |
| 101 | + "env": { |
| 102 | + "TENANCY_ID_OVERRIDE": "ocid1.tenancy.oc1..deadbeef" |
| 103 | + } |
| 104 | + } |
| 105 | + } |
| 106 | +} |
| 107 | +``` |
| 108 | + |
| 109 | +## Environment Variables |
| 110 | + |
| 111 | +The server supports the following environment variables: |
| 112 | + |
| 113 | +- `PROFILE_NAME`: OCI configuration profile name (default: "DEFAULT") |
| 114 | +- `TENANCY_ID_OVERRIDE`: Overrides the tenancy ID from the config file |
| 115 | + |
| 116 | +## Configuration (utils.fill_config_defaults and utils.load_mysql_config) |
| 117 | + |
| 118 | +The server loads and validates connection configuration using two helpers in utils.py. |
| 119 | + |
| 120 | +- utils.load_mysql_config: |
| 121 | + - Search order (first existing file wins): |
| 122 | + 1) Path from env `MYSQL_MCP_CONFIG` (if set). If relative, also tries `<module_dir>/<value>`. |
| 123 | + 2) `<module_dir>/local_config.json` (default when env not set) |
| 124 | + 3) `<module_dir>/config.json` |
| 125 | + 4) `<cwd>/config.json` |
| 126 | + - Returns a validated dict after passing the loaded JSON through fill_config_defaults. |
| 127 | + |
| 128 | +- utils.fill_config_defaults: |
| 129 | + - Validates the schema and applies defaults for the optional bastion section. |
| 130 | + - Expected JSON shape: |
| 131 | + { |
| 132 | + "server_infos": { |
| 133 | + "<connection_id>": { |
| 134 | + "host": "<hostname or IP>", |
| 135 | + "user": "<username>", |
| 136 | + "password": "<password>", |
| 137 | + "database": "<default_schema>", |
| 138 | + "port": 3306 |
| 139 | + } |
| 140 | + }, |
| 141 | + "bastion": { // optional; for SSH tunneling |
| 142 | + "bastion_host": "<host>", |
| 143 | + "bastion_username": "<user>", |
| 144 | + "private_key_path": "<path to private key>", |
| 145 | + "db_host": "<remote DB host>", |
| 146 | + "db_port": 3306, // default 3306 |
| 147 | + "bastion_port": 22, // default 22 |
| 148 | + "local_bind_host": "127.0.0.1", // default 127.0.0.1 |
| 149 | + "local_bind_port": 3306 // default 3306 |
| 150 | + } |
| 151 | + } |
| 152 | + - Required server entry keys are exactly: {"host","user","password","database","port"}. |
| 153 | + - If a bastion block is present, only the allowed keys above are permitted; defaults are applied when omitted. |
| 154 | + |
| 155 | +Example minimal config (local file): |
| 156 | +{ |
| 157 | + "server_infos": { |
| 158 | + "local_server": { |
| 159 | + "host": "localhost", |
| 160 | + "user": "root", |
| 161 | + "password": "", |
| 162 | + "database": "mysql_mcp", |
| 163 | + "port": 3306 |
| 164 | + } |
| 165 | + } |
| 166 | +} |
| 167 | + |
| 168 | +Example with bastion: |
| 169 | +{ |
| 170 | + "server_infos": { |
| 171 | + "remote_via_bastion": { |
| 172 | + "host": "127.0.0.1", |
| 173 | + "user": "dbuser", |
| 174 | + "password": "secret", |
| 175 | + "database": "appdb", |
| 176 | + "port": 3306 |
| 177 | + } |
| 178 | + }, |
| 179 | + "bastion": { |
| 180 | + "bastion_host": "bastion.example.com", |
| 181 | + "bastion_username": "ubuntu", |
| 182 | + "private_key_path": "/home/user/.ssh/id_rsa", |
| 183 | + "db_host": "mysql.internal", |
| 184 | + "db_port": 3306 |
| 185 | + // optional keys (with defaults if omitted): bastion_port, local_bind_host, local_bind_port |
| 186 | + } |
| 187 | +} |
| 188 | + |
| 189 | +Note: |
| 190 | +- Set `MYSQL_MCP_CONFIG` to point at a specific JSON file if you don't want to use `local_config.json`. |
| 191 | +- The defaults and schema enforcement are performed at startup; invalid or incomplete entries raise clear exceptions. |
| 192 | + |
| 193 | +## Usage |
| 194 | + |
| 195 | +The server runs using stdio transport and can be started by running: |
| 196 | + |
| 197 | +```bash |
| 198 | +python mysql_mcp_server.py |
| 199 | +``` |
| 200 | + |
| 201 | +## API Tools |
| 202 | + |
| 203 | +1. `list_all_connections()`: List configured database connections and modes |
| 204 | +2. `execute_sql_tool_by_connection_id(connection_id, sql, params)`: Execute SQL on a database connection |
| 205 | +3. `ml_generate(connection_id, question)`: Generate text via MySQL AI ML |
| 206 | +4. `ragify_column(connection_id, table, input_col, embedding_col)`: Embed text into a VECTOR column |
| 207 | +5. `list_vector_store_files_local(connection_id)`: List available files in `secure_file_priv` |
| 208 | +6. `load_vector_store_local(connection_id, file_path)`: Load documents from local filesystem |
| 209 | +7. `load_vector_store_oci(connection_id, namespace, bucket, prefix, schema, table)`: Load documents from OCI Object Storage |
| 210 | +8. `ask_ml_rag_vector_store(connection_id, question)`: RAG query on default vector store |
| 211 | +9. `ask_ml_rag_innodb(connection_id, question, segment_col, embedding_col)`: RAG query restricted to InnoDB tables |
| 212 | +10. `list_all_compartments()`: List OCI compartments |
| 213 | +11. `object_storage_list_buckets(compartment_name | compartment_id)`: List buckets in a compartment |
| 214 | +12. `object_storage_list_objects(namespace, bucket_name)`: List objects in a bucket |
| 215 | + |
| 216 | +## Security |
| 217 | + |
| 218 | +- Uses OCI’s config-based authentication |
| 219 | +- MySQL connection parameters may be stored in JSON config or environment variables |
| 220 | + |
| 221 | +## Example Prompts |
| 222 | + |
| 223 | +Here are example prompts you can use to interact with the MCP server, note that depending on the model being used you might need to be more specific, for example: "list all employees using myConnection1 mysql connection". |
| 224 | + |
| 225 | +### 1. Database Operations |
| 226 | + |
| 227 | +``` |
| 228 | +"List all configured database connections" |
| 229 | +"Execute 'SELECT * FROM employees' on my connection" |
| 230 | +"Add embeddings for 'body' column into 'embedding' column in docs table" |
| 231 | +``` |
| 232 | + |
| 233 | +### 2. MySQL AI AI |
| 234 | + |
| 235 | +``` |
| 236 | +"Generate a summary of error logs using MySQL AI ML" |
| 237 | +"Ask ml_rag: Show me refund policy from the vector store" |
| 238 | +``` |
| 239 | + |
| 240 | +### 3. Object Storage |
| 241 | + |
| 242 | +``` |
| 243 | +"List all compartments in my tenancy" |
| 244 | +"Show all buckets in the development compartment" |
| 245 | +"List objects in my 'docs-bucket'" |
| 246 | +``` |
| 247 | + |
| 248 | +### 4. Vector Store |
| 249 | + |
| 250 | +``` |
| 251 | +"Load all documents with prefix 'manuals/' into schema hr, table product_docs" |
| 252 | +"List local files for vector store ingestion" |
| 253 | +``` |
0 commit comments