Skip to content

feat(migrate): convert toolset to group kind during migration - #3704

Merged
twishabansal merged 38 commits into
mainfrom
feat/groups-migrate-toolset
Aug 10, 2026
Merged

feat(migrate): convert toolset to group kind during migration#3704
twishabansal merged 38 commits into
mainfrom
feat/groups-migrate-toolset

Conversation

@twishabansal

@twishabansal twishabansal commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Description

Parsing a toolset as a group is stricter than the old toolset path, so three behaviors change:

  • A description on a toolset is dropped with a warning: a toolset has no description of its own, so promoting one would publish a description the collection never declared. Use kind: group to keep it.
  • Unknown fields are rejected at startup rather than silently ignored.
  • A kind: toolset and kind: group sharing a name is a duplicate-name error; it used to warn and let the group win.

Docs under configuration/groups/ and configuration/toolsets/ said toolsets need "no migration", and now list these three changes.

Stacked on #3764, which converts the two cloud-storage toolsets carrying descriptions so those descriptions apply rather than being dropped by the rule above.

twishabansal and others added 21 commits July 13, 2026 09:25
…ews (#3488)

## Description

First slice of the toolsets→groups evolution. Introduces
`internal/group` as the unified source of truth for a named collection
of **tools and prompts**, without changing any existing behavior yet.
…3569)

## Description

Makes `internal/group` the source of truth in `ResourceManager` and
derives the `tools.Toolset` / `prompts.Promptset` views from it.

Stacked on #3488

---------

Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
## Description

The MCP route is `/{toolsetName}`, so `promptsetName` was always empty
and `GetPromptset("")` returned every prompt regardless of which group
the client connected to. This fixes `prompts/list` (and `prompts/get`)
to scope prompts to the connected group by resolving the group from the
URL name and serving its derived promptset. `tools/list` is unchanged —
tools were already scoped by the toolset name.

### Old vs new response

Given two groups `docs` (prompt `summarize`) and `i18n` (prompt
`translate`), connected to `/mcp/docs`:

**`prompts/list`** request:

```json
{ "jsonrpc": "2.0", "id": 1, "method": "prompts/list" }
```

Old (bug — returns every prompt on the server):

```json
{ "jsonrpc": "2.0", "id": 1, "result": { "prompts": [
  { "name": "summarize", "description": "Summarize a document" },
  { "name": "translate", "description": "Translate text" }
] } }
```

New (scoped to the `docs` group):

```json
{ "jsonrpc": "2.0", "id": 1, "result": { "prompts": [
  { "name": "summarize", "description": "Summarize a document" }
] } }
```

**`prompts/get`** for a prompt in another group (`translate`, which
belongs to `i18n`):

Old (bug — succeeds, since the default all-prompts set was used):

```json
{ "jsonrpc": "2.0", "id": 2, "result": { "description": "Translate text", "messages": [ ... ] } }
```

New (correctly rejected):

```json
{ "jsonrpc": "2.0", "id": 2, "error": {
  "code": -32602,
  "message": "invalid prompt name: prompt with name \"translate\" does not exist"
} }
```

Stacked on #3575

---------

Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
## Description

Adds two Toolbox methods for group introspection, implemented across all
five MCP protocol versions (v20241105, v20250326, v20250618, v20251125,
vdraft).

- **`groups/list`** — returns named groups (name + description). The
default nameless group is omitted and results are sorted by name.
- **`groups/get`** — returns a named group's tools and prompts. Unknown
names return `-32602` (INVALID_PARAMS); the default group is reachable
via an empty name.

### `groups/list`

Request:
```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "groups/list"
}
```
Response:
```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "groups": [
      { "name": "set_one" },
      { "name": "set_two" }
    ]
  }
}
```

### `groups/get`

Request:
```json
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "groups/get",
  "params": { "name": "set_two" }
}
```
Response:
```json
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "name": "set_two",
    "tools": [
      {
        "name": "tool_b",
        "description": "Tool B does B.",
        "inputSchema": { "type": "object", "properties": {}, "required": [] }
      },
      {
        "name": "tool_a",
        "description": "Tool A does A.",
        "inputSchema": { "type": "object", "properties": {}, "required": [] }
      }
    ],
    "prompts": []
  }
}
```

