mirror of
https://github.com/googleapis/genai-toolbox.git
synced 2026-01-11 16:38:15 -05:00
Compare commits
10 Commits
source-imp
...
ainl-docs
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1eb056853 | ||
|
|
6f342a1e72 | ||
|
|
41b518b955 | ||
|
|
6e8a9eb8ec | ||
|
|
ef8f3b02f2 | ||
|
|
351b007fe3 | ||
|
|
9d1feca108 | ||
|
|
17b41f6453 | ||
|
|
a7799757c9 | ||
|
|
d961e373e1 |
@@ -51,6 +51,10 @@ ignoreFiles = ["quickstart/shared", "quickstart/python", "quickstart/js", "quick
|
||||
# Add a new version block here before every release
|
||||
# The order of versions in this file is mirrored into the dropdown
|
||||
|
||||
[[params.versions]]
|
||||
version = "v0.25.0"
|
||||
url = "https://googleapis.github.io/genai-toolbox/v0.25.0/"
|
||||
|
||||
[[params.versions]]
|
||||
version = "v0.24.0"
|
||||
url = "https://googleapis.github.io/genai-toolbox/v0.24.0/"
|
||||
|
||||
25
CHANGELOG.md
25
CHANGELOG.md
@@ -1,5 +1,30 @@
|
||||
# Changelog
|
||||
|
||||
## [0.25.0](https://github.com/googleapis/genai-toolbox/compare/v0.24.0...v0.25.0) (2026-01-08)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add `embeddingModel` support ([#2121](https://github.com/googleapis/genai-toolbox/issues/2121)) ([9c62f31](https://github.com/googleapis/genai-toolbox/commit/9c62f313ff5edf0a3b5b8a3e996eba078fba4095))
|
||||
* Add `allowed-hosts` flag ([#2254](https://github.com/googleapis/genai-toolbox/issues/2254)) ([17b41f6](https://github.com/googleapis/genai-toolbox/commit/17b41f64531b8fe417c28ada45d1992ba430dc1b))
|
||||
* Add parameter default value to manifest ([#2264](https://github.com/googleapis/genai-toolbox/issues/2264)) ([9d1feca](https://github.com/googleapis/genai-toolbox/commit/9d1feca10810fa42cb4c94a409252f1bd373ee36))
|
||||
* **snowflake:** Add Snowflake Source and Tools ([#858](https://github.com/googleapis/genai-toolbox/issues/858)) ([b706b5b](https://github.com/googleapis/genai-toolbox/commit/b706b5bc685aeda277f277868bae77d38d5fd7b6))
|
||||
* **prebuilt/cloud-sql-mysql:** Update CSQL MySQL prebuilt tools to use IAM ([#2202](https://github.com/googleapis/genai-toolbox/issues/2202)) ([731a32e](https://github.com/googleapis/genai-toolbox/commit/731a32e5360b4d6862d81fcb27d7127c655679a8))
|
||||
* **sources/bigquery:** Make credentials scope configurable ([#2210](https://github.com/googleapis/genai-toolbox/issues/2210)) ([a450600](https://github.com/googleapis/genai-toolbox/commit/a4506009b93771b77fb05ae97044f914967e67ed))
|
||||
* **sources/trino:** Add ssl verification options and fix docs example ([#2155](https://github.com/googleapis/genai-toolbox/issues/2155)) ([4a4cf1e](https://github.com/googleapis/genai-toolbox/commit/4a4cf1e712b671853678dba99c4dc49dd4fc16a2))
|
||||
* **tools/looker:** Add ability to set destination folder with `make_look` and `make_dashboard`. ([#2245](https://github.com/googleapis/genai-toolbox/issues/2245)) ([eb79339](https://github.com/googleapis/genai-toolbox/commit/eb793398cd1cc4006d9808ccda5dc7aea5e92bd5))
|
||||
* **tools/postgressql:** Add tool to list store procedure ([#2156](https://github.com/googleapis/genai-toolbox/issues/2156)) ([cf0fc51](https://github.com/googleapis/genai-toolbox/commit/cf0fc515b57d9b84770076f3c0c5597c4597ef62))
|
||||
* **tools/postgressql:** Add Parameter `embeddedBy` config support ([#2151](https://github.com/googleapis/genai-toolbox/issues/2151)) ([17b70cc](https://github.com/googleapis/genai-toolbox/commit/17b70ccaa754d15bcc33a1a3ecb7e652520fa600))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **server:** Add `embeddingModel` config initialization ([#2281](https://github.com/googleapis/genai-toolbox/issues/2281)) ([a779975](https://github.com/googleapis/genai-toolbox/commit/a7799757c9345f99b6d2717841fbf792d364e1a2))
|
||||
* **sources/cloudgda:** Add import for cloudgda source ([#2217](https://github.com/googleapis/genai-toolbox/issues/2217)) ([7daa411](https://github.com/googleapis/genai-toolbox/commit/7daa4111f4ebfb0a35319fd67a8f7b9f0f99efcf))
|
||||
* **tools/alloydb-wait-for-operation:** Fix connection message generation ([#2228](https://github.com/googleapis/genai-toolbox/issues/2228)) ([7053fbb](https://github.com/googleapis/genai-toolbox/commit/7053fbb1953653143d39a8510916ea97a91022a6))
|
||||
* **tools/alloydbainl:** Only add psv when NL Config Param is defined ([#2265](https://github.com/googleapis/genai-toolbox/issues/2265)) ([ef8f3b0](https://github.com/googleapis/genai-toolbox/commit/ef8f3b02f2f38ce94a6ba9acf35d08b9469bef4e))
|
||||
* **tools/looker:** Looker client OAuth nil pointer error ([#2231](https://github.com/googleapis/genai-toolbox/issues/2231)) ([268700b](https://github.com/googleapis/genai-toolbox/commit/268700bdbf8281de0318d60ca613ed3672990b20))
|
||||
|
||||
## [0.24.0](https://github.com/googleapis/genai-toolbox/compare/v0.23.0...v0.24.0) (2025-12-19)
|
||||
|
||||
|
||||
|
||||
14
README.md
14
README.md
@@ -140,7 +140,7 @@ To install Toolbox as a binary:
|
||||
>
|
||||
> ```sh
|
||||
> # see releases page for other versions
|
||||
> export VERSION=0.24.0
|
||||
> export VERSION=0.25.0
|
||||
> curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/linux/amd64/toolbox
|
||||
> chmod +x toolbox
|
||||
> ```
|
||||
@@ -153,7 +153,7 @@ To install Toolbox as a binary:
|
||||
>
|
||||
> ```sh
|
||||
> # see releases page for other versions
|
||||
> export VERSION=0.24.0
|
||||
> export VERSION=0.25.0
|
||||
> curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/darwin/arm64/toolbox
|
||||
> chmod +x toolbox
|
||||
> ```
|
||||
@@ -166,7 +166,7 @@ To install Toolbox as a binary:
|
||||
>
|
||||
> ```sh
|
||||
> # see releases page for other versions
|
||||
> export VERSION=0.24.0
|
||||
> export VERSION=0.25.0
|
||||
> curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/darwin/amd64/toolbox
|
||||
> chmod +x toolbox
|
||||
> ```
|
||||
@@ -179,7 +179,7 @@ To install Toolbox as a binary:
|
||||
>
|
||||
> ```cmd
|
||||
> :: see releases page for other versions
|
||||
> set VERSION=0.24.0
|
||||
> set VERSION=0.25.0
|
||||
> curl -o toolbox.exe "https://storage.googleapis.com/genai-toolbox/v%VERSION%/windows/amd64/toolbox.exe"
|
||||
> ```
|
||||
>
|
||||
@@ -191,7 +191,7 @@ To install Toolbox as a binary:
|
||||
>
|
||||
> ```powershell
|
||||
> # see releases page for other versions
|
||||
> $VERSION = "0.24.0"
|
||||
> $VERSION = "0.25.0"
|
||||
> curl.exe -o toolbox.exe "https://storage.googleapis.com/genai-toolbox/v$VERSION/windows/amd64/toolbox.exe"
|
||||
> ```
|
||||
>
|
||||
@@ -204,7 +204,7 @@ You can also install Toolbox as a container:
|
||||
|
||||
```sh
|
||||
# see releases page for other versions
|
||||
export VERSION=0.24.0
|
||||
export VERSION=0.25.0
|
||||
docker pull us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:$VERSION
|
||||
```
|
||||
|
||||
@@ -228,7 +228,7 @@ To install from source, ensure you have the latest version of
|
||||
[Go installed](https://go.dev/doc/install), and then run the following command:
|
||||
|
||||
```sh
|
||||
go install github.com/googleapis/genai-toolbox@v0.24.0
|
||||
go install github.com/googleapis/genai-toolbox@v0.25.0
|
||||
```
|
||||
<!-- {x-release-please-end} -->
|
||||
|
||||
|
||||
@@ -381,7 +381,9 @@ func NewCommand(opts ...Option) *Command {
|
||||
flags.BoolVar(&cmd.cfg.Stdio, "stdio", false, "Listens via MCP STDIO instead of acting as a remote HTTP server.")
|
||||
flags.BoolVar(&cmd.cfg.DisableReload, "disable-reload", false, "Disables dynamic reloading of tools file.")
|
||||
flags.BoolVar(&cmd.cfg.UI, "ui", false, "Launches the Toolbox UI web server.")
|
||||
// TODO: Insecure by default. Might consider updating this for v1.0.0
|
||||
flags.StringSliceVar(&cmd.cfg.AllowedOrigins, "allowed-origins", []string{"*"}, "Specifies a list of origins permitted to access this server. Defaults to '*'.")
|
||||
flags.StringSliceVar(&cmd.cfg.AllowedHosts, "allowed-hosts", []string{"*"}, "Specifies a list of hosts permitted to access this server. Defaults to '*'.")
|
||||
|
||||
// wrap RunE command so that we have access to original Command object
|
||||
cmd.RunE = func(*cobra.Command, []string) error { return run(cmd) }
|
||||
@@ -947,6 +949,7 @@ func run(cmd *Command) error {
|
||||
|
||||
cmd.cfg.SourceConfigs = finalToolsFile.Sources
|
||||
cmd.cfg.AuthServiceConfigs = finalToolsFile.AuthServices
|
||||
cmd.cfg.EmbeddingModelConfigs = finalToolsFile.EmbeddingModels
|
||||
cmd.cfg.ToolConfigs = finalToolsFile.Tools
|
||||
cmd.cfg.ToolsetConfigs = finalToolsFile.Toolsets
|
||||
cmd.cfg.PromptConfigs = finalToolsFile.Prompts
|
||||
|
||||
@@ -67,6 +67,9 @@ func withDefaults(c server.ServerConfig) server.ServerConfig {
|
||||
if c.AllowedOrigins == nil {
|
||||
c.AllowedOrigins = []string{"*"}
|
||||
}
|
||||
if c.AllowedHosts == nil {
|
||||
c.AllowedHosts = []string{"*"}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -220,6 +223,13 @@ func TestServerConfigFlags(t *testing.T) {
|
||||
AllowedOrigins: []string{"http://foo.com", "http://bar.com"},
|
||||
}),
|
||||
},
|
||||
{
|
||||
desc: "allowed hosts",
|
||||
args: []string{"--allowed-hosts", "http://foo.com,http://bar.com"},
|
||||
want: withDefaults(server.ServerConfig{
|
||||
AllowedHosts: []string{"http://foo.com", "http://bar.com"},
|
||||
}),
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.24.0
|
||||
0.25.0
|
||||
|
||||
18
docs/en/blogs/_index.md
Normal file
18
docs/en/blogs/_index.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: "Featured Articles"
|
||||
weight: 3
|
||||
description: Toolbox Medium Blogs
|
||||
manualLink: "https://medium.com/@mcp_toolbox"
|
||||
manualLinkTarget: _blank
|
||||
---
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Redirecting to Featured Articles</title>
|
||||
<link rel="canonical" href="https://medium.com/@mcp_toolbox"/>
|
||||
<meta http-equiv="refresh" content="0;url=https://medium.com/@mcp_toolbox"/>
|
||||
</head>
|
||||
<body>
|
||||
<p>If you are not automatically redirected, please <a href="https://medium.com/@mcp_toolbox">follow this link to our articles</a>.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -234,7 +234,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"version = \"0.24.0\" # x-release-please-version\n",
|
||||
"version = \"0.25.0\" # x-release-please-version\n",
|
||||
"! curl -O https://storage.googleapis.com/genai-toolbox/v{version}/linux/amd64/toolbox\n",
|
||||
"\n",
|
||||
"# Make the binary executable\n",
|
||||
|
||||
@@ -103,7 +103,7 @@ To install Toolbox as a binary on Linux (AMD64):
|
||||
|
||||
```sh
|
||||
# see releases page for other versions
|
||||
export VERSION=0.24.0
|
||||
export VERSION=0.25.0
|
||||
curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/linux/amd64/toolbox
|
||||
chmod +x toolbox
|
||||
```
|
||||
@@ -114,7 +114,7 @@ To install Toolbox as a binary on macOS (Apple Silicon):
|
||||
|
||||
```sh
|
||||
# see releases page for other versions
|
||||
export VERSION=0.24.0
|
||||
export VERSION=0.25.0
|
||||
curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/darwin/arm64/toolbox
|
||||
chmod +x toolbox
|
||||
```
|
||||
@@ -125,7 +125,7 @@ To install Toolbox as a binary on macOS (Intel):
|
||||
|
||||
```sh
|
||||
# see releases page for other versions
|
||||
export VERSION=0.24.0
|
||||
export VERSION=0.25.0
|
||||
curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/darwin/amd64/toolbox
|
||||
chmod +x toolbox
|
||||
```
|
||||
@@ -136,7 +136,7 @@ To install Toolbox as a binary on Windows (Command Prompt):
|
||||
|
||||
```cmd
|
||||
:: see releases page for other versions
|
||||
set VERSION=0.24.0
|
||||
set VERSION=0.25.0
|
||||
curl -o toolbox.exe "https://storage.googleapis.com/genai-toolbox/v%VERSION%/windows/amd64/toolbox.exe"
|
||||
```
|
||||
|
||||
@@ -146,7 +146,7 @@ To install Toolbox as a binary on Windows (PowerShell):
|
||||
|
||||
```powershell
|
||||
# see releases page for other versions
|
||||
$VERSION = "0.24.0"
|
||||
$VERSION = "0.25.0"
|
||||
curl.exe -o toolbox.exe "https://storage.googleapis.com/genai-toolbox/v$VERSION/windows/amd64/toolbox.exe"
|
||||
```
|
||||
|
||||
@@ -158,7 +158,7 @@ You can also install Toolbox as a container:
|
||||
|
||||
```sh
|
||||
# see releases page for other versions
|
||||
export VERSION=0.24.0
|
||||
export VERSION=0.25.0
|
||||
docker pull us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:$VERSION
|
||||
```
|
||||
|
||||
@@ -177,7 +177,7 @@ To install from source, ensure you have the latest version of
|
||||
[Go installed](https://go.dev/doc/install), and then run the following command:
|
||||
|
||||
```sh
|
||||
go install github.com/googleapis/genai-toolbox@v0.24.0
|
||||
go install github.com/googleapis/genai-toolbox@v0.25.0
|
||||
```
|
||||
|
||||
{{% /tab %}}
|
||||
|
||||
@@ -105,7 +105,7 @@ In this section, we will download Toolbox, configure our tools in a
|
||||
<!-- {x-release-please-start-version} -->
|
||||
```bash
|
||||
export OS="linux/amd64" # one of linux/amd64, darwin/arm64, darwin/amd64, or windows/amd64
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/$OS/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/$OS/toolbox
|
||||
```
|
||||
<!-- {x-release-please-end} -->
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ In this section, we will download Toolbox, configure our tools in a
|
||||
<!-- {x-release-please-start-version} -->
|
||||
```bash
|
||||
export OS="linux/amd64" # one of linux/amd64, darwin/arm64, darwin/amd64, or windows/amd64
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/$OS/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/$OS/toolbox
|
||||
```
|
||||
<!-- {x-release-please-end} -->
|
||||
|
||||
|
||||
@@ -100,19 +100,19 @@ After you install Looker in the MCP Store, resources and tools from the server a
|
||||
|
||||
{{< tabpane persist=header >}}
|
||||
{{< tab header="linux/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/linux/amd64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/linux/amd64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="darwin/arm64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/darwin/arm64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/darwin/arm64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="darwin/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/darwin/amd64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/darwin/amd64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="windows/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/windows/amd64/toolbox.exe
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/windows/amd64/toolbox.exe
|
||||
{{< /tab >}}
|
||||
{{< /tabpane >}}
|
||||
<!-- {x-release-please-end} -->
|
||||
|
||||
@@ -45,19 +45,19 @@ instance:
|
||||
<!-- {x-release-please-start-version} -->
|
||||
{{< tabpane persist=header >}}
|
||||
{{< tab header="linux/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/linux/amd64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/linux/amd64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="darwin/arm64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/darwin/arm64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/darwin/arm64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="darwin/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/darwin/amd64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/darwin/amd64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="windows/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/windows/amd64/toolbox.exe
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/windows/amd64/toolbox.exe
|
||||
{{< /tab >}}
|
||||
{{< /tabpane >}}
|
||||
<!-- {x-release-please-end} -->
|
||||
|
||||
@@ -43,19 +43,19 @@ expose your developer assistant tools to a MySQL instance:
|
||||
<!-- {x-release-please-start-version} -->
|
||||
{{< tabpane persist=header >}}
|
||||
{{< tab header="linux/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/linux/amd64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/linux/amd64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="darwin/arm64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/darwin/arm64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/darwin/arm64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="darwin/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/darwin/amd64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/darwin/amd64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="windows/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/windows/amd64/toolbox.exe
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/windows/amd64/toolbox.exe
|
||||
{{< /tab >}}
|
||||
{{< /tabpane >}}
|
||||
<!-- {x-release-please-end} -->
|
||||
|
||||
@@ -44,19 +44,19 @@ expose your developer assistant tools to a Neo4j instance:
|
||||
<!-- {x-release-please-start-version} -->
|
||||
{{< tabpane persist=header >}}
|
||||
{{< tab header="linux/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/linux/amd64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/linux/amd64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="darwin/arm64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/darwin/arm64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/darwin/arm64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="darwin/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/darwin/amd64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/darwin/amd64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="windows/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/windows/amd64/toolbox.exe
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/windows/amd64/toolbox.exe
|
||||
{{< /tab >}}
|
||||
{{< /tabpane >}}
|
||||
<!-- {x-release-please-end} -->
|
||||
|
||||
@@ -56,19 +56,19 @@ Omni](https://cloud.google.com/alloydb/omni/current/docs/overview).
|
||||
<!-- {x-release-please-start-version} -->
|
||||
{{< tabpane persist=header >}}
|
||||
{{< tab header="linux/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/linux/amd64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/linux/amd64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="darwin/arm64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/darwin/arm64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/darwin/arm64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="darwin/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/darwin/amd64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/darwin/amd64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="windows/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/windows/amd64/toolbox.exe
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/windows/amd64/toolbox.exe
|
||||
{{< /tab >}}
|
||||
{{< /tabpane >}}
|
||||
<!-- {x-release-please-end} -->
|
||||
|
||||
@@ -43,19 +43,19 @@ to expose your developer assistant tools to a SQLite instance:
|
||||
<!-- {x-release-please-start-version} -->
|
||||
{{< tabpane persist=header >}}
|
||||
{{< tab header="linux/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/linux/amd64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/linux/amd64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="darwin/arm64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/darwin/arm64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/darwin/arm64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="darwin/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/darwin/amd64/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/darwin/amd64/toolbox
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab header="windows/amd64" lang="bash" >}}
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/windows/amd64/toolbox.exe
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/windows/amd64/toolbox.exe
|
||||
{{< /tab >}}
|
||||
{{< /tabpane >}}
|
||||
<!-- {x-release-please-end} -->
|
||||
|
||||
@@ -68,7 +68,12 @@ networks:
|
||||
```
|
||||
|
||||
{{< notice tip >}}
|
||||
To prevent DNS rebinding attack, use the `--allowed-origins` flag to specify a
|
||||
To prevent DNS rebinding attack, use the `--allowed-hosts` flag to specify a
|
||||
list of hosts for validation. E.g. `command: [ "toolbox",
|
||||
"--tools-file", "/config/tools.yaml", "--address", "0.0.0.0",
|
||||
"--allowed-hosts", "localhost:5000"]`
|
||||
|
||||
To implement CORs, use the `--allowed-origins` flag to specify a
|
||||
list of origins permitted to access the server. E.g. `command: [ "toolbox",
|
||||
"--tools-file", "/config/tools.yaml", "--address", "0.0.0.0",
|
||||
"--allowed-origins", "https://foo.bar"]`
|
||||
|
||||
@@ -188,9 +188,13 @@ description: >
|
||||
path: tools.yaml
|
||||
```
|
||||
|
||||
{{< notice tip >}}
|
||||
{{< notice tip >}}
|
||||
To prevent DNS rebinding attack, use the `--allowed-origins` flag to specify a
|
||||
list of origins permitted to access the server. E.g. `args: ["--address",
|
||||
"0.0.0.0", "--allowed-hosts", "foo.bar:5000"]`
|
||||
|
||||
To implement CORs, use the `--allowed-origins` flag to specify a
|
||||
list of origins permitted to access the server. E.g. `args: ["--address",
|
||||
"0.0.0.0", "--allowed-origins", "https://foo.bar"]`
|
||||
{{< /notice >}}
|
||||
|
||||
|
||||
@@ -142,14 +142,18 @@ deployment will time out.
|
||||
|
||||
### Update deployed server to be secure
|
||||
|
||||
To prevent DNS rebinding attack, use the `--allowed-origins` flag to specify a
|
||||
list of origins permitted to access the server. In order to do that, you will
|
||||
To prevent DNS rebinding attack, use the `--allowed-hosts` flag to specify a
|
||||
list of hosts. In order to do that, you will
|
||||
have to re-deploy the cloud run service with the new flag.
|
||||
|
||||
To implement CORs checks, use the `--allowed-origins` flag to specify a list of
|
||||
origins permitted to access the server.
|
||||
|
||||
1. Set an environment variable to the cloud run url:
|
||||
|
||||
```bash
|
||||
export URL=<cloud run url>
|
||||
export HOST=<cloud run host>
|
||||
```
|
||||
|
||||
2. Redeploy Toolbox:
|
||||
@@ -160,7 +164,7 @@ have to re-deploy the cloud run service with the new flag.
|
||||
--service-account toolbox-identity \
|
||||
--region us-central1 \
|
||||
--set-secrets "/app/tools.yaml=tools:latest" \
|
||||
--args="--tools-file=/app/tools.yaml","--address=0.0.0.0","--port=8080","--allowed-origins=$URL"
|
||||
--args="--tools-file=/app/tools.yaml","--address=0.0.0.0","--port=8080","--allowed-origins=$URL","--allowed-hosts=$HOST"
|
||||
# --allow-unauthenticated # https://cloud.google.com/run/docs/authenticating/public#gcloud
|
||||
```
|
||||
|
||||
@@ -172,7 +176,7 @@ have to re-deploy the cloud run service with the new flag.
|
||||
--service-account toolbox-identity \
|
||||
--region us-central1 \
|
||||
--set-secrets "/app/tools.yaml=tools:latest" \
|
||||
--args="--tools-file=/app/tools.yaml","--address=0.0.0.0","--port=8080","--allowed-origins=$URL" \
|
||||
--args="--tools-file=/app/tools.yaml","--address=0.0.0.0","--port=8080","--allowed-origins=$URL","--allowed-hosts=$HOST" \
|
||||
# TODO(dev): update the following to match your VPC if necessary
|
||||
--network default \
|
||||
--subnet default
|
||||
|
||||
@@ -8,25 +8,26 @@ description: >
|
||||
|
||||
## Reference
|
||||
|
||||
| Flag (Short) | Flag (Long) | Description | Default |
|
||||
|--------------|----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------|
|
||||
| `-a` | `--address` | Address of the interface the server will listen on. | `127.0.0.1` |
|
||||
| | `--disable-reload` | Disables dynamic reloading of tools file. | |
|
||||
| `-h` | `--help` | help for toolbox | |
|
||||
| | `--log-level` | Specify the minimum level logged. Allowed: 'DEBUG', 'INFO', 'WARN', 'ERROR'. | `info` |
|
||||
| | `--logging-format` | Specify logging format to use. Allowed: 'standard' or 'JSON'. | `standard` |
|
||||
| `-p` | `--port` | Port the server will listen on. | `5000` |
|
||||
| | `--prebuilt` | Use a prebuilt tool configuration by source type. See [Prebuilt Tools Reference](prebuilt-tools.md) for allowed values. | |
|
||||
| | `--stdio` | Listens via MCP STDIO instead of acting as a remote HTTP server. | |
|
||||
| | `--telemetry-gcp` | Enable exporting directly to Google Cloud Monitoring. | |
|
||||
| | `--telemetry-otlp` | Enable exporting using OpenTelemetry Protocol (OTLP) to the specified endpoint (e.g. 'http://127.0.0.1:4318') | |
|
||||
| | `--telemetry-service-name` | Sets the value of the service.name resource attribute for telemetry data. | `toolbox` |
|
||||
| Flag (Short) | Flag (Long) | Description | Default |
|
||||
|--------------|----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------|
|
||||
| `-a` | `--address` | Address of the interface the server will listen on. | `127.0.0.1` |
|
||||
| | `--disable-reload` | Disables dynamic reloading of tools file. | |
|
||||
| `-h` | `--help` | help for toolbox | |
|
||||
| | `--log-level` | Specify the minimum level logged. Allowed: 'DEBUG', 'INFO', 'WARN', 'ERROR'. | `info` |
|
||||
| | `--logging-format` | Specify logging format to use. Allowed: 'standard' or 'JSON'. | `standard` |
|
||||
| `-p` | `--port` | Port the server will listen on. | `5000` |
|
||||
| | `--prebuilt` | Use a prebuilt tool configuration by source type. See [Prebuilt Tools Reference](prebuilt-tools.md) for allowed values. | |
|
||||
| | `--stdio` | Listens via MCP STDIO instead of acting as a remote HTTP server. | |
|
||||
| | `--telemetry-gcp` | Enable exporting directly to Google Cloud Monitoring. | |
|
||||
| | `--telemetry-otlp` | Enable exporting using OpenTelemetry Protocol (OTLP) to the specified endpoint (e.g. 'http://127.0.0.1:4318') | |
|
||||
| | `--telemetry-service-name` | Sets the value of the service.name resource attribute for telemetry data. | `toolbox` |
|
||||
| | `--tools-file` | File path specifying the tool configuration. Cannot be used with --tools-files or --tools-folder. | |
|
||||
| | `--tools-files` | Multiple file paths specifying tool configurations. Files will be merged. Cannot be used with --tools-file or --tools-folder. | |
|
||||
| | `--tools-folder` | Directory path containing YAML tool configuration files. All .yaml and .yml files in the directory will be loaded and merged. Cannot be used with --tools-file or --tools-files. | |
|
||||
| | `--ui` | Launches the Toolbox UI web server. | |
|
||||
| | `--allowed-origins` | Specifies a list of origins permitted to access this server. | `*` |
|
||||
| `-v` | `--version` | version for toolbox | |
|
||||
| | `--ui` | Launches the Toolbox UI web server. | |
|
||||
| | `--allowed-origins` | Specifies a list of origins permitted to access this server for CORs access. | `*` |
|
||||
| | `--allowed-hosts` | Specifies a list of hosts permitted to access this server to prevent DNS rebinding attacks. | `*` |
|
||||
| `-v` | `--version` | version for toolbox | |
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
@@ -91,8 +91,8 @@ visible to the LLM.
|
||||
https://cloud.google.com/alloydb/docs/parameterized-secure-views-overview
|
||||
|
||||
{{< notice tip >}} Make sure to enable the `parameterized_views` extension
|
||||
before running this tool. You can do so by running this command in the AlloyDB
|
||||
studio:
|
||||
to utilize PSV feature (`nlConfigParameters`) with this tool. You can do so by
|
||||
running this command in the AlloyDB studio:
|
||||
|
||||
```sql
|
||||
CREATE EXTENSION IF NOT EXISTS parameterized_views;
|
||||
|
||||
@@ -771,7 +771,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"version = \"0.24.0\" # x-release-please-version\n",
|
||||
"version = \"0.25.0\" # x-release-please-version\n",
|
||||
"! curl -L -o /content/toolbox https://storage.googleapis.com/genai-toolbox/v{version}/linux/amd64/toolbox\n",
|
||||
"\n",
|
||||
"# Make the binary executable\n",
|
||||
|
||||
@@ -123,7 +123,7 @@ In this section, we will download and install the Toolbox binary.
|
||||
<!-- {x-release-please-start-version} -->
|
||||
```bash
|
||||
export OS="linux/amd64" # one of linux/amd64, darwin/arm64, darwin/amd64, or windows/amd64
|
||||
export VERSION="0.24.0"
|
||||
export VERSION="0.25.0"
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v$VERSION/$OS/toolbox
|
||||
```
|
||||
<!-- {x-release-please-end} -->
|
||||
|
||||
@@ -220,7 +220,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"version = \"0.24.0\" # x-release-please-version\n",
|
||||
"version = \"0.25.0\" # x-release-please-version\n",
|
||||
"! curl -O https://storage.googleapis.com/genai-toolbox/v{version}/linux/amd64/toolbox\n",
|
||||
"\n",
|
||||
"# Make the binary executable\n",
|
||||
|
||||
@@ -179,7 +179,7 @@ to use BigQuery, and then run the Toolbox server.
|
||||
<!-- {x-release-please-start-version} -->
|
||||
```bash
|
||||
export OS="linux/amd64" # one of linux/amd64, darwin/arm64, darwin/amd64, or windows/amd64
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/$OS/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/$OS/toolbox
|
||||
```
|
||||
<!-- {x-release-please-end} -->
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ In this section, we will download Toolbox, configure our tools in a
|
||||
<!-- {x-release-please-start-version} -->
|
||||
```bash
|
||||
export OS="linux/amd64" # one of linux/amd64, darwin/arm64, darwin/amd64, or windows/amd64
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/$OS/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/$OS/toolbox
|
||||
```
|
||||
<!-- {x-release-please-end} -->
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ In this section, we will download Toolbox and run the Toolbox server.
|
||||
<!-- {x-release-please-start-version} -->
|
||||
```bash
|
||||
export OS="linux/amd64" # one of linux/amd64, darwin/arm64, darwin/amd64, or windows/amd64
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/$OS/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/$OS/toolbox
|
||||
```
|
||||
<!-- {x-release-please-end} -->
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ In this section, we will download Toolbox and run the Toolbox server.
|
||||
<!-- {x-release-please-start-version} -->
|
||||
```bash
|
||||
export OS="linux/amd64" # one of linux/amd64, darwin/arm64, darwin/amd64, or windows/amd64
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/$OS/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/$OS/toolbox
|
||||
```
|
||||
<!-- {x-release-please-end} -->
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ In this section, we will download Toolbox and run the Toolbox server.
|
||||
<!-- {x-release-please-start-version} -->
|
||||
```bash
|
||||
export OS="linux/amd64" # one of linux/amd64, darwin/arm64, darwin/amd64, or windows/amd64
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.24.0/$OS/toolbox
|
||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.25.0/$OS/toolbox
|
||||
```
|
||||
<!-- {x-release-please-end} -->
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mcp-toolbox-for-databases",
|
||||
"version": "0.24.0",
|
||||
"version": "0.25.0",
|
||||
"description": "MCP Toolbox for Databases is an open-source MCP server for more than 30 different datasources.",
|
||||
"contextFileName": "MCP-TOOLBOX-EXTENSION.md"
|
||||
}
|
||||
@@ -68,6 +68,8 @@ type ServerConfig struct {
|
||||
UI bool
|
||||
// Specifies a list of origins permitted to access this server.
|
||||
AllowedOrigins []string
|
||||
// Specifies a list of hosts permitted to access this server
|
||||
AllowedHosts []string
|
||||
}
|
||||
|
||||
type logFormat string
|
||||
|
||||
@@ -300,6 +300,21 @@ func InitializeConfigs(ctx context.Context, cfg ServerConfig) (
|
||||
return sourcesMap, authServicesMap, embeddingModelsMap, toolsMap, toolsetsMap, promptsMap, promptsetsMap, nil
|
||||
}
|
||||
|
||||
func hostCheck(allowedHosts map[string]struct{}) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
_, hasWildcard := allowedHosts["*"]
|
||||
_, hostIsAllowed := allowedHosts[r.Host]
|
||||
if !hasWildcard && !hostIsAllowed {
|
||||
// Return 400 Bad Request or 403 Forbidden to block the attack
|
||||
http.Error(w, "Invalid Host header", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// NewServer returns a Server object based on provided Config.
|
||||
func NewServer(ctx context.Context, cfg ServerConfig) (*Server, error) {
|
||||
instrumentation, err := util.InstrumentationFromContext(ctx)
|
||||
@@ -374,7 +389,7 @@ func NewServer(ctx context.Context, cfg ServerConfig) (*Server, error) {
|
||||
|
||||
// cors
|
||||
if slices.Contains(cfg.AllowedOrigins, "*") {
|
||||
s.logger.WarnContext(ctx, "wildcard (`*`) allows all origin to access the resource and is not secure. Use it with cautious for public, non-sensitive data, or during local development. Recommended to use `--allowed-origins` flag to prevent DNS rebinding attacks")
|
||||
s.logger.WarnContext(ctx, "wildcard (`*`) allows all origin to access the resource and is not secure. Use it with cautious for public, non-sensitive data, or during local development. Recommended to use `--allowed-origins` flag")
|
||||
}
|
||||
corsOpts := cors.Options{
|
||||
AllowedOrigins: cfg.AllowedOrigins,
|
||||
@@ -385,6 +400,15 @@ func NewServer(ctx context.Context, cfg ServerConfig) (*Server, error) {
|
||||
MaxAge: 300, // cache preflight results for 5 minutes
|
||||
}
|
||||
r.Use(cors.Handler(corsOpts))
|
||||
// validate hosts for DNS rebinding attacks
|
||||
if slices.Contains(cfg.AllowedHosts, "*") {
|
||||
s.logger.WarnContext(ctx, "wildcard (`*`) allows all hosts to access the resource and is not secure. Use it with cautious for public, non-sensitive data, or during local development. Recommended to use `--allowed-hosts` flag to prevent DNS rebinding attacks")
|
||||
}
|
||||
allowedHostsMap := make(map[string]struct{}, len(cfg.AllowedHosts))
|
||||
for _, h := range cfg.AllowedHosts {
|
||||
allowedHostsMap[h] = struct{}{}
|
||||
}
|
||||
r.Use(hostCheck(allowedHostsMap))
|
||||
|
||||
// control plane
|
||||
apiR, err := apiRouter(s)
|
||||
|
||||
@@ -43,9 +43,10 @@ func TestServe(t *testing.T) {
|
||||
|
||||
addr, port := "127.0.0.1", 5000
|
||||
cfg := server.ServerConfig{
|
||||
Version: "0.0.0",
|
||||
Address: addr,
|
||||
Port: port,
|
||||
Version: "0.0.0",
|
||||
Address: addr,
|
||||
Port: port,
|
||||
AllowedHosts: []string{"*"},
|
||||
}
|
||||
|
||||
otelShutdown, err := telemetry.SetupOTel(ctx, "0.0.0", "", false, "toolbox")
|
||||
|
||||
@@ -77,26 +77,21 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
|
||||
placeholderParts = append(placeholderParts, fmt.Sprintf("$%d", i+3)) // $1, $2 reserved
|
||||
}
|
||||
|
||||
var paramNamesSQL string
|
||||
var paramValuesSQL string
|
||||
|
||||
var stmt string
|
||||
if numParams > 0 {
|
||||
paramNamesSQL = fmt.Sprintf("ARRAY[%s]", strings.Join(quotedNameParts, ", "))
|
||||
paramValuesSQL = fmt.Sprintf("ARRAY[%s]", strings.Join(placeholderParts, ", "))
|
||||
paramNamesSQL := fmt.Sprintf("ARRAY[%s]", strings.Join(quotedNameParts, ", "))
|
||||
paramValuesSQL := fmt.Sprintf("ARRAY[%s]", strings.Join(placeholderParts, ", "))
|
||||
// execute_nl_query is the AlloyDB AI function that executes the natural language query
|
||||
// The first parameter is the natural language query, which is passed as $1
|
||||
// The second parameter is the NLConfig, which is passed as a $2
|
||||
// The following params are the list of PSV values passed to the NLConfig
|
||||
// Example SQL statement being executed:
|
||||
// SELECT alloydb_ai_nl.execute_nl_query(nl_question => 'How many tickets do I have?', nl_config_id => 'cymbal_air_nl_config', param_names => ARRAY ['user_email'], param_values => ARRAY ['hailongli@google.com']);
|
||||
stmtFormat := "SELECT alloydb_ai_nl.execute_nl_query(nl_question => $1, nl_config_id => $2, param_names => %s, param_values => %s);"
|
||||
stmt = fmt.Sprintf(stmtFormat, paramNamesSQL, paramValuesSQL)
|
||||
} else {
|
||||
paramNamesSQL = "ARRAY[]::TEXT[]"
|
||||
paramValuesSQL = "ARRAY[]::TEXT[]"
|
||||
stmt = "SELECT alloydb_ai_nl.execute_nl_query(nl_question => $1, nl_config_id => $2);"
|
||||
}
|
||||
|
||||
// execute_nl_query is the AlloyDB AI function that executes the natural language query
|
||||
// The first parameter is the natural language query, which is passed as $1
|
||||
// The second parameter is the NLConfig, which is passed as a $2
|
||||
// The following params are the list of PSV values passed to the NLConfig
|
||||
// Example SQL statement being executed:
|
||||
// SELECT alloydb_ai_nl.execute_nl_query(nl_question => 'How many tickets do I have?', nl_config_id => 'cymbal_air_nl_config', param_names => ARRAY ['user_email'], param_values => ARRAY ['hailongli@google.com']);
|
||||
stmtFormat := "SELECT alloydb_ai_nl.execute_nl_query(nl_question => $1, nl_config_id => $2, param_names => %s, param_values => %s);"
|
||||
stmt := fmt.Sprintf(stmtFormat, paramNamesSQL, paramValuesSQL)
|
||||
|
||||
newQuestionParam := parameters.NewStringParameter(
|
||||
"question", // name
|
||||
"The natural language question to ask.", // description
|
||||
|
||||
@@ -478,9 +478,13 @@ func (ps Parameters) McpManifest() (McpToolsSchema, map[string][]string) {
|
||||
for _, p := range ps {
|
||||
name := p.GetName()
|
||||
paramManifest, authParamList := p.McpManifest()
|
||||
defaultV := p.GetDefault()
|
||||
if defaultV != nil {
|
||||
paramManifest.Default = defaultV
|
||||
}
|
||||
properties[name] = paramManifest
|
||||
// parameters that doesn't have a default value are added to the required field
|
||||
if CheckParamRequired(p.GetRequired(), p.GetDefault()) {
|
||||
if CheckParamRequired(p.GetRequired(), defaultV) {
|
||||
required = append(required, name)
|
||||
}
|
||||
if len(authParamList) > 0 {
|
||||
@@ -502,6 +506,7 @@ type ParameterManifest struct {
|
||||
Description string `json:"description"`
|
||||
AuthServices []string `json:"authSources"`
|
||||
Items *ParameterManifest `json:"items,omitempty"`
|
||||
Default any `json:"default,omitempty"`
|
||||
AdditionalProperties any `json:"additionalProperties,omitempty"`
|
||||
EmbeddedBy string `json:"embeddedBy,omitempty"`
|
||||
}
|
||||
@@ -511,6 +516,7 @@ type ParameterMcpManifest struct {
|
||||
Type string `json:"type"`
|
||||
Description string `json:"description"`
|
||||
Items *ParameterMcpManifest `json:"items,omitempty"`
|
||||
Default any `json:"default,omitempty"`
|
||||
AdditionalProperties any `json:"additionalProperties,omitempty"`
|
||||
}
|
||||
|
||||
@@ -788,6 +794,7 @@ func (p *StringParameter) Manifest() ParameterManifest {
|
||||
Required: r,
|
||||
Description: p.Desc,
|
||||
AuthServices: authServiceNames,
|
||||
Default: p.GetDefault(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -946,6 +953,7 @@ func (p *IntParameter) Manifest() ParameterManifest {
|
||||
Required: r,
|
||||
Description: p.Desc,
|
||||
AuthServices: authServiceNames,
|
||||
Default: p.GetDefault(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1102,6 +1110,7 @@ func (p *FloatParameter) Manifest() ParameterManifest {
|
||||
Required: r,
|
||||
Description: p.Desc,
|
||||
AuthServices: authServiceNames,
|
||||
Default: p.GetDefault(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1235,6 +1244,7 @@ func (p *BooleanParameter) Manifest() ParameterManifest {
|
||||
Required: r,
|
||||
Description: p.Desc,
|
||||
AuthServices: authServiceNames,
|
||||
Default: p.GetDefault(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1430,6 +1440,7 @@ func (p *ArrayParameter) Manifest() ParameterManifest {
|
||||
Description: p.Desc,
|
||||
AuthServices: authServiceNames,
|
||||
Items: &items,
|
||||
Default: p.GetDefault(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1675,7 +1686,10 @@ func (p *MapParameter) Manifest() ParameterManifest {
|
||||
// If no valueType is given, allow any properties.
|
||||
additionalProperties = true
|
||||
}
|
||||
|
||||
var defaultV any
|
||||
if p.Default != nil {
|
||||
defaultV = *p.Default
|
||||
}
|
||||
return ParameterManifest{
|
||||
Name: p.Name,
|
||||
Type: "object",
|
||||
@@ -1683,6 +1697,7 @@ func (p *MapParameter) Manifest() ParameterManifest {
|
||||
Description: p.Desc,
|
||||
AuthServices: authServiceNames,
|
||||
AdditionalProperties: additionalProperties,
|
||||
Default: defaultV,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1625,22 +1625,22 @@ func TestParamManifest(t *testing.T) {
|
||||
{
|
||||
name: "string default",
|
||||
in: parameters.NewStringParameterWithDefault("foo-string", "foo", "bar"),
|
||||
want: parameters.ParameterManifest{Name: "foo-string", Type: "string", Required: false, Description: "bar", AuthServices: []string{}},
|
||||
want: parameters.ParameterManifest{Name: "foo-string", Type: "string", Required: false, Description: "bar", Default: "foo", AuthServices: []string{}},
|
||||
},
|
||||
{
|
||||
name: "int default",
|
||||
in: parameters.NewIntParameterWithDefault("foo-int", 1, "bar"),
|
||||
want: parameters.ParameterManifest{Name: "foo-int", Type: "integer", Required: false, Description: "bar", AuthServices: []string{}},
|
||||
want: parameters.ParameterManifest{Name: "foo-int", Type: "integer", Required: false, Description: "bar", Default: 1, AuthServices: []string{}},
|
||||
},
|
||||
{
|
||||
name: "float default",
|
||||
in: parameters.NewFloatParameterWithDefault("foo-float", 1.1, "bar"),
|
||||
want: parameters.ParameterManifest{Name: "foo-float", Type: "float", Required: false, Description: "bar", AuthServices: []string{}},
|
||||
want: parameters.ParameterManifest{Name: "foo-float", Type: "float", Required: false, Description: "bar", Default: 1.1, AuthServices: []string{}},
|
||||
},
|
||||
{
|
||||
name: "boolean default",
|
||||
in: parameters.NewBooleanParameterWithDefault("foo-bool", true, "bar"),
|
||||
want: parameters.ParameterManifest{Name: "foo-bool", Type: "boolean", Required: false, Description: "bar", AuthServices: []string{}},
|
||||
want: parameters.ParameterManifest{Name: "foo-bool", Type: "boolean", Required: false, Description: "bar", Default: true, AuthServices: []string{}},
|
||||
},
|
||||
{
|
||||
name: "array default",
|
||||
@@ -1650,6 +1650,7 @@ func TestParamManifest(t *testing.T) {
|
||||
Type: "array",
|
||||
Required: false,
|
||||
Description: "bar",
|
||||
Default: []any{"foo", "bar"},
|
||||
AuthServices: []string{},
|
||||
Items: ¶meters.ParameterManifest{Name: "foo-string", Type: "string", Required: false, Description: "bar", AuthServices: []string{}},
|
||||
},
|
||||
@@ -1841,7 +1842,7 @@ func TestMcpManifest(t *testing.T) {
|
||||
wantSchema: parameters.McpToolsSchema{
|
||||
Type: "object",
|
||||
Properties: map[string]parameters.ParameterMcpManifest{
|
||||
"foo-string": {Type: "string", Description: "bar"},
|
||||
"foo-string": {Type: "string", Description: "bar", Default: "foo"},
|
||||
"foo-string2": {Type: "string", Description: "bar"},
|
||||
"foo-string3-auth": {Type: "string", Description: "bar"},
|
||||
"foo-int2": {Type: "integer", Description: "bar"},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json",
|
||||
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
||||
"name": "io.github.googleapis/genai-toolbox",
|
||||
"description": "MCP Toolbox for Databases enables your agent to connect to your database.",
|
||||
"title": "MCP Toolbox",
|
||||
@@ -14,11 +14,11 @@
|
||||
"url": "https://github.com/googleapis/genai-toolbox",
|
||||
"source": "github"
|
||||
},
|
||||
"version": "0.24.0",
|
||||
"version": "0.25.0",
|
||||
"packages": [
|
||||
{
|
||||
"registryType": "oci",
|
||||
"identifier": "us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:0.24.0",
|
||||
"identifier": "us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:0.25.0",
|
||||
"transport": {
|
||||
"type": "streamable-http",
|
||||
"url": "http://{host}:{port}/mcp"
|
||||
|
||||
@@ -194,7 +194,7 @@ func runAlloyDBToolGetTest(t *testing.T) {
|
||||
"description": "Simple tool to test end to end functionality.",
|
||||
"parameters": []any{
|
||||
map[string]any{"name": "project", "type": "string", "description": "The GCP project ID to list clusters for.", "required": true, "authSources": []any{}},
|
||||
map[string]any{"name": "location", "type": "string", "description": "Optional: The location to list clusters in (e.g., 'us-central1'). Use '-' to list clusters across all locations.(Default: '-')", "required": false, "authSources": []any{}},
|
||||
map[string]any{"name": "location", "type": "string", "description": "Optional: The location to list clusters in (e.g., 'us-central1'). Use '-' to list clusters across all locations.(Default: '-')", "required": false, "default": "-", "authSources": []any{}},
|
||||
},
|
||||
"authRequired": []any{},
|
||||
},
|
||||
|
||||
@@ -431,6 +431,7 @@ func TestLooker(t *testing.T) {
|
||||
"description": "The filters for the query",
|
||||
"name": "filters",
|
||||
"required": false,
|
||||
"default": map[string]any{},
|
||||
"type": "object",
|
||||
},
|
||||
map[string]any{
|
||||
@@ -446,6 +447,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "pivots",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"default": []any{},
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -460,6 +462,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "sorts",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"default": []any{},
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -467,6 +470,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "limit",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"default": float64(500),
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -519,6 +523,7 @@ func TestLooker(t *testing.T) {
|
||||
"description": "The filters for the query",
|
||||
"name": "filters",
|
||||
"required": false,
|
||||
"default": map[string]any{},
|
||||
"type": "object",
|
||||
},
|
||||
map[string]any{
|
||||
@@ -534,6 +539,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "pivots",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"default": []any{},
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -548,6 +554,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "sorts",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"default": []any{},
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -555,6 +562,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "limit",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"default": float64(500),
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -607,6 +615,7 @@ func TestLooker(t *testing.T) {
|
||||
"description": "The filters for the query",
|
||||
"name": "filters",
|
||||
"required": false,
|
||||
"default": map[string]any{},
|
||||
"type": "object",
|
||||
},
|
||||
map[string]any{
|
||||
@@ -622,6 +631,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "pivots",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"default": []any{},
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -636,6 +646,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "sorts",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"default": []any{},
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -643,6 +654,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "limit",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"default": float64(500),
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -658,6 +670,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "vis_config",
|
||||
"required": false,
|
||||
"type": "object",
|
||||
"default": map[string]any{},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -675,6 +688,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "title",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"default": "",
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -682,6 +696,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "desc",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"default": "",
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -689,6 +704,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "limit",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"default": float64(100),
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -696,6 +712,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "offset",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"default": float64(0),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -741,6 +758,7 @@ func TestLooker(t *testing.T) {
|
||||
"description": "The filters for the query",
|
||||
"name": "filters",
|
||||
"required": false,
|
||||
"default": map[string]any{},
|
||||
"type": "object",
|
||||
},
|
||||
map[string]any{
|
||||
@@ -756,6 +774,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "pivots",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"default": []any{},
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -770,6 +789,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "sorts",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"default": []any{},
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -777,6 +797,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "limit",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"default": float64(500),
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -797,6 +818,7 @@ func TestLooker(t *testing.T) {
|
||||
"description": "The description of the Look",
|
||||
"name": "description",
|
||||
"required": false,
|
||||
"default": "",
|
||||
"type": "string",
|
||||
},
|
||||
map[string]any{
|
||||
@@ -804,6 +826,7 @@ func TestLooker(t *testing.T) {
|
||||
"description": "The folder id where the Look will be created. Leave blank to use the user's personal folder",
|
||||
"name": "folder",
|
||||
"required": false,
|
||||
"default": "",
|
||||
"type": "string",
|
||||
},
|
||||
map[string]any{
|
||||
@@ -813,6 +836,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "vis_config",
|
||||
"required": false,
|
||||
"type": "object",
|
||||
"default": map[string]any{},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -830,6 +854,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "title",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"default": "",
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -837,6 +862,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "desc",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"default": "",
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -844,6 +870,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "limit",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"default": float64(100),
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -851,6 +878,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "offset",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"default": float64(0),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -875,6 +903,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "description",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"default": "",
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -882,6 +911,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "folder",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"default": "",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -920,6 +950,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "filter_type",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"default": "field_filter",
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -955,6 +986,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "allow_multiple_values",
|
||||
"required": false,
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -962,6 +994,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "required",
|
||||
"required": false,
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1007,6 +1040,7 @@ func TestLooker(t *testing.T) {
|
||||
"description": "The filters for the query",
|
||||
"name": "filters",
|
||||
"required": false,
|
||||
"default": map[string]any{},
|
||||
"type": "object",
|
||||
},
|
||||
map[string]any{
|
||||
@@ -1022,6 +1056,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "pivots",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"default": []any{},
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -1036,6 +1071,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "sorts",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"default": []any{},
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -1043,6 +1079,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "limit",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"default": float64(500),
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -1064,6 +1101,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "title",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"default": "",
|
||||
},
|
||||
map[string]any{
|
||||
"additionalProperties": true,
|
||||
@@ -1072,6 +1110,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "vis_config",
|
||||
"required": false,
|
||||
"type": "object",
|
||||
"default": map[string]any{},
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -1083,6 +1122,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "dashboard_filter",
|
||||
"required": false,
|
||||
"type": "object",
|
||||
"default": map[string]any{},
|
||||
},
|
||||
"name": "dashboard_filters",
|
||||
"required": false,
|
||||
@@ -1181,6 +1221,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "timeframe",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"default": float64(90),
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -1188,6 +1229,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "min_queries",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"default": float64(0),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1212,6 +1254,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "project",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"default": "",
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -1219,6 +1262,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "model",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"default": "",
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -1226,6 +1270,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "explore",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"default": "",
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -1233,6 +1278,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "timeframe",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"default": float64(90),
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -1240,6 +1286,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "min_queries",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"default": float64(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1257,6 +1304,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "devMode",
|
||||
"required": false,
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1410,6 +1458,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "type",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"default": "",
|
||||
},
|
||||
map[string]any{
|
||||
"authSources": []any{},
|
||||
@@ -1417,6 +1466,7 @@ func TestLooker(t *testing.T) {
|
||||
"name": "id",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"default": "",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -165,6 +165,7 @@ func TestNeo4jToolEndpoints(t *testing.T) {
|
||||
"type": "boolean",
|
||||
"required": false,
|
||||
"description": "If set to true, the query will be validated and information about the execution will be returned without running the query. Defaults to false.",
|
||||
"default": false,
|
||||
"authSources": []any{},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user