-
Notifications
You must be signed in to change notification settings - Fork 1.5k
feat(tool/postgres): add postgres-execute-sql-many and postgres-sql-many
#3083
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
3cd7a0e
c79c161
8001227
1b94444
f3ac22a
af168c1
f3d09a4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| --- | ||
| title: "postgres-execute-sql-many" | ||
| type: docs | ||
| weight: 1 | ||
| description: > | ||
| A "postgres-execute-sql-many" tool executes a SQL statement against a specific Cloud SQL Postgres instance provided at runtime. | ||
| --- | ||
|
|
||
| ## About | ||
|
|
||
| A `postgres-execute-sql-many` tool executes a SQL statement against a specific Cloud SQL Postgres instance identified by project, instance, and database parameters provided at runtime. | ||
|
|
||
| This tool is useful for executing arbitrary SQL queries across multiple database instances without needing to configure a separate tool for each instance. | ||
|
|
||
| > **Note:** This tool is intended for developer assistant workflows with human-in-the-loop and shouldn't be used for production agents. | ||
|
|
||
| ## Compatible Sources | ||
|
|
||
| {{< compatible-sources others="integrations/cloud-sql-admin" >}} | ||
|
|
||
| ## Parameters | ||
|
|
||
| The following parameters are required at runtime when invoking the tool: | ||
|
|
||
| | **Parameter** | **Type** | **Description** | | ||
| | :------------ | :------- | :---------------------------- | | ||
| | `project` | string | The GCP project ID. | | ||
| | `instance` | string | The Cloud SQL instance ID. | | ||
| | `database` | string | The database name. | | ||
| | `sql` | string | The SQL statement to execute. | | ||
|
|
||
| ## Example | ||
|
|
||
| ```yaml | ||
| kind: tool | ||
| name: execute_sql_many_tool | ||
| type: postgres-execute-sql-many | ||
| source: my-cloud-sql-admin-source | ||
| description: Use this tool to execute sql statement on a specific instance. | ||
| ``` | ||
|
|
||
| ## Reference | ||
|
|
||
| | **field** | **type** | **required** | **description** | | ||
| | :---------- | :------- | :----------- | :------------------------------------------------- | | ||
| | type | string | true | Must be "postgres-execute-sql-many". | | ||
| | source | string | true | Name of the `cloud-sql-admin` source. | | ||
| | description | string | true | Description of the tool that is passed to the LLM. | | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| --- | ||
| title: "postgres-sql-many" | ||
|
duwenxin99 marked this conversation as resolved.
|
||
| type: docs | ||
| weight: 1 | ||
| description: > | ||
| A "postgres-sql-many" tool executes a predefined SQL statement against a specific Cloud SQL Postgres instance provided at runtime. | ||
| --- | ||
|
|
||
| ## About | ||
|
|
||
| A `postgres-sql-many` tool executes a predefined SQL statement against a specific Cloud SQL Postgres instance identified by project, instance, and database parameters provided at runtime. | ||
|
|
||
| It supports `templateParameters` to allow dynamic values to be injected into the query at runtime. | ||
|
|
||
| > **Note:** This tool is intended for developer assistant workflows with human-in-the-loop and shouldn't be used for production agents. | ||
|
|
||
| ## Compatible Sources | ||
|
|
||
| {{< compatible-sources others="integrations/cloud-sql-admin" >}} | ||
|
|
||
| ## Parameters | ||
|
|
||
| The following parameters are required at runtime when invoking the tool: | ||
|
|
||
| | **Parameter** | **Type** | **Description** | | ||
| | :------------ | :------- | :------------------------- | | ||
| | `project` | string | The GCP project ID. | | ||
| | `instance` | string | The Cloud SQL instance ID. | | ||
| | `database` | string | The database name. | | ||
|
|
||
| Additional parameters may be required based on the `templateParameters` configured in the tool definition. | ||
|
|
||
| ## Example | ||
|
|
||
| ```yaml | ||
| kind: tool | ||
| name: get_user_many_tool | ||
| type: postgres-sql-many | ||
| source: my-cloud-sql-admin-source | ||
| description: Use this tool to get user details from a specific instance. | ||
| statement: SELECT * FROM users WHERE id = {{.user_id}} | ||
| templateParameters: | ||
| - name: user_id | ||
| type: string | ||
| description: The ID of the user. | ||
| ``` | ||
|
|
||
| ## Reference | ||
|
|
||
| | **field** | **type** | **required** | **description** | | ||
| | :----------------- | :------- | :----------- | :------------------------------------------------- | | ||
| | type | string | true | Must be "postgres-sql-many". | | ||
| | source | string | true | Name of the `cloud-sql-admin` source. | | ||
| | description | string | true | Description of the tool that is passed to the LLM. | | ||
| | statement | string | true | The SQL statement template to execute. | | ||
| | templateParameters | list | false | List of parameters used in the statement template. | | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove this change for now as of right now we need more guidnace to use this correctly |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These tools won't be generic postgres so we should move them to a different tool source directory |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,164 @@ | ||
| // Copyright 2026 Google LLC | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| package postgresexecutesqlmany | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
| "net/http" | ||
|
|
||
| yaml "github.com/goccy/go-yaml" | ||
| "github.com/googleapis/mcp-toolbox/internal/embeddingmodels" | ||
| "github.com/googleapis/mcp-toolbox/internal/sources" | ||
| "github.com/googleapis/mcp-toolbox/internal/tools" | ||
| "github.com/googleapis/mcp-toolbox/internal/util" | ||
| "github.com/googleapis/mcp-toolbox/internal/util/parameters" | ||
| ) | ||
|
|
||
| const resourceType string = "postgres-execute-sql-many" | ||
|
|
||
| func init() { | ||
| if !tools.Register(resourceType, newConfig) { | ||
| panic(fmt.Sprintf("tool type %q already registered", resourceType)) | ||
| } | ||
| } | ||
|
|
||
| func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.ToolConfig, error) { | ||
| actual := Config{Name: name} | ||
| if err := decoder.DecodeContext(ctx, &actual); err != nil { | ||
| return nil, err | ||
| } | ||
| return actual, nil | ||
| } | ||
|
|
||
| type compatibleSource interface { | ||
| ExecuteSql(ctx context.Context, project, instance, database, sql string, accessToken string) (any, error) | ||
| UseClientAuthorization() bool | ||
| } | ||
|
|
||
| type Config struct { | ||
| Name string `yaml:"name" validate:"required"` | ||
| Type string `yaml:"type" validate:"required"` | ||
| Source string `yaml:"source" validate:"required"` | ||
| Description string `yaml:"description"` | ||
| AuthRequired []string `yaml:"authRequired"` | ||
| Annotations *tools.ToolAnnotations `yaml:"annotations,omitempty"` | ||
| } | ||
|
|
||
| var _ tools.ToolConfig = Config{} | ||
|
|
||
| func (cfg Config) ToolConfigType() string { | ||
| return resourceType | ||
| } | ||
|
|
||
| // Initialize creates a new Postgres ExecuteSqlMany tool. | ||
| func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { | ||
| params := parameters.Parameters{ | ||
| parameters.NewStringParameter("project", "The GCP project ID."), | ||
| parameters.NewStringParameter("instance", "The Cloud SQL instance ID."), | ||
| parameters.NewStringParameter("database", "The database name."), | ||
| parameters.NewStringParameter("sql", "The SQL statement to execute."), | ||
|
duwenxin99 marked this conversation as resolved.
|
||
| } | ||
|
|
||
| description := cfg.Description | ||
| if description == "" { | ||
| description = "Executes multiple SQL statements on a Postgres database." | ||
| } | ||
|
|
||
| annotations := tools.GetAnnotationsOrDefault(cfg.Annotations, tools.NewDestructiveAnnotations) | ||
| mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, params, annotations) | ||
|
|
||
| t := Tool{ | ||
| Config: cfg, | ||
| Parameters: params, | ||
| manifest: tools.Manifest{Description: description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired}, | ||
| mcpManifest: mcpManifest, | ||
| } | ||
| return t, nil | ||
| } | ||
|
|
||
| var _ tools.Tool = Tool{} | ||
|
|
||
| type Tool struct { | ||
| Config | ||
| Parameters parameters.Parameters `yaml:"parameters"` | ||
| manifest tools.Manifest | ||
| mcpManifest tools.McpManifest | ||
| } | ||
|
|
||
| // Invoke executes the SQL statement on the given database. | ||
| func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, util.ToolboxError) { | ||
| // Check source compatibility | ||
| source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) | ||
| if err != nil { | ||
| return nil, util.NewClientServerError("source used is not compatible with the tool", http.StatusInternalServerError, err) | ||
| } | ||
|
|
||
| // Extract parameters from the parameter values map. | ||
| paramsMap := params.AsMap() | ||
| project, _ := paramsMap["project"].(string) | ||
| instance, _ := paramsMap["instance"].(string) | ||
| database, _ := paramsMap["database"].(string) | ||
| sql, _ := paramsMap["sql"].(string) | ||
|
|
||
| logger, err := util.LoggerFromContext(ctx) | ||
| if err != nil { | ||
| return nil, util.NewClientServerError("error getting logger", http.StatusInternalServerError, err) | ||
| } | ||
| logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query on %s/%s/%s", resourceType, project, instance, database)) | ||
|
|
||
| // Execute the SQL statement on the given database. | ||
| resp, err := source.ExecuteSql(ctx, project, instance, database, sql, string(accessToken)) | ||
| if err != nil { | ||
| return nil, util.ProcessGcpError(err) | ||
| } | ||
| return resp, nil | ||
| } | ||
|
|
||
| func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { | ||
| return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) | ||
| } | ||
|
|
||
| func (t Tool) Manifest() tools.Manifest { | ||
| return t.manifest | ||
| } | ||
|
|
||
| func (t Tool) McpManifest() tools.McpManifest { | ||
| return t.mcpManifest | ||
| } | ||
|
|
||
| func (t Tool) Authorized(verifiedAuthServices []string) bool { | ||
| return tools.IsAuthorized(t.AuthRequired, verifiedAuthServices) | ||
| } | ||
|
|
||
| func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { | ||
| source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) | ||
| if err != nil { | ||
| return false, err | ||
| } | ||
| return source.UseClientAuthorization(), nil | ||
| } | ||
|
|
||
| func (t Tool) ToConfig() tools.ToolConfig { | ||
| return t.Config | ||
| } | ||
|
|
||
| func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { | ||
| return "Authorization", nil | ||
| } | ||
|
|
||
| func (t Tool) GetParameters() parameters.Parameters { | ||
| return t.Parameters | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.