Tool: execute_sql
Execute any valid SQL statement, including data definition language (DDL), data control language (DCL), data query language (DQL), or data manipulation language (DML) statements, on a Cloud SQL for MySQL, Cloud SQL for PostgreSQL, or Cloud SQL for SQL Server instance.
To support the execute_sql tool, a Cloud SQL instance and request must meet the following requirements:
- The value of
data_api_accessmust be set toALLOW_DATA_API. - For PostgreSQL and SQL Server instances, the
databasefield is required. For MySQL instances, thedatabasefield is optional. For built-in database users (supported for MySQL, PostgreSQL, and SQL Server, and required for SQL Server because Cloud SQL for SQL Server doesn't support IAM database authentication):
- Specify the
userfield and thepassword_secret_versionfield. - The value of
password_secret_versionmust be the resource name of a regional secret version in Secret Manager stored in the same region as the Cloud SQL instance, such asprojects/12345/locations/us-central1/secrets/my-password-secret/versions/1orprojects/12345/locations/us-central1/secrets/my-password-secret/versions/latest. - The caller must have the
secretmanager.secretVersions.accesspermission on the secret version.
- Specify the
For IAM database authentication (supported for MySQL and PostgreSQL only; not supported for SQL Server):
- For a MySQL instance, the database flag
cloudsql_iam_authenticationmust be set toon. - For a PostgreSQL instance, the database flag
cloudsql.iam_authenticationmust be set toon. - An IAM user account or IAM service account (
CLOUD_IAM_USERorCLOUD_IAM_SERVICE_ACCOUNT) must exist on the instance. After you use thecreate_instancetool to create a MySQL or PostgreSQL instance, you can use thecreate_usertool to create an IAM user account for the user currently logged in to the project.
- For a MySQL instance, the database flag
The execute_sql tool has the following limitations:
- If a SQL statement returns a response larger than 10 MB, then the response will be truncated.
- The
execute_sqltool has a default timeout of 30 seconds. If a query runs longer than 30 seconds, then the tool returns aDEADLINE_EXCEEDEDerror.
If you receive errors similar to "IAM authentication is not enabled for the instance" on a MySQL or PostgreSQL instance, then you can use the get_instance tool to check the value of the IAM database authentication flag for the instance.
If you receive errors like "The instance doesn't allow using executeSql to access this instance", then you can use the get_instance tool to check the data_api_access setting.
When you receive authentication errors for a built-in database user (including all SQL Server requests):
- Check if the specified database user exists on the instance using the
list_userstool. - Verify that
password_secret_versionreferences a valid regional Secret Manager secret version in the same region as the Cloud SQL instance and that the caller has thesecretmanager.secretVersions.accesspermission on the secret version. - Check if the caller has the
cloudsql.instances.executeSqlIAM permission on the project (included in roles such as Cloud SQL Instance User (roles/cloudsql.instanceUser) or Cloud SQL Admin (roles/cloudsql.admin)).
When you receive authentication errors for IAM database authentication (MySQL and PostgreSQL only):
- Check if the currently logged-in user account exists as an IAM user on the instance using the
list_userstool. - If the IAM user account doesn't exist, then use the
create_usertool to create the IAM user account for the logged-in user. - If the currently logged-in user doesn't have the proper database user roles, then you can use the
update_usertool to grant database roles to the user. For example, thecloudsqlsuperuserrole can provide an IAM user with many required permissions. Check if the currently logged-in user has the correct IAM permissions assigned for the project. You can use the
gcloud projects get-iam-policy [PROJECT_ID]command to check if the user has the proper IAM roles or permissions assigned for the project.- The user must have
cloudsql.instances.loginpermission to do automatic IAM database authentication. - The user must have
cloudsql.instances.executeSqlpermission to execute SQL statements using theexecute_sqltool orexecuteSqlAPI. - Common IAM roles that contain the required permissions: Cloud SQL Instance User (
roles/cloudsql.instanceUser) or Cloud SQL Admin (roles/cloudsql.admin).
- The user must have
When receiving an ExecuteSqlResponse, always check the message and status fields within the response body. A successful HTTP status code doesn't guarantee full success of all SQL statements. The message and status fields will indicate if there were any partial errors or warnings during SQL statement execution.
The following code sample shows how to use curl to call the execute_sql MCP tool.
| Curl Request |
|---|
curl --location 'https://sqladmin.googleapis.com/mcp' \ --header 'content-type: application/json' \ --header 'accept: application/json, text/event-stream' \ --data '{ "method": "tools/call", "params": { "name": "execute_sql", "arguments": { // Provide these details according to the MCP tool specification. } }, "jsonrpc": "2.0", "id": 1 }' |
Input Schema
Instance execute sql request for MCP.
SqlInstancesExecuteSqlMcpRequest
| JSON representation |
|---|
{ "instance": string, "project": string, "sqlStatement": string, "database": string, "user": string, "passwordSecretVersion": string, "sqlCommenterEnabled": boolean } |
| Fields | |
|---|---|
instance |
Required. Database instance ID. This does not include the project ID. |
project |
Required. Project ID of the project that contains the instance. |
sqlStatement |
Required. SQL statements to run on the database. It can be a single statement or a sequence of statements separated by semicolons. |
database |
Optional. Name of the database on which the statement will be executed. For Postgres and SQL Server it's required, for MySQL it's optional. For Postgres, if your query is not scoped to an existing database, like list databases / create new database / grant roles, you can pass in default value as |
user |
Optional. The name of an existing database user to connect to the database. This field is used together with the |
passwordSecretVersion |
Optional. The resource name of the Secret Manager secret holding the password for the user to log into the database. The secret should be created using the regional endpoint (for API) or from the Regional Secrets page (for UI), and stored in the same region as the Cloud SQL instance. The expected resource name format is |
sqlCommenterEnabled |
Optional. If set to true, enables sqlcommenter-style tagging. Automatically collects and populates mcp.server, mcp.tool, mcp.client, and user.identity. See https://google.github.io/sqlcommenter/ for detail about sqlcommenter. |
Output Schema
SqlInstancesExecuteSqlResponse
| JSON representation |
|---|
{ "messages": [ { object ( |
| Fields | |
|---|---|
messages[] |
A list of notices and warnings generated during query execution. For PostgreSQL, this includes all notices and warnings. For MySQL, this includes warnings generated by the last executed statement. To retrieve all warnings for a multi-statement query, |
metadata |
The additional metadata information regarding the execution of the SQL statements. |
results[] |
The list of results after executing all the SQL statements. |
status |
Contains the error from the database if the SQL execution failed. |
Message
| JSON representation |
|---|
{ // Union field |
| Fields | |
|---|---|
Union field
|
|
message |
The full message string. For PostgreSQL, this is a formatted string that may include severity, code, and the notice/warning message. For MySQL, this contains the warning message. |
Union field
|
|
severity |
The severity of the message (e.g., "NOTICE" for PostgreSQL, "WARNING" for MySQL). |
Metadata
| JSON representation |
|---|
{ "sqlStatementExecutionTime": string } |
| Fields | |
|---|---|
sqlStatementExecutionTime |
The time taken to execute the SQL statements. A duration in seconds with up to nine fractional digits, ending with ' |
Duration
| JSON representation |
|---|
{ "seconds": string, "nanos": integer } |
| Fields | |
|---|---|
seconds |
Signed seconds of the span of time. Must be from -315,576,000,000 to +315,576,000,000 inclusive. Note: these bounds are computed from: 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years |
nanos |
Signed fractions of a second at nanosecond resolution of the span of time. Durations less than one second are represented with a 0 |
QueryResult
| JSON representation |
|---|
{ "columns": [ { object ( |
| Fields | |
|---|---|
columns[] |
List of columns included in the result. This also includes the data type of the column. |
rows[] |
Rows returned by the SQL statement. |
message |
Message related to the SQL execution result. |
partialResult |
Set to true if the SQL execution's result is truncated due to size limits or an error retrieving results. |
status |
If results were truncated due to an error, details of that error. |
Column
| JSON representation |
|---|
{ "name": string, "type": string } |
| Fields | |
|---|---|
name |
Name of the column. |
type |
Datatype of the column. |
Row
| JSON representation |
|---|
{
"values": [
{
object ( |
| Fields | |
|---|---|
values[] |
The values for the row. |
Value
| JSON representation |
|---|
{ "value": string, "nullValue": boolean } |
| Fields | |
|---|---|
value |
The cell value in string format. |
nullValue |
If cell value is null, then this flag will be set to true. |
Status
| JSON representation |
|---|
{ "code": integer, "message": string, "details": [ { "@type": string, field1: ..., ... } ] } |
| Fields | |
|---|---|
code |
The status code, which should be an enum value of |
message |
A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the |
details[] |
A list of messages that carry the error details. There is a common set of message types for APIs to use. An object containing fields of an arbitrary type. An additional field |
Any
| JSON representation |
|---|
{ "typeUrl": string, "value": string } |
| Fields | |
|---|---|
typeUrl |
Identifies the type of the serialized Protobuf message with a URI reference consisting of a prefix ending in a slash and the fully-qualified type name. Example: type.googleapis.com/google.protobuf.StringValue This string must contain at least one The prefix is arbitrary and Protobuf implementations are expected to simply strip off everything up to and including the last All type URL strings must be legal URI references with the additional restriction (for the text format) that the content of the reference must consist only of alphanumeric characters, percent-encoded escapes, and characters in the following set (not including the outer backticks): In the original design of |
value |
Holds a Protobuf serialization of the type described by type_url. A base64-encoded string. |
Tool Annotations
Tool annotations are sent to MCP clients to describe the basic risk of a given tool. Most clients treat these hints as untrusted, but they can be used to decide when a confirmation prompt might be sent to a user.
Along with the title string, the following boolean hints are defined as follows:
readOnlyHint: If true, the tool doesn't modify its environment. Default: false.destructiveHint: If true, then the tool can perform destructive actions. If false, then the tool can only perform additive actions. Default: true.idempotentHint: If true, then calling the tool repeatedly with the same arguments will have no additional effect on its environment. Default: false.openWorldHint: If true, then the tool can interact with an 'open world' of external entities. If false, then the tool can only interact with internal entities. For example, a web search tool would be open world, while a memory tool would not be open world.
Destructive Hint: ✅ | Idempotent Hint: ❌ | Read Only Hint: ❌ | Open World Hint: ❌