MCP tool reference
The 24 tools an AI app sees after it connects, in the server's own words.
Every tool takes a connection: its id or its name, as list_connections returns them. Only connections whose AI level isn’t Off are listed. Hidden columns are left out of everything a tool returns.
Write tools follow the connection’s AI level: refused on Read-only, staged for your approval on Ask before write, run at once on Full. Destructive or unrecognised statements wait for approval at every level, with a backup first (BigQuery relies on its time travel instead). delete_rows counts as an ordinary write here: on Full it runs at once, and only BigQuery stages it. A staged change returns a change_id; follow it with the tools under Follow a change.
All tools
| Tool | Kind | Waits for approval |
|---|---|---|
list_connections | Read | No |
list_schemas | Read | No |
list_tables | Read | No |
describe_table | Read | No |
get_ddl | Read | No |
search_schema | Read | No |
search_values | Read | No |
sample_rows | Read | No |
run_query | Read | No |
explain_query | Read | No |
estimate_query_cost | Read | No |
execute_sql | Write | Per level |
insert_rows | Write | Per level |
update_rows | Write | Per level |
delete_rows | Write | Per level |
drop_object | Destructive | Always |
truncate_table | Destructive | Always |
wp_site_info | Read | No |
wp_get_option | Read | No |
wp_update_option | Write | Per level |
wp_search_replace | Destructive | dry_run false |
list_pending_changes | Read | No |
get_change_status | Read | No |
wait_for_change | Read | No |
Explore
list_connections
Connections Gadwal lets you use, with each one's AI level (what you may do there).
No parameters.
list_schemas
Schemas in a connection.
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
list_tables
Tables and views, optionally in one schema.
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
schema | string | Schema (default: public on Postgres, main on SQLite). |
describe_table
Columns (type, nullability, default, key, references), indexes, constraints and a row estimate. Columns hidden from AI are left out.
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
table required | string | Table or view name. |
schema | string | Schema (default: public on Postgres, main on SQLite). |
get_ddl
The CREATE statement for a table or view (hidden column names masked).
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
table required | string | Table or view name. |
schema | string | Schema (default: public on Postgres, main on SQLite). |
search_schema
Tables and columns whose names contain the text.
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
query required | string | Part of a table or column name. |
search_values
Find a value in every text column of every table in a schema (first 100,000 rows per table, up to 20 matches each).
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
text required | string | The value to find. |
schema | string | Schema (default: public on Postgres, main on SQLite). |
Read data
Reads run one statement in a read-only transaction and stop after 30 seconds. Results are capped at the Rows returned to AI setting (200 by default), 2 KB per cell and 256 KB per answer.
sample_rows
Rows of a table (visible columns), optionally filtered by a WHERE condition.
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
table required | string | Table or view name. |
limit | integer | Rows (default 20). |
schema | string | Schema (default: public on Postgres, main on SQLite). |
where | string | Optional SQL condition, without the WHERE keyword. |
run_query
One read-only SQL statement (SELECT, WITH, VALUES, SHOW, EXPLAIN), run in a read-only transaction. Results are capped; for changes use execute_sql.
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
sql required | string | One statement. |
explain_query
The query plan of one statement (it is not run). On BigQuery: the dry run's estimate.
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
sql required | string | One statement, without EXPLAIN. |
estimate_query_cost
BigQuery: the dry run's bytes processed and whether that is over the connection's cost limit (nothing runs or is billed). Other engines: the planner's plan, as explain_query.
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
sql required | string | One statement, without EXPLAIN. |
Change data
insert_rows, update_rows and delete_rows take structured values and address rows by primary key (up to 1,000 rows per call). Gadwal writes the SQL and shows it in Review. When it waits for approval, Gadwal checks each row again before it runs (except on BigQuery, where reading them would be a billed query): if one changed since the AI proposed the edit, nothing is applied. On Full, a write the AI runs itself gets 30 seconds, then it’s stopped and rolled back.
execute_sql
One SQL statement that changes data or schema. Depending on the connection's AI level it runs at once, waits for the user's approval (you get a change id), or is refused. Destructive statements always wait for approval and get a backup first.
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
sql required | string | One statement. |
insert_rows
Insert rows (same rules as execute_sql).
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
rows required | array of objects | One object per row: column → value (null for NULL). |
table required | string | Table or view name. |
schema | string | Schema (default: public on Postgres, main on SQLite). |
update_rows
Set column values on rows addressed by primary key (same rules as execute_sql).
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
keys required | array of objects | One object per row: primary-key column → value. |
table required | string | Table or view name. |
values required | object | Column → new value for every addressed row. |
schema | string | Schema (default: public on Postgres, main on SQLite). |
delete_rows
Delete rows addressed by primary key (same rules as execute_sql).
On Full, delete_rows runs at once; only BigQuery stages it.
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
keys required | array of objects | One object per row: primary-key column → value. |
table required | string | Table or view name. |
schema | string | Schema (default: public on Postgres, main on SQLite). |
drop_object
Drop a table or view. Always waits for the user's approval, with a backup first.
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
table required | string | Table or view name. |
kind | string | table or view |
schema | string | Schema (default: public on Postgres, main on SQLite). |
truncate_table
Remove every row. Always waits for the user's approval, with a backup first.
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
table required | string | Table or view name. |
schema | string | Schema (default: public on Postgres, main on SQLite). |
WordPress
For MySQL and MariaDB connections that hold a WordPress install. See WordPress mode.
wp_site_info
The WordPress installs in a MySQL / MariaDB connection: table prefix, siteurl and home, WordPress version, active plugins and, for multisite, its blogs.
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
schema | string | Database (default: the connection's). |
wp_get_option
One option from <prefix>options. Serialized PHP is unserialized into value (JSON: lists as arrays, other arrays and objects as objects, objects with __class); raw is the stored text.
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
name required | string | Option name, e.g. siteurl or theme_mods_twentytwentyfive. |
blog | integer | Multisite: the blog id (default 1, the main site). |
prefix | string | Table prefix of the install (wp_ …), from wp_site_info; needed when the database holds several. |
schema | string | Database (default: the connection's). |
wp_update_option
Change one existing option. Pass value as JSON: when the option is serialized it is re-serialized with correct byte lengths (keys keep their order); otherwise arrays and objects are serialized and scalars stored as text, as update_option() does. Or pass raw, the exact text. Same rules as update_rows, with a backup of the options table first. An option whose serialized data doesn't parse is refused unless force is true.
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
name required | string | Option name. |
blog | integer | Multisite: the blog id (default 1, the main site). |
force | boolean | Overwrite a value whose serialized data doesn't parse. |
prefix | string | Table prefix of the install (wp_ …), from wp_site_info; needed when the database holds several. |
raw | string | The exact text to store, instead of value. |
schema | string | Database (default: the connection's). |
value | any JSON | The new value as JSON. |
wp_search_replace
Serialized-aware search & replace over a WordPress install (domain moves, http → https). dry_run (default true) only counts, per table and column, with samples. dry_run false always waits for the user's approval, whatever the AI level; on approval each table is backed up, then changed in one transaction. Post GUIDs, tables without a key and tables that can't roll back (MyISAM) are skipped unless asked.
| Parameter | Type | Description |
|---|---|---|
connection required | string | Connection id or name, from list_connections. |
replace required | string | Replacement text (may be empty). |
search required | string | Text to find (case-sensitive unless case_insensitive). |
all_tables | boolean | Every table of the database, not just the install's prefix. |
allow_non_transactional | boolean | Also change MyISAM/Aria tables, which can't roll back. |
case_insensitive | boolean | Match ASCII letters in any case. |
dry_run | boolean | Default true: count only. false proposes the change for approval. |
include_guid | boolean | Also change posts' guid (WordPress advises against it). |
prefix | string | Table prefix of the install (wp_ …), from wp_site_info; needed when the database holds several. |
schema | string | Database (default: the connection's). |
Follow a change
An AI app only sees its own changes. See How AI review works for the statuses.
list_pending_changes
Your changes that are waiting for the user, or were decided recently.
No parameters.
get_change_status
Where one of your changes stands: pending, approved, applied, rejected (with the user's reason), expired or failed.
| Parameter | Type | Description |
|---|---|---|
change_id required | string | From execute_sql and the other write tools. |
wait_for_change
Wait until the user decides on one of your changes (up to timeout_seconds, default 55, max 120).
| Parameter | Type | Description |
|---|---|---|
change_id required | string | From execute_sql and the other write tools. |
timeout_seconds | integer | Default 55, at most 120. |
Resources and prompts
Clients that support MCP resources can read gadwal://<connection>/schema (tables and their visible columns) and gadwal://<connection>/table/<name> (one table, as describe_table). Two prompts are offered:
explore-database(connection): Look around a connection and explain what it holds.write-migration(connection, goal): Propose a schema change as SQL for the user to review.