| layout | page |
|---|---|
| title | MCP Tool Reference |
| subtitle | Every tool the mariadb-shell MCP server exposes, what it takes, and the behaviour that is not obvious from the name. |
| permalink | /mcp-tools/ |
| description | Reference for the mariadb-shell MCP server tools — db.*, msm.*, sandbox.*, util.*, sql.* and the optional migrator.* group. |
The server exposes {{ site.tool_count }} tools in five groups, plus an optional sixth that only appears when the migration tooling is installed.
| Group | Tools | What they do |
|---|---|---|
db.* |
8 | List connections and schemas, describe objects, run SQL |
msm.* |
12 | Versioned schema projects, releases, deployments |
sandbox.* |
8 | List deployable server versions; deploy, start, stop and delete local instances |
util.* |
12 | Dump, load, export, import and copy data between servers, as background tasks |
sql.* |
3 | Check, outline and format SQL text with MariaDB's grammar — no server needed |
migrator.* |
4 | MySQL-to-MariaDB migration — optional, not counted above |
A server in multi-tenant mode (mcp setup --multiTenant=true, mariadb-shell
26.10.0 and later) serves only the db.* group — 26.10.0 and 26.10.1 served
msm.* too. The other groups run local servers and long jobs, or read and write
files, on the server's own machine and are not offered to tenants.
The plugins' launchers start a single-tenant server, which serves every group.
| Tool | Arguments | Notes |
|---|---|---|
db.list_connections |
— | The configured connection URIs. Derived from the shell's secret store, so a sandbox's auto-registered connection appears here too. Call it first. |
db.connect |
uri |
Opens and caches a connection, returns a connection_id. The URI is normalized before matching; a URI asking for more than was configured (a default schema, an option) is refused. |
db.list_schemas |
connection_id |
Schemas visible to the account. A missing schema is usually privileges. |
db.list_objects |
connection_id, schema_name, object_type="table" |
table, view, procedure, function, trigger, event. |
db.get_object_details |
connection_id, schema_name, object_name, object_type="table" |
Structured detail — columns, keys, indexes, constraints — not a CREATE string. Call this before proposing any schema change. |
db.execute_sql |
connection_id, sql, params=None |
One statement. Use it when you want rows back or need parameters. |
db.execute_sql_script |
connection_id, sql_script=None, file_path=None, stop_on_error=True, limit=None, column_metadata=False |
Multi-statement, in order, on the connection's session. Not a transaction, and a failed statement does not raise — see the warning below. |
db.close |
connection_id |
Closes it. Idle connections are reaped anyway, but close before deleting a sandbox. |
What it does not do is undo itself or raise. A failed statement comes back as an
entry with an error key, the script stops there (stop_on_error=True), and
everything before it has already taken effect. Check every entry before calling
a script done.
State is lost in one case only: a connection that sat idle long enough to be
closed is reopened before the script runs, and the first entry then carries
session_restarted: true. Whatever earlier calls left in the session —
variables, the current schema, an open transaction — is gone.
MariaDB Schema Management. See [Tutorial 6]({{ '/tutorials/versioned-schema-with-msm/' | relative_url }}) for the workflow and the section model.
| Tool | Arguments | Notes |
|---|---|---|
msm.create_project |
schema_name, target_path, copyright_holder, license, overwrite_existing, … |
Scaffolds <schema>.msm.project/. An unrecognized license name is rejected — omit it or pass your own text. |
msm.get_project_information |
schema_project_path |
Project metadata. |
msm.set_development_version |
version, schema_project_path |
Sets the version in section 910 of the development script. |
msm.get_released_versions |
schema_project_path |
Every released version. |
msm.get_last_released_version |
schema_project_path |
The most recent release. |
msm.get_last_deployment_version |
schema_project_path |
The most recent generated deployment script. |
msm.get_deployment_script_versions |
schema_project_path |
All generated deployment scripts. |
msm.get_sql_content_from_section |
file_path, section_id |
Read one section. |
msm.set_section_sql_content |
file_path, section_id, sql_content |
Write one section. Always edit sections through these two so the banners are never corrupted. |
msm.prepare_release |
version, next_version, schema_project_path, … |
Snapshots the development script and creates an empty update script. |
msm.generate_deployment_script |
version, schema_project_path, overwrite_existing |
Composes the create-or-upgrade artifact. Run after filling the update script. |
msm.deploy_schema |
connection_id, version, schema_project_path, backup, backup_directory |
Applies a version to a live server. Needs an open db.connect connection. |
| Create script | Update script | Contents |
|---|---|---|
| 130 | 230 | Helper routines, names prefixed msm_ |
| 140 | 240 | Non-idempotent: tables, base data — and in an update, all ALTERs, backfills and drops of removed objects |
| 150 | 250 | Idempotent: views, procedures, functions, triggers, events. 250 is not deployed — leave it empty |
| 170 | 270 | Authorization — 170: CREATE ROLE IF NOT EXISTS, GRANT; 270: only REVOKE, DROP ROLE |
| 180 | — | Optional MariaDB REST Service endpoints (CREATE OR REPLACE REST …) |
| 190 | 290 | Removal of the msm_ helpers |
Sections 140, 240, 170, 270 become the body of a stored procedure in the
generated script: plain ;-terminated statements, no DELIMITER, dynamic SQL
for conditional DDL. Sections 130, 150, 180, 230, 190, 290 are emitted at top
level and use DELIMITER %%.
The deployment script runs the target version's 150, 170 and 180 in full on
every deployment, after the table changes, so new and changed views, routines,
roles, grants and endpoints reach upgraded schemas on their own. The update
script only carries what those can't express: table changes and drops (240), and
REVOKE / DROP ROLE (270). Never GRANT in 270 — on an upgrade it runs before
170 creates a new role, and the deployment fails.
See [Tutorial 4]({{ '/tutorials/sandbox-lifecycle/' | relative_url }}).
| Tool | Arguments | Notes |
|---|---|---|
sandbox.list_available_versions |
series |
Versions deploy can be asked for. No argument: the newest patch of each series. series="11.8" or "11": every release below it. Only packages built for this platform are listed, and anything listed can be deployed. |
sandbox.deploy |
port, password, sandbox_dir, allow_root_from, server_id, ssl=False, server_version, mariadbd_path, mariadbd_options, timeout |
Creates and starts an instance, and registers its connection with the MCP server. Resolves a server from the PATH, then already-downloaded versions, then the published index — no MariaDB Server need be installed. server_version accepts 11.8.9, 11.8 or 11, and is refused together with mariadbd_path. |
sandbox.start |
port, sandbox_dir, mariadbd_path, timeout |
Restarts an existing instance with its data intact. |
sandbox.stop |
port, sandbox_dir, password, timeout |
Graceful shutdown. Needs the root password. |
sandbox.kill |
port, sandbox_dir |
Forceful. The fallback when stop will not. |
sandbox.delete |
port, sandbox_dir |
Removes the instance. Refuses a running one — stop or kill first. |
sandbox.vendor |
port, sandbox_dir, mariadbd_path |
MariaDB or MySQL. The sandbox machinery can stand up either. |
sandbox.version |
port, sandbox_dir, mariadbd_path |
The instance's server version. |
Instances live in ~/.mariadb-shell/sandboxes/<port>/ on macOS and Linux, and
%USERPROFILE%\MariaDB\mariadb-shell\sandboxes\<port>\ on Windows. Downloaded
servers live separately, one directory per version, under
~/.local/share/mariadb-sandbox-server/ (%LOCALAPPDATA%\Programs\mariadb-sandbox-server
on Windows). Instances create a root@'%' account and listen on all interfaces,
so they are a development tool and not something to leave running on an untrusted
network.
The shell's dump, load, export, import and copy utilities, as tools. Use them
instead of piping mariadb-dump into another client — the plugins' CLI guard
blocks that and points here. Offered only together with the db.* group, since
every one of them works on a connection from db.connect.
| Tool | Arguments | Notes |
|---|---|---|
util.dump_instance |
connection_id, output_url, options=None |
The whole server. output_url must not exist or be empty. |
util.dump_schemas |
connection_id, schemas, output_url, options=None |
The named schemas. |
util.dump_tables |
connection_id, schema, tables, output_url, options=None |
Tables and views of one schema. tables=[] with {"all": true} dumps every one. |
util.export_table |
connection_id, table, output_url, options=None |
One table's rows to one file. table is t or schema.t. |
util.load_dump |
connection_id, url, options=None |
Loads a dump made by any of the three dump tools. The server needs local_infile on. |
util.import_table |
connection_id, urls, options=None |
A file, or a list of files, into a table that must already exist. Wildcards * and ? work. Needs local_infile. |
util.copy_instance |
connection_id, target_connection_id, options=None |
Dumps from the source and loads into the target at once, no files written. The target must be another server with local_infile on. |
util.copy_schemas |
connection_id, schemas, target_connection_id, options=None |
The same, for the named schemas. |
util.copy_tables |
connection_id, schema, tables, target_connection_id, options=None |
The same, for tables of one schema. {"schema": "other"} loads them into another schema. |
util.get_task |
task_id, since=0, wait_ms=0 |
A task's status, stages, current progress (with percent, throughput, eta_seconds), the messages after since, next_since, and its result or error once it ended. wait_ms (at most 30000) waits for news instead of answering at once. |
util.list_tasks |
— | This client's tasks, without their messages. |
util.cancel_task |
task_id |
Interrupts the utility as Ctrl+C would; the task ends cancelled. |
Every utility runs as a background task. The tool returns a task_id at
once, with status pending or running; follow it with util.get_task,
passing the last next_since back as since to get only new messages, and
wait_ms to avoid a tight polling loop. A task ends completed, failed or
cancelled, and is kept for an hour after that (at most 100 of them). A client
can have at most four tasks running at once — a dump opens a session per
thread.
options takes the utility's own options with their camelCase names —
{"threads": 8}, {"ddlOnly": true}, {"loadUsers": false}. session,
progressCallback and showProgress are set by the tool and refused, and so is
outputUrl for dump_schemas and dump_tables: use output_url.
Local paths in output_url, url and urls, and in file options such as
progressFile, must be on the allowed-paths list. A URL with another scheme
(https://…), or a prefix in an object storage bucket (s3BucketName,
osBucketName, azureContainerName), is not a local path and goes to the
utility unchecked.
The core of the [SQL language server]({{ '/how-it-works/#the-sql-language-server' | relative_url }}),
as tools: they run mariadb-lsp on SQL text with the MariaDB server's own
grammar. Nothing is executed and no connection is needed, so the agent can
check a script before it runs it — and this works in every harness, including
Codex and Pi, which have no language-server support of their own. mariadb-shell
26.10.3 and later.
| Tool | Arguments | Notes |
|---|---|---|
sql.check |
sql or file_path, source_dir=None, sql_mode=None, delimiter=None, version_id=None, max_errors=100 |
valid, statements, and per error its start (line, column), message, the failing token and the tokens the grammar expected there. |
sql.outline |
sql or file_path, source_dir=None, sql_mode=None, delimiter=None, version_id=None |
Applies the CREATE/ALTER/DROP/RENAME/USE statements in order and lists what results: schemas, tables with columns, indexes, keys and checks, views, routines, triggers, events, sequences, REST objects. |
sql.format |
sql or file_path, line_width=80, keyword_case="upper", indent="2", sql_mode=None, delimiter=None, version_id=None |
Returns the laid-out sql; a file is not changed. Statements that don't parse are left as they are, comments kept. |
Pass the SQL inline (sql) or as a .sql file (file_path, on the
allowed-paths list) — exactly one, at most 10 MB. check and outline follow
Schema Management's SOURCE '<path>'[<start>:<end>]; directives, expanded by
the server with the same path checks as db.execute_sql_script, so an error in
an included section is reported in that file, at its line. Lines and columns
count from 1, as an editor shows them.
Optional and not part of the {{ site.tool_count }}. These four tools are registered only when
the migration tooling is installed
(mariadb-shell -- mcp setup --installMigrator, then restart the server). A
server with no install advertises none of them, rather than four tools whose
every call would fail. Linux and macOS only. See
[Tutorial 9]({{ '/tutorials/mysql-to-mariadb-migration/' | relative_url }}).
| Tool | Arguments | Notes |
|---|---|---|
migrator.set_config |
mode, env, merge=False |
Writes config/migration.yaml. Only configured connections may be named; passwords are refused. |
migrator.plan |
mode, out=None, timeout=3600 |
Resolves the step list and validates the config. Executes nothing. |
migrator.run |
mode, out=None, timeout=3600 |
Performs the migration. Omit out on a new run. |
migrator.resume |
mode, out, timeout=3600 |
Continues a failed run from its state.json. out is required here. |
| Message | Cause | Fix |
|---|---|---|
| not a configured connection | The URI is not on the allow-list, or asks for more than was configured (a schema, an option). | mariadb-shell -- mcp setup, or drop the extra part from the URI. |
| A call that never returns | A path is not on the allowed-paths list, and the guard fell back to a prompt nothing can answer. | Add the directory with mcp setup. |
| There is no object registered under name 'mcp' | The shell cannot find its plugins — usually a relocated or broken config home. | Check ~/.mariadb-shell/plugins/. |
No sql.* tools at all |
The server found no mariadb-lsp, runs in multi-tenant mode, or is older than 26.10.3. |
Use a shell from the release packages, or point mcp setup --lspPath at a mariadb-lsp. |
No util.* tools at all |
The server does not serve the db.* group, or runs in multi-tenant mode. |
Serve db too; a multi-tenant server never offers them. |
| The MariaDB Shell binary to run the utility in was not found | A util.* tool could not find mariadb-shell to run the task in. |
Put mariadb-shell on the PATH. |
| Already 4 tasks are running | The client's limit of running util.* tasks. |
Wait for one with util.get_task, or util.cancel_task one. |
A load or copy fails on local_infile |
The target server has local_infile off. |
SET GLOBAL local_infile = ON on the target. |
No migrator.* tools at all |
The migration tooling is not installed, or the server has not been restarted since it was. | mcp setup --installMigrator, then restart. |
| No module named 'pywintypes' (Windows) | The Windows shell packages do not yet bundle pywin32. | pip install pywin32 into the shell's bundled Python. |