Unknown group:
```json
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "groups/get",
  "params": { "name": "nope" }
}
```
```json
{
  "jsonrpc": "2.0",
  "id": 3,
  "error": {
    "code": -32602,
    "message": "invalid group name: group with name \"nope\" does not exist"
  }
}
```

Stacked on #3576

---------

Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
Stacked on #3575

---------

Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
# Conflicts:
#	cmd/internal/config.go
#	cmd/internal/invoke/command.go
#	cmd/internal/skills/command.go
#	cmd/root.go
#	internal/server/api.go
#	internal/server/common_test.go
#	internal/server/config.go
#	internal/server/mcp.go
#	internal/server/mcp/mcp.go
#	internal/server/mcp/v20241105/method.go
#	internal/server/mcp/v20241105/method_test.go
#	internal/server/mcp/v20250326/method.go
#	internal/server/mcp/v20250326/method_test.go
#	internal/server/mcp/v20250618/method.go
#	internal/server/mcp/v20250618/method_test.go
#	internal/server/mcp/v20251125/method.go
#	internal/server/mcp/v20251125/method_test.go
#	internal/server/mcp/vdraft/method.go
#	internal/server/mcp/vdraft/method_test.go
#	internal/server/mcp_test.go
#	internal/server/primitives/primitives.go
#	internal/server/primitives/primitives_test.go
#	internal/server/server.go
#	internal/server/server_test.go
#	internal/tools/cloudgda/cloudgda_test.go
…ip (#3629)

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
## Description

Reinstates the `(!present || rawName == nil)` guard in
`UnmarshalResourceConfig` that was accidentally dropped during the merge
of the groups stack into `feat/groups`.

Without the guard, a config like:

```yaml
kind: group
name: 123
```

would silently default to the empty (default) group instead of returning
a parse error. Deeven Seru flagged this in the review of #3575.

The fix ensures non-string name values (`name: 123`, `name: true`) are
rejected with `"missing 'name' field or it is not a string"`, while
legitimately absent or null names are still accepted as the default
group.

Adds regression tests to `TestParseConfigGroupNameValidation` covering
all four cases.
## Description

Follow-up to #3575

Previously only `kind: group` rejected duplicate names. Every other
resource kind — `source`, `authService`, `tool`, `toolset`,
`embeddingModel`, and `prompt` silently kept the *last* declaration when
a name was reused within a config, so a duplicated resource would be
dropped with no error.

This makes duplicate detection uniform: `UnmarshalResourceConfig` now
returns `"<kind> %q declared more than once"` for any repeated name,
matching the behavior already in place for groups.

Stacked on top of #3575 

Fixed #3648

---------

Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
## Description

Follow-up to #3583, adding the telemetry that was deferred out of the
introspection PR to keep it focused.

This mirrors the existing `prompts/get` instrumentation for `groups/get`
across all five MCP version packages (`v20241105`, `v20250326`,
`v20250618`, `v20251125`, `vdraft`)

---------

Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
## Description

Stacked on top of #3605.

The prompts coverage check in #3605 fails at **69.2%** (needs **80%**).
Investigating why turned up the real cause: the `prompts.Promptset`
layer is **dead code**.

Groups are the source of truth for prompt scoping. `prompts/list` and
`prompts/get` resolve entirely from `group.Group`
(`GenerateListPromptsResult` and `group.ContainsPrompt`).
`PrimitiveManager.GetPromptset` — the only caller of
`prompts.Promptset.Initialize` — has no production caller itself, so
`Promptset` / `PromptsetConfig` / `PromptsetManifest` and `GetPromptset`
are never used.

Rather than add tests for unreachable code to satisfy the gate, this PR
removes the orphaned layer:
- `internal/prompts/promptsets.go` (+ its unit test)
- `PrimitiveManager.GetPromptset`
- the promptset scaffolding in `testutils.SetUpResources` and the two
server tests

Dropping the uncovered promptset statements brings
`./internal/prompts/...` coverage to **84.0%**, clearing the gate with
no new tests.

**Groups still contain prompts** — this only removes the unused parallel
view; `group.Group.PromptNames` / `ContainsPrompt` and the MCP prompt
handlers are unchanged.
## Description

Stacked on top of #3641.

Companion cleanup to the promptset removal.
`PrimitiveManager.GetToolset` is the toolset twin of the `GetPromptset`
dead code removed in #3641 — and it is equally orphaned.

Groups are the source of truth for named collections. The REST
`/toolset/{name}` path renders directly from
`group.Group.ToolsetManifest`, and MCP tool listing resolves from
`group.Group.ToolNames` / `ContainsTool`. Nothing in production calls
`GetToolset`, so the "materialize a `tools.Toolset` view from the group
on demand" helper is never reached.

This PR removes the orphaned method and its now-dangling test
assertions.
# Conflicts:
#	internal/server/mcp/vdraft/method_test.go
#	internal/server/server.go
…gated extension release (#3670)

## Description

Makes `groups/list` / `groups/get` unreachable in `feat/groups` so
groups ships as Part A only (scoping). These methods must be gated
behind the `com.google.cloud/toolbox` extension; shipping them reachable
now and gating later would be a breaking change.

Removes only the `case GROUPS_LIST` / `case GROUPS_GET` dispatch arms in
`ProcessMethod` across all 5 MCP versions (methods now return
`METHOD_NOT_FOUND`). All other Part B code — types, handlers, manifests,
telemetry, tests — is retained and still unit-tested. Re-enabling later
= re-add the arms alongside the gate. Also trims the docs describing
these methods.
The migrate command now rewrites toolsets to groups for both nested and
already-flat inputs. The conversion is opt-in via a ConvertConfig flag so
the runtime parse path leaves toolsets untouched.
@twishabansal
twishabansal requested a review from a team as a code owner July 24, 2026 06:10
@twishabansal twishabansal added the do not merge Indicates a pull request not ready for merge, due to either quality or timing. label Jul 24, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for migrating toolsets to groups during configuration migration. It updates the ConvertConfig function to accept a migrateToolset boolean flag, which, when enabled, rewrites both nested and flat toolset configurations to the group kind. The migrate command has been updated to pass true for this flag, and comprehensive unit and integration tests have been added to verify the migration behavior. There are no review comments, so I have no additional feedback to provide.

Add a migrate subcommand entry to the CLI reference and a migration note
to the groups doc pointing users to toolbox migrate.
Base automatically changed from feat/groups to main July 24, 2026 17:54
@twishabansal twishabansal removed the do not merge Indicates a pull request not ready for merge, due to either quality or timing. label Jul 27, 2026
twishabansal and others added 4 commits August 3, 2026 12:22
The runtime already folds every kind: toolset into a group config, so gating
the rewrite behind a flag only preserved two ways the toolset path was looser:
unknown fields were silently dropped, and a toolset/group name clash warned
instead of erroring. Both now behave like groups.

A toolset has no description of its own -- UnmarshalYAMLToolsetConfig keeps
only the tools list -- so a description on one is dropped on conversion rather
than promoted, which would otherwise publish a description for a collection
that never declared one.
Both collections carry a description, but a kind: toolset has no description
field -- UnmarshalYAMLToolsetConfig keeps only the tools list -- so the text
was parsed and silently discarded. Declaring them as kind: group makes the
descriptions reach clients.
@twishabansal
twishabansal changed the base branch from main to fix/cloud-storage-group-kind August 3, 2026 09:59
twishabansal and others added 5 commits August 4, 2026 08:05
A description written on a nested map-form toolset bypassed the strip and
was promoted onto the resulting group. Drop it on that path too, warn on
both, and stop mutating the caller's MapSlice while rewriting the kind.

Correct the docs that claimed toolsets keep working unchanged: they are
now parsed as groups, so descriptions are dropped, unknown fields are
rejected, and a toolset/group name clash is a duplicate-name error.
The rewrite lived in two places — the nested switch and a flat-only helper —
so the two spellings could drift, and they did. Flatten first and emit
kind: toolset as before, then rewrite to group on every doc once it is flat.

transformDocs and processValue return to their original form, leaving the
shared nested-to-flat path untouched by this change.
The multi-kind nested cases already assert that toolsets emit as groups
alongside every other kind, and the description-drop cases already cover
the plain rewrite. Fold the two end-to-end migrate tests into one that
exercises all three toolset spellings.

Also drop the cli.md migrate reference: it documents flags and behavior
that predate this change.
@twishabansal

Copy link
Copy Markdown
Contributor Author

Hi @Yuan325

The previous version rewrote the toolset kind in two places: once for nested input, once for already-flat docs. I realised it makes more sense to have two sequential passes instead of one forked pass: transformDocs flattens nested input exactly as before and still emits kind: toolset, then migrateToolsetKind rewrites the kind on every doc once it's flat. Both shapes converge on a single function.

This seems to have made the code changes simpler and more robust. Let me know what you think!

@twishabansal
twishabansal requested a review from Yuan325 August 4, 2026 09:17
Comment thread cmd/internal/config.go Outdated
Comment thread cmd/internal/config.go Outdated
Comment thread cmd/internal/config.go Outdated

@Yuan325 Yuan325 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, feel free to merge after resolving the comments :)

Index name alongside kind and description in the pass that already runs,
rewrite the kind through kindIndex instead of a second loop, and drop
mapSliceString and warnDescriptionDropped, which each had a single caller.

The copy of the input doc is kept, now as slices.Clone: ConvertConfig
passes the slice it is still ranging over, so deleting the description in
place would shift a zeroed element under that loop.
Base automatically changed from fix/cloud-storage-group-kind to main August 10, 2026 06:39
@twishabansal
twishabansal merged commit 0adeaa5 into main Aug 10, 2026
33 checks passed
@twishabansal
twishabansal deleted the feat/groups-migrate-toolset branch August 10, 2026 07:06
@github-actions

Copy link
Copy Markdown
Contributor

🧨 Preview deployments removed.

Cloudflare Pages environments for pr-3704 have been deleted.

github-actions Bot pushed a commit that referenced this pull request Aug 10, 2026
…#3704)

## Description

Parsing a toolset as a group is stricter than the old toolset path, so
three behaviors change:

- A `description` on a toolset is **dropped** with a warning: a toolset
has no description of its own, so promoting one would publish a
description the collection never declared. Use `kind: group` to keep it.
- Unknown fields are **rejected** at startup rather than silently
ignored.
- A `kind: toolset` and `kind: group` sharing a name is a
**duplicate-name error**; it used to warn and let the group win.

Docs under `configuration/groups/` and `configuration/toolsets/` said
toolsets need "no migration", and now list these three changes.

Stacked on #3764, which converts the two cloud-storage toolsets carrying
descriptions so those descriptions apply rather than being dropped by
the rule above.

---------

Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> 0adeaa5
github-actions Bot pushed a commit to Jaleel-zhu/genai-toolbox that referenced this pull request Aug 10, 2026
…googleapis#3704)

## Description

Parsing a toolset as a group is stricter than the old toolset path, so
three behaviors change:

- A `description` on a toolset is **dropped** with a warning: a toolset
has no description of its own, so promoting one would publish a
description the collection never declared. Use `kind: group` to keep it.
- Unknown fields are **rejected** at startup rather than silently
ignored.
- A `kind: toolset` and `kind: group` sharing a name is a
**duplicate-name error**; it used to warn and let the group win.

Docs under `configuration/groups/` and `configuration/toolsets/` said
toolsets need "no migration", and now list these three changes.

Stacked on googleapis#3764, which converts the two cloud-storage toolsets carrying
descriptions so those descriptions apply rather than being dropped by
the rule above.

---------

Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> 0adeaa5
github-actions Bot pushed a commit to pepe57/genai-toolbox that referenced this pull request Aug 10, 2026
…googleapis#3704)

## Description

Parsing a toolset as a group is stricter than the old toolset path, so
three behaviors change:

- A `description` on a toolset is **dropped** with a warning: a toolset
has no description of its own, so promoting one would publish a
description the collection never declared. Use `kind: group` to keep it.
- Unknown fields are **rejected** at startup rather than silently
ignored.
- A `kind: toolset` and `kind: group` sharing a name is a
**duplicate-name error**; it used to warn and let the group win.

Docs under `configuration/groups/` and `configuration/toolsets/` said
toolsets need "no migration", and now list these three changes.

Stacked on googleapis#3764, which converts the two cloud-storage toolsets carrying
descriptions so those descriptions apply rather than being dropped by
the rule above.

---------

Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> 0adeaa5
Yuan325 added a commit that referenced this pull request Aug 14, 2026
🤖 I have created a release *beep* *boop*
---


##
[1.9.0](v1.8.0...v1.9.0)
(2026-08-14)


### Features

* **groups:** Add ttlMs and cacheScope customization to config
([#3805](#3805))
([a5d4947](a5d4947))
* **migrate:** Convert toolset to group kind during migration
([#3704](#3704))
([0adeaa5](0adeaa5))
* **server/mcp:** Introduce generic client extension registry
([#3723](#3723))
([016245c](016245c))
* **skill:** Add review-prs skill for mcp-toolbox
([#3743](#3743))
([5b7bacc](5b7bacc))
* **source/bigquery:** Add apiEndpoint field to override BigQuery API
host ([#3437](#3437))
([4da1600](4da1600))
* **source/databaseinsights:** Add databaseinsights source
([#3461](#3461))
([3b9615d](3b9615d))
* **sources/spanner:** Rename execute_sql_dql to execute_sql_readonly
([#3776](#3776))
([cf5a0c8](cf5a0c8))
* **tools/bigtable:** Add admin lifecycle and listing tools
([#3596](#3596))
([801d589](801d589))
* **tools/bigtable:** Bigtable-list-schemas MCP tool
([#3683](#3683))
([9228c61](9228c61))
* **tools/databaseinsights:** Add Advanced Query Insights tools for
AlloyDB ([#3722](#3722))
([74d18ae](74d18ae))
* **tools/looker:** Add additional tools to allow dashboards to be
modified, and their layouts altered.
([#3597](#3597))
([b2b80fb](b2b80fb))
* **tools:** Add cloud-sql-connect-gce for pg, mysql, mssql
([#3740](#3740))
([ca58fa4](ca58fa4))


### Bug Fixes

* **auth/mcp:** Derive PRM URL from Toolbox URL
([#3765](#3765))
([aa30842](aa30842))
* **config:** Ignore environment variables in YAML comments
([#3807](#3807))
([79aa732](79aa732)),
refs [#3793](#3793)
* **mcp:** Return Tool execution error for invalid input param
([#3799](#3799))
([8120197](8120197))
* **prebuilt/cloud-storage:** Declare tool collections as groups
([#3764](#3764))
([7d468be](7d468be))
* **server/mcp:** Disallow client overriding URL bound parameters
([#3798](#3798))
([f15a9c7](f15a9c7))
* **server:** Avoid a nil-flusher panic in the SSE handler
([#3520](#3520))
([947f42f](947f42f))
* **tools/bigquery:** Keep the provider error classification in
bigquery-execute-sql
([#3738](#3738))
([42570b8](42570b8))
* **tools/looker:** Scope the filters quoting rule to values in query
description
([#3788](#3788))
([78eb0b8](78eb0b8))
* **util:** Convert exponent-form JSON numbers in ConvertNumbers
([#3730](#3730))
([e9713ee](e9713ee))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
github-actions Bot pushed a commit that referenced this pull request Aug 14, 2026
🤖 I have created a release *beep* *boop*
---

##
[1.9.0](v1.8.0...v1.9.0)
(2026-08-14)

### Features

* **groups:** Add ttlMs and cacheScope customization to config
([#3805](#3805))
([a5d4947](a5d4947))
* **migrate:** Convert toolset to group kind during migration
([#3704](#3704))
([0adeaa5](0adeaa5))
* **server/mcp:** Introduce generic client extension registry
([#3723](#3723))
([016245c](016245c))
* **skill:** Add review-prs skill for mcp-toolbox
([#3743](#3743))
([5b7bacc](5b7bacc))
* **source/bigquery:** Add apiEndpoint field to override BigQuery API
host ([#3437](#3437))
([4da1600](4da1600))
* **source/databaseinsights:** Add databaseinsights source
([#3461](#3461))
([3b9615d](3b9615d))
* **sources/spanner:** Rename execute_sql_dql to execute_sql_readonly
([#3776](#3776))
([cf5a0c8](cf5a0c8))
* **tools/bigtable:** Add admin lifecycle and listing tools
([#3596](#3596))
([801d589](801d589))
* **tools/bigtable:** Bigtable-list-schemas MCP tool
([#3683](#3683))
([9228c61](9228c61))
* **tools/databaseinsights:** Add Advanced Query Insights tools for
AlloyDB ([#3722](#3722))
([74d18ae](74d18ae))
* **tools/looker:** Add additional tools to allow dashboards to be
modified, and their layouts altered.
([#3597](#3597))
([b2b80fb](b2b80fb))
* **tools:** Add cloud-sql-connect-gce for pg, mysql, mssql
([#3740](#3740))
([ca58fa4](ca58fa4))

### Bug Fixes

* **auth/mcp:** Derive PRM URL from Toolbox URL
([#3765](#3765))
([aa30842](aa30842))
* **config:** Ignore environment variables in YAML comments
([#3807](#3807))
([79aa732](79aa732)),
refs [#3793](#3793)
* **mcp:** Return Tool execution error for invalid input param
([#3799](#3799))
([8120197](8120197))
* **prebuilt/cloud-storage:** Declare tool collections as groups
([#3764](#3764))
([7d468be](7d468be))
* **server/mcp:** Disallow client overriding URL bound parameters
([#3798](#3798))
([f15a9c7](f15a9c7))
* **server:** Avoid a nil-flusher panic in the SSE handler
([#3520](#3520))
([947f42f](947f42f))
* **tools/bigquery:** Keep the provider error classification in
bigquery-execute-sql
([#3738](#3738))
([42570b8](42570b8))
* **tools/looker:** Scope the filters quoting rule to values in query
description
([#3788](#3788))
([78eb0b8](78eb0b8))
* **util:** Convert exponent-form JSON numbers in ConvertNumbers
([#3730](#3730))
([e9713ee](e9713ee))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com> 5de8f13
github-actions Bot pushed a commit to rodineyw/mcp-toolbox that referenced this pull request Aug 14, 2026
🤖 I have created a release *beep* *boop*
---

##
[1.9.0](googleapis/mcp-toolbox@v1.8.0...v1.9.0)
(2026-08-14)

### Features

* **groups:** Add ttlMs and cacheScope customization to config
([googleapis#3805](googleapis#3805))
([a5d4947](googleapis@a5d4947))
* **migrate:** Convert toolset to group kind during migration
([googleapis#3704](googleapis#3704))
([0adeaa5](googleapis@0adeaa5))
* **server/mcp:** Introduce generic client extension registry
([googleapis#3723](googleapis#3723))
([016245c](googleapis@016245c))
* **skill:** Add review-prs skill for mcp-toolbox
([googleapis#3743](googleapis#3743))
([5b7bacc](googleapis@5b7bacc))
* **source/bigquery:** Add apiEndpoint field to override BigQuery API
host ([googleapis#3437](googleapis#3437))
([4da1600](googleapis@4da1600))
* **source/databaseinsights:** Add databaseinsights source
([googleapis#3461](googleapis#3461))
([3b9615d](googleapis@3b9615d))
* **sources/spanner:** Rename execute_sql_dql to execute_sql_readonly
([googleapis#3776](googleapis#3776))
([cf5a0c8](googleapis@cf5a0c8))
* **tools/bigtable:** Add admin lifecycle and listing tools
([googleapis#3596](googleapis#3596))
([801d589](googleapis@801d589))
* **tools/bigtable:** Bigtable-list-schemas MCP tool
([googleapis#3683](googleapis#3683))
([9228c61](googleapis@9228c61))
* **tools/databaseinsights:** Add Advanced Query Insights tools for
AlloyDB ([googleapis#3722](googleapis#3722))
([74d18ae](googleapis@74d18ae))
* **tools/looker:** Add additional tools to allow dashboards to be
modified, and their layouts altered.
([googleapis#3597](googleapis#3597))
([b2b80fb](googleapis@b2b80fb))
* **tools:** Add cloud-sql-connect-gce for pg, mysql, mssql
([googleapis#3740](googleapis#3740))
([ca58fa4](googleapis@ca58fa4))

### Bug Fixes

* **auth/mcp:** Derive PRM URL from Toolbox URL
([googleapis#3765](googleapis#3765))
([aa30842](googleapis@aa30842))
* **config:** Ignore environment variables in YAML comments
([googleapis#3807](googleapis#3807))
([79aa732](googleapis@79aa732)),
refs [googleapis#3793](googleapis#3793)
* **mcp:** Return Tool execution error for invalid input param
([googleapis#3799](googleapis#3799))
([8120197](googleapis@8120197))
* **prebuilt/cloud-storage:** Declare tool collections as groups
([googleapis#3764](googleapis#3764))
([7d468be](googleapis@7d468be))
* **server/mcp:** Disallow client overriding URL bound parameters
([googleapis#3798](googleapis#3798))
([f15a9c7](googleapis@f15a9c7))
* **server:** Avoid a nil-flusher panic in the SSE handler
([googleapis#3520](googleapis#3520))
([947f42f](googleapis@947f42f))
* **tools/bigquery:** Keep the provider error classification in
bigquery-execute-sql
([googleapis#3738](googleapis#3738))
([42570b8](googleapis@42570b8))
* **tools/looker:** Scope the filters quoting rule to values in query
description
([googleapis#3788](googleapis#3788))
([78eb0b8](googleapis@78eb0b8))
* **util:** Convert exponent-form JSON numbers in ConvertNumbers
([googleapis#3730](googleapis#3730))
([e9713ee](googleapis@e9713ee))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com> 5de8f13
github-actions Bot pushed a commit to Jaleel-zhu/genai-toolbox that referenced this pull request Aug 14, 2026
🤖 I have created a release *beep* *boop*
---

##
[1.9.0](googleapis/mcp-toolbox@v1.8.0...v1.9.0)
(2026-08-14)

### Features

* **groups:** Add ttlMs and cacheScope customization to config
([googleapis#3805](googleapis#3805))
([a5d4947](googleapis@a5d4947))
* **migrate:** Convert toolset to group kind during migration
([googleapis#3704](googleapis#3704))
([0adeaa5](googleapis@0adeaa5))
* **server/mcp:** Introduce generic client extension registry
([googleapis#3723](googleapis#3723))
([016245c](googleapis@016245c))
* **skill:** Add review-prs skill for mcp-toolbox
([googleapis#3743](googleapis#3743))
([5b7bacc](googleapis@5b7bacc))
* **source/bigquery:** Add apiEndpoint field to override BigQuery API
host ([googleapis#3437](googleapis#3437))
([4da1600](googleapis@4da1600))
* **source/databaseinsights:** Add databaseinsights source
([googleapis#3461](googleapis#3461))
([3b9615d](googleapis@3b9615d))
* **sources/spanner:** Rename execute_sql_dql to execute_sql_readonly
([googleapis#3776](googleapis#3776))
([cf5a0c8](googleapis@cf5a0c8))
* **tools/bigtable:** Add admin lifecycle and listing tools
([googleapis#3596](googleapis#3596))
([801d589](googleapis@801d589))
* **tools/bigtable:** Bigtable-list-schemas MCP tool
([googleapis#3683](googleapis#3683))
([9228c61](googleapis@9228c61))
* **tools/databaseinsights:** Add Advanced Query Insights tools for
AlloyDB ([googleapis#3722](googleapis#3722))
([74d18ae](googleapis@74d18ae))
* **tools/looker:** Add additional tools to allow dashboards to be
modified, and their layouts altered.
([googleapis#3597](googleapis#3597))
([b2b80fb](googleapis@b2b80fb))
* **tools:** Add cloud-sql-connect-gce for pg, mysql, mssql
([googleapis#3740](googleapis#3740))
([ca58fa4](googleapis@ca58fa4))

### Bug Fixes

* **auth/mcp:** Derive PRM URL from Toolbox URL
([googleapis#3765](googleapis#3765))
([aa30842](googleapis@aa30842))
* **config:** Ignore environment variables in YAML comments
([googleapis#3807](googleapis#3807))
([79aa732](googleapis@79aa732)),
refs [googleapis#3793](googleapis#3793)
* **mcp:** Return Tool execution error for invalid input param
([googleapis#3799](googleapis#3799))
([8120197](googleapis@8120197))
* **prebuilt/cloud-storage:** Declare tool collections as groups
([googleapis#3764](googleapis#3764))
([7d468be](googleapis@7d468be))
* **server/mcp:** Disallow client overriding URL bound parameters
([googleapis#3798](googleapis#3798))
([f15a9c7](googleapis@f15a9c7))
* **server:** Avoid a nil-flusher panic in the SSE handler
([googleapis#3520](googleapis#3520))
([947f42f](googleapis@947f42f))
* **tools/bigquery:** Keep the provider error classification in
bigquery-execute-sql
([googleapis#3738](googleapis#3738))
([42570b8](googleapis@42570b8))
* **tools/looker:** Scope the filters quoting rule to values in query
description
([googleapis#3788](googleapis#3788))
([78eb0b8](googleapis@78eb0b8))
* **util:** Convert exponent-form JSON numbers in ConvertNumbers
([googleapis#3730](googleapis#3730))
([e9713ee](googleapis@e9713ee))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com> 5de8f13
github-actions Bot pushed a commit to pepe57/genai-toolbox that referenced this pull request Aug 14, 2026
🤖 I have created a release *beep* *boop*
---

##
[1.9.0](googleapis/mcp-toolbox@v1.8.0...v1.9.0)
(2026-08-14)

### Features

* **groups:** Add ttlMs and cacheScope customization to config
([googleapis#3805](googleapis#3805))
([a5d4947](googleapis@a5d4947))
* **migrate:** Convert toolset to group kind during migration
([googleapis#3704](googleapis#3704))
([0adeaa5](googleapis@0adeaa5))
* **server/mcp:** Introduce generic client extension registry
([googleapis#3723](googleapis#3723))
([016245c](googleapis@016245c))
* **skill:** Add review-prs skill for mcp-toolbox
([googleapis#3743](googleapis#3743))
([5b7bacc](googleapis@5b7bacc))
* **source/bigquery:** Add apiEndpoint field to override BigQuery API
host ([googleapis#3437](googleapis#3437))
([4da1600](googleapis@4da1600))
* **source/databaseinsights:** Add databaseinsights source
([googleapis#3461](googleapis#3461))
([3b9615d](googleapis@3b9615d))
* **sources/spanner:** Rename execute_sql_dql to execute_sql_readonly
([googleapis#3776](googleapis#3776))
([cf5a0c8](googleapis@cf5a0c8))
* **tools/bigtable:** Add admin lifecycle and listing tools
([googleapis#3596](googleapis#3596))
([801d589](googleapis@801d589))
* **tools/bigtable:** Bigtable-list-schemas MCP tool
([googleapis#3683](googleapis#3683))
([9228c61](googleapis@9228c61))
* **tools/databaseinsights:** Add Advanced Query Insights tools for
AlloyDB ([googleapis#3722](googleapis#3722))
([74d18ae](googleapis@74d18ae))
* **tools/looker:** Add additional tools to allow dashboards to be
modified, and their layouts altered.
([googleapis#3597](googleapis#3597))
([b2b80fb](googleapis@b2b80fb))
* **tools:** Add cloud-sql-connect-gce for pg, mysql, mssql
([googleapis#3740](googleapis#3740))
([ca58fa4](googleapis@ca58fa4))

### Bug Fixes

* **auth/mcp:** Derive PRM URL from Toolbox URL
([googleapis#3765](googleapis#3765))
([aa30842](googleapis@aa30842))
* **config:** Ignore environment variables in YAML comments
([googleapis#3807](googleapis#3807))
([79aa732](googleapis@79aa732)),
refs [googleapis#3793](googleapis#3793)
* **mcp:** Return Tool execution error for invalid input param
([googleapis#3799](googleapis#3799))
([8120197](googleapis@8120197))
* **prebuilt/cloud-storage:** Declare tool collections as groups
([googleapis#3764](googleapis#3764))
([7d468be](googleapis@7d468be))
* **server/mcp:** Disallow client overriding URL bound parameters
([googleapis#3798](googleapis#3798))
([f15a9c7](googleapis@f15a9c7))
* **server:** Avoid a nil-flusher panic in the SSE handler
([googleapis#3520](googleapis#3520))
([947f42f](googleapis@947f42f))
* **tools/bigquery:** Keep the provider error classification in
bigquery-execute-sql
([googleapis#3738](googleapis#3738))
([42570b8](googleapis@42570b8))
* **tools/looker:** Scope the filters quoting rule to values in query
description
([googleapis#3788](googleapis#3788))
([78eb0b8](googleapis@78eb0b8))
* **util:** Convert exponent-form JSON numbers in ConvertNumbers
([googleapis#3730](googleapis#3730))
([e9713ee](googleapis@e9713ee))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com> 5de8f13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants