support both generic and typed map. Config example:
```
parameters:
- name: user_scores
type: map
description: A map of user IDs to their scores. All scores must be integers.
valueType: integer # This enforces the value type for all entries. Leave it blank for generic map
```
Represented as `Object` with `additionalProperties` in manifests.
Added a util function to convert json.Number (string type) to int/float
types to address the problem where int/float values are converted to
strings for the generic map.
- Added a dry run step to identify the query type (e.g., SELECT, DML),
which allows the tool to correctly handle the query's output.
- The recommended high-level client, cloud.google.com/go/bigquery, does
not expose the statement type from a dry run. To circumvent this
limitation, the low-level BigQuery REST API client
(google.golang.org/api/bigquery/v2) was added to gain access to these
necessary details.
fixes: #915
---------
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
Firestore is a NoSQL document database built for automatic scaling, high
performance, and ease of application development. It's a fully managed,
serverless database that supports mobile, web, and server development.
This change adds Firestore as a source in toolbox
This PR consist of two fixes:
1. Added `default` to table_names parameter since the default value is
an empty string.
2. Update the sql statement for reusing parameter within the statement.
Fixes partial #877
Update `tool.Invoke()` to return type `any` instead of `[]any`.
Toolbox return a map with the `results` key, and the SDK reads the
string from the key. So this won't break existing SDK implementation.
Fixes#870
`
tools:
wait_for_tool:
kind: wait-for
description: "Tool puts chat to sleep for given timeout example 3m,10s,
5m etc. For tasks such as cluster creation no need to wait. It takes
longer time such as 8m for instance creation. Use timeout value as
default if nothing is provided"
timeout: 10s
`
Output:
`
prernakakkar@prernakakkar:~/senseai/genai-toolbox$ curl -X POST -H
"Content-Type: application/json" -d '{"duration": "5m"}'
http://127.0.0.1:5000/api/tool/wa
it_for_tool/invoke
{"result":"[\"Wait for 5m0s completed successfully.\"]"}
`
This PR add supports to MCP version 2025-06-18 defined
[here](https://modelcontextprotocol.io/specification/2025-06-18).
The main updates includes:
* Retrieving protocol version from header via `MCP-Protocol-Version`.
* Throwing `400 Bad Request` when an invalid version is received.
Added an option for user to indicate if the parameter is required.
Example:
```
parameters:
- name: foo
type: string
description: foo
required: false
```
If the `required` field is not provided, it will be defaulted to `true`.
If a `default` value is provided, `required = false` regardless if the
field is indicated.
```
parameters:
- name: foo
type: string
description: foo
default: hello world
```
Fixes#736
## Summary
- Added configurable query timeout to MySQL source configuration
- Updated connection DSN to include readTimeout parameter
- Added documentation and example usage
- Added test coverage for queryTimeout configuration
## Test plan
- [x] Added unit test for queryTimeout configuration parsing
- [x] Updated documentation with queryTimeout field description
- [x] Verified timeout parameter is correctly added to DSN when
specified
## Caveat
When queryTimeout is exceeded, we get an obscure error message
([screenshot](https://github.com/user-attachments/assets/fd292f91-328d-4ebc-9a87-2d92e9887300)):
```
unable to execute query: invalid connection
```
This seems to be a problem with the mysql-go library:
https://stackoverflow.com/q/65253798/10720618
I tried to use
[MAX_EXECUTION_TIME](https://dev.mysql.com/doc/refman/8.0/en/optimizer-hints.html#optimizer-hints-execution-time)
but it didn't work as expected (my `sleep(MAX_EXECUTION_TIME+3)` query
finished successfully after MAX_EXECUTION_TIME milliseconds)
Any ideas on what can be done here? The error message is very
misleading. My goal with adding timeouts is to communicate to the LLM
when it has issued a slow query and force it to adjust (e.g. query
indexes and write a more optimized query) but this defeats the purpose.
---------
Co-authored-by: Wenxin Du <117315983+duwenxin99@users.noreply.github.com>
- Spanner: convert array to typed before querying, as Spanner does not
accept non-typed array []any
- BigQuery: fix https://github.com/googleapis/genai-toolbox/issues/793
- Bigtable: add the required `ElemType` for array-type params
- Redis/Valkey: change indexing to append to avoid extra spaces
Add integration tests for array parameters, skipped for the sources not
supporting arrays:
- SQLite
- Cloud SQL MSSQL
- Cloud SQL MySQL
- MSSQL
- MySQL
Allow Toolbox server to automatically update when users modify their
tool configuration file(s), instead of requiring a restart.
This feature is automatically enabled, but can be turned off with the
flag `--disable-reload`.
Optional projectID parameter enables dynamic, cross-project resource
access in BigQuery tools.
This allows a single tool configuration to target different projects at
runtime, rather than being fixed to the project in its source
configuration.
---------
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
Co-authored-by: Wenxin Du <117315983+duwenxin99@users.noreply.github.com>
When go-yaml decode into CommonParameter with Default being an any type,
int will be converted into []uint64.
It will fail the Parse() when the value is being used since it does not
belong to either of the int types.
Unmarshal `default` value into each field's type directly.
Fixes#771
Copy fix from #757.
The Invoke function had two bugs:
A panic would occur when scanning a row containing a NULL value in a
TEXT or VARCHAR column. The code did not check for nil before attempting
a type assertion on the scanned value.
The *sql.Rows result was not being closed on all code paths, leading to
connection leaks that could exhaust the database connection pool.
This change corrects both issues. A guard clause now checks for nil
values before processing, and rows.Close() is deferred to guarantee the
connection is released.
The Invoke function had two bugs:
1. A panic would occur when scanning a row containing a NULL value in a
TEXT or VARCHAR column. The code did not check for nil before attempting
a type assertion on the scanned value.
2. The *sql.Rows result was not being closed on all code paths, leading
to connection leaks that could exhaust the database connection pool.
This change corrects both issues. A guard clause now checks for nil
values before processing, and rows.Close() is deferred to guarantee the
connection is released.
Co-authored-by: Yuan <45984206+Yuan325@users.noreply.github.com>
This feature includes the following:
* Implement initialize lifecycle (including version negotiation)
* Add the v20250326 schema
* Supporting the `DELETE` and `GET` endpoint for MCP.
* Supporting streamable HTTP (without SSE).
* Terminating sessions after timeout (default = 10 minutes from last
active).
* Toolbox do not support batch request. Will response with `Invalid
requests` if batch requests is received.
Add a `default` field to parameters, that enables users to specify a
default value.
e.g.
```
parameters:
- name: name
type: string
default: "some-default-value"
description: The name of the hotel.
```
if this parameter is invoked without specifying `name`, the parameter
would default to "some-default-value"
For parameter manifest, there will be an additional `Required` field.
The default `Required` field is true. If a `default` value is presented,
`Required: false`. Array parameter's item's `Required` field will
inherit the array's `Required` field.
Fixes#475
Add templateParameters to support non-filter parameters and DDL
statements.
Added a new argument `ignoreInsert` at integration test. Bigtable only
allow `SELECT` statement. This is used to filter insert statement for
bigtable.
Part of #535
Add `templateParameters` to support non-filter parameters and DDL
statements.
Added a new argument `ignoreDdl` at integration test. Admin client is
needed to execute ddl statement in spanner. Toolbox does not use admin
client.
Part of #535
This commit refactors the source configuration and loading mechanism to
use a dynamic registration pattern. Each source package now registers
itself with a central registry via its init() function.
The server configuration code uses this registry to decode and
initialize sources, decoupling it from specific source implementations
and simplifying the addition of new sources.
Key changes:
- Introduced `sources.Register()` and `newConfig()` constructor in each
source package.
- Moved source package imports to `cmd/root.go` as blank imports to
trigger `init()` functions for self-registration.
- Removed direct imports of specific source packages from
`internal/server/config.go`.
- Renamed `SourceKind` constants to `Kind` within each source package.
- Updated tests to use the new `Kind` constants and reflect registration
changes.
---------
Co-authored-by: Yuan Teoh <yuanteoh@google.com>
Add new tool field, templateParameters, to support non-filter parameters
and DDL statements
Fix#535 for postgressql tool.
---------
Co-authored-by: Yuan <45984206+Yuan325@users.noreply.github.com>
This PR refactors the tool configuration and loading mechanism to use a
dynamic registration pattern. Each tool package now registers itself
with a central registry, and the server configuration code uses this
registry to decode and initialize tools.
Key changes:
- Introduced tools.Register and tools.DecodeToolConfig for dynamic tool
handling.
- Removed direct imports of specific tool packages from
internal/server/config.go.
- Updated individual tool packages to include init() functions for
self-registration.
- Modified ToolKind constants to be local kind constants within each
tool package.
- Adjusted test files to reflect the changes in tool kind identifiers.
This change simplifies adding new tools and decouples the server
configuration from specific tool implementations.
---------
Co-authored-by: Yuan Teoh <yuanteoh@google.com>
Co-authored-by: Yuan <45984206+Yuan325@users.noreply.github.com>
@Yuan325 please review and merge this if all looks ok.
In existing code, for the character field with null values it will panic
with error:
"panic: interface conversion: interface {} is nil, not []uint8"
Currently the `stdio` transport protocol will throw a `ZodError` during
initialization. This is due to Toolbox writing `null` to stdout when it
received a notification. This is not expected hence the `ZodError`
occurs. Per the MCP protocol, notifications do not expect any response.
This fix added a condition to check if the responses is `nil` before
writing to stdout.
gosimple had been deprecated in favor of staticcheck:
https://github.com/golangci/golangci-lint/issues/357
Other requirements are all migrated.
`std-error-handling` exclusions is included because without that, it
will ask to check all error returns from (`Close()`, or `os.Setenv`s, or
`fmt.Fprint`s...
Introduces a new --prebuilt <source_type> flag. This flag is mutually
exclusive with the existing --tools-file flag.
Added a new directory cmd/prebuiltconfigs/ to store the prebuilt
tools.yaml files (e.g., alloydb.yaml, postgres.yaml, etc.).
These YAML files are embedded into the Go binary using the //go:embed
directive.
---------
Co-authored-by: Averi Kitsch <akitsch@google.com>