From d14ffb12523af8e60aa07eb4c4152dec37f2e6e2 Mon Sep 17 00:00:00 2001 From: Juexin Wang Date: Fri, 14 Aug 2026 16:48:58 -0700 Subject: [PATCH 1/5] chore: run toolbox via npx instead of the bundled binary --- .github/renovate.json5 | 16 +- .github/workflows/mirror-changelog.yml | 5 +- .../workflows/package-and-upload-assets.yml | 139 ------------------ .github/workflows/presubmit-tests.yml | 6 - README.md | 4 +- gemini-extension.json | 4 +- toolbox_version.txt | 1 - 7 files changed, 18 insertions(+), 157 deletions(-) delete mode 100644 .github/workflows/package-and-upload-assets.yml delete mode 100644 toolbox_version.txt diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 0533093..9b200fa 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -21,18 +21,20 @@ pinDigests: true, }, { - matchPackageNames: ['googleapis/mcp-toolbox'], - 'semanticCommitType': 'feat' + matchPackageNames: ['@toolbox-sdk/server'], + // Group the toolbox update under a stable branch name (renovate/toolbox). + groupName: 'toolbox', + semanticCommitType: 'feat', } ], customManagers: [ { + // Track the npm toolbox server pinned in the extension's MCP command. customType: "regex", - managerFilePatterns: ["/toolbox_version\\.txt$/"], - matchStrings: ["(?[\\d\\.]+)"], - datasourceTemplate: "github-releases", - packageNameTemplate: "googleapis/mcp-toolbox", - extractVersionTemplate: "^v(?.*)$", + managerFilePatterns: ["/gemini-extension\\.json$/"], + matchStrings: ["@toolbox-sdk/server@(?[\\d\\.]+)"], + datasourceTemplate: "npm", + depNameTemplate: "@toolbox-sdk/server", } ] } diff --git a/.github/workflows/mirror-changelog.yml b/.github/workflows/mirror-changelog.yml index 00689a9..9376e6c 100644 --- a/.github/workflows/mirror-changelog.yml +++ b/.github/workflows/mirror-changelog.yml @@ -20,7 +20,10 @@ on: jobs: add-release-notes: - if: github.actor == 'renovate-bot' && startsWith(github.head_ref, 'renovate/googleapis-mcp-toolbox') + # Renovate groups the npm toolbox update under groupName 'toolbox' (see + # renovate.json5), so its branch is renovate/toolbox. Release notes still come + # from googleapis/mcp-toolbox (same source repo), so the markers below are unchanged. + if: github.actor == 'renovate-bot' && startsWith(github.head_ref, 'renovate/toolbox') runs-on: ubuntu-latest permissions: pull-requests: write diff --git a/.github/workflows/package-and-upload-assets.yml b/.github/workflows/package-and-upload-assets.yml deleted file mode 100644 index 906a9b6..0000000 --- a/.github/workflows/package-and-upload-assets.yml +++ /dev/null @@ -1,139 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: Package and Upload Release Assets - -# Global variables -env: - PACKAGE_NAME: "bigquery-conversational-analytics" - FILES_TO_PACKAGE: "gemini-extension.json BIGQUERY_CONVERSATIONAL_ANALYTICS.md LICENSE tools.yaml" - GCS_BUCKET_URL: "https://storage.googleapis.com/mcp-toolbox-for-databases/geminicli" - -on: - release: - types: [created] - -jobs: - package: - name: Package for ${{ matrix.platform.os }}-${{ matrix.platform.arch }} - runs-on: ubuntu-latest - - strategy: - matrix: - platform: - - { os: "linux", arch: "x64", download_path_segment: "linux/amd64", binary_suffix: "", archive_extension: "tar.gz", archive_command: 'tar -czvf "${ARCHIVE_NAME}" -C staging .' } - - { os: "darwin", arch: "arm64", download_path_segment: "darwin/arm64", binary_suffix: "", archive_extension: "tar.gz", archive_command: 'tar -czvf "${ARCHIVE_NAME}" -C staging .' } - - { os: "darwin", arch: "x64", download_path_segment: "darwin/amd64", binary_suffix: "", archive_extension: "tar.gz", archive_command: 'tar -czvf "${ARCHIVE_NAME}" -C staging .' } - - { os: "win32", arch: "x64", download_path_segment: "windows/amd64", binary_suffix: ".exe", archive_extension: "zip", archive_command: '(cd staging && zip ../"${ARCHIVE_NAME}" *)' } - - steps: - - name: Checkout code at the new tag - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - with: - ref: ${{ github.event.release.tag_name }} - - - name: Set Dynamic Environment Variables - id: vars - run: | - echo "archive_name=${{ matrix.platform.os }}.${{ matrix.platform.arch }}.${{ env.PACKAGE_NAME }}.${{ matrix.platform.archive_extension }}" >> $GITHUB_OUTPUT - echo "source_binary=toolbox${{ matrix.platform.binary_suffix }}" >> $GITHUB_OUTPUT - - - name: Get Toolbox Version - id: get_toolbox_version - run: | - TOOLBOX_VERSION=$(cat toolbox_version.txt) - echo "Found toolbox version: ${TOOLBOX_VERSION}" - echo "TOOLBOX_VERSION=${TOOLBOX_VERSION}" >> $GITHUB_OUTPUT - - - name: Download Source Binary - env: - TOOLBOX_VERSION: ${{ steps.get_toolbox_version.outputs.TOOLBOX_VERSION }} - DOWNLOAD_PATH_SEGMENT: ${{ matrix.platform.download_path_segment }} - SOURCE_BINARY: ${{ steps.vars.outputs.source_binary }} - run: | - DOWNLOAD_URL="${GCS_BUCKET_URL}/v${TOOLBOX_VERSION}/${DOWNLOAD_PATH_SEGMENT}/${SOURCE_BINARY}" - - echo "Downloading binary from: ${DOWNLOAD_URL}" - curl -L --fail -o "${SOURCE_BINARY}" "${DOWNLOAD_URL}" - chmod +x ${SOURCE_BINARY} - - echo "Binary downloaded and prepared." - ls -l - - - name: Create release archive - id: create_archive - env: - ARCHIVE_COMMAND: ${{ matrix.platform.archive_command }} - ARCHIVE_NAME: ${{ steps.vars.outputs.archive_name }} - SOURCE_BINARY: ${{ steps.vars.outputs.source_binary }} - run: | - ARCHIVE_NAME="${{ matrix.platform.os }}.${{ matrix.platform.arch }}.${PACKAGE_NAME}.${{ matrix.platform.archive_extension }}" - SOURCE_BINARY="toolbox${{ matrix.platform.binary_suffix }}" - - echo "Packaging ${SOURCE_BINARY} into ${ARCHIVE_NAME}" - - mkdir staging - cp "${SOURCE_BINARY}" "staging/${SOURCE_BINARY}" - cp ${FILES_TO_PACKAGE} staging/ - - if [[ "${{ matrix.platform.os }}" == "win32" ]]; then - echo "Modifying gemini-extension.json for Windows..." - jq '(.mcpServers[].command) |= sub("toolbox$"; "toolbox.exe")' gemini-extension.json > staging/gemini-extension.json - echo "Modification complete." - fi - - echo "All assets staged." - ls -l staging - - # Create archive - eval "${ARCHIVE_COMMAND}" - echo "Created archive: ${ARCHIVE_NAME}" - echo "ARCHIVE_PATH=${ARCHIVE_NAME}" >> $GITHUB_OUTPUT - - - name: Upload archive as workflow artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 - with: - name: ${{ steps.vars.outputs.archive_name }} - path: ${{ steps.create_archive.outputs.ARCHIVE_PATH }} - - # This job gathers all archives and uploads them to the GitHub Release. - upload: - name: Upload all assets to release - runs-on: ubuntu-latest - needs: package - permissions: - contents: write - steps: - - name: Checkout code - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - - - name: Download all archives from workflow artifacts - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 - with: - path: release-archives - - - name: List downloaded files - run: | - echo "--- Downloaded files ---" - ls -R release-archives - echo "------------------------" - - - name: Upload all assets to GitHub Release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GITHUB_EVENT_RELEASE_TAG_NAME: ${{ github.event.release.tag_name }} - run: | - gh release upload \ - ${GITHUB_EVENT_RELEASE_TAG_NAME} \ - release-archives/*/* diff --git a/.github/workflows/presubmit-tests.yml b/.github/workflows/presubmit-tests.yml index 417bb6f..07f6a55 100644 --- a/.github/workflows/presubmit-tests.yml +++ b/.github/workflows/presubmit-tests.yml @@ -27,12 +27,6 @@ jobs: - name: Install Gemini CLI run: npm install @google/gemini-cli - - name: Install toolbox binary - run: | - VERSION=$(cat toolbox_version.txt) - curl -L -o toolbox "https://storage.googleapis.com/mcp-toolbox-for-databases/v${VERSION}/linux/amd64/toolbox" - chmod +x toolbox - - name: Install Extension run: npx gemini extensions validate . env: diff --git a/README.md b/README.md index 05bd447..086a80d 100644 --- a/README.md +++ b/README.md @@ -110,5 +110,5 @@ Common issues: * "failed to find default credentials: google: could not find default credentials.": Ensure [Application Default Credentials](https://cloud.google.com/docs/authentication/gcloud) are available in your environment. See [Set up Application Default Credentials](https://cloud.google.com/docs/authentication/external/set-up-adc) for more information. * "✖ Error during discovery for server: MCP error -32000: Connection closed": The database connection has not been established. Ensure your configuration is set via environment variables. -* "✖ MCP ERROR: Error: spawn /Users/USER/.gemini/extensions/bigquery-conversational-analytics/toolbox ENOENT": The Toolbox binary did not download correctly. Ensure you are using Gemini CLI v0.6.0+. -* "cannot execute binary file": The Toolbox binary did not download correctly. Ensure the correct binary for your OS/Architecture has been downloaded. See [Installing the server](https://mcp-toolbox.dev/documentation/introduction/#install-toolbox) for more information. +* "✖ MCP ERROR: Error: spawn npx ENOENT": Node.js/`npx` is not installed or not on your `PATH`. Install Node.js (which provides `npx`). +* "npm error"/network failures on first run: `npx` fetches `@toolbox-sdk/server` on first launch, so it needs network access. Retry once connectivity is available. diff --git a/gemini-extension.json b/gemini-extension.json index 54008e5..cb1ad88 100644 --- a/gemini-extension.json +++ b/gemini-extension.json @@ -4,8 +4,10 @@ "description": "Connect, query, and generate data insights for BigQuery datasets and data.", "mcpServers": { "bigquery_conversational_analytics": { - "command": "${extensionPath}${/}toolbox", + "command": "npx", "args": [ + "-y", + "@toolbox-sdk/server@1.8.0", "--tools-file", "${extensionPath}${/}tools.yaml", "--stdio" diff --git a/toolbox_version.txt b/toolbox_version.txt deleted file mode 100644 index 4e8f395..0000000 --- a/toolbox_version.txt +++ /dev/null @@ -1 +0,0 @@ -0.26.0 From 8135f2fd123b004f4e36c2492f060e78c6412d92 Mon Sep 17 00:00:00 2001 From: Juexin Wang Date: Fri, 14 Aug 2026 21:23:18 -0700 Subject: [PATCH 2/5] ci: address zizmor findings (scope permissions, use pull_request trigger) --- .github/workflows/mirror-changelog.yml | 2 +- .github/workflows/presubmit-tests.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/mirror-changelog.yml b/.github/workflows/mirror-changelog.yml index 9376e6c..ed80d04 100644 --- a/.github/workflows/mirror-changelog.yml +++ b/.github/workflows/mirror-changelog.yml @@ -15,7 +15,7 @@ name: Mirror Toolbox Changelog on: - pull_request_target: + pull_request: types: [opened, edited] jobs: diff --git a/.github/workflows/presubmit-tests.yml b/.github/workflows/presubmit-tests.yml index 07f6a55..5b24339 100644 --- a/.github/workflows/presubmit-tests.yml +++ b/.github/workflows/presubmit-tests.yml @@ -20,6 +20,8 @@ on: jobs: run-presubmit-tests: runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Check out code uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 From c27157df6b41990352acbc8a8afdc74c57dc5ed2 Mon Sep 17 00:00:00 2001 From: Juexin Wang Date: Fri, 14 Aug 2026 21:31:22 -0700 Subject: [PATCH 3/5] docs: drop binary packaging references (server runs via npx) --- DEVELOPER.md | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/DEVELOPER.md b/DEVELOPER.md index 351a61f..fdf8987 100644 --- a/DEVELOPER.md +++ b/DEVELOPER.md @@ -75,14 +75,9 @@ are currently tested in the [MCP Toolbox GitHub](https://github.com/googleapis/m ## Building the Extension -The "build" process for this extension involves packaging the extension's -metadata files (`gemini-extension.json`, `BIGQUERY-CONVERSATIONAL-ANALYTICS.md`, `LICENSE`) along with the -pre-built `toolbox` binary into platform-specific archives (`.tar.gz` or `.zip`). - -This process is handled automatically by the -[`package-and-upload-assets.yml`](.github/workflows/package-and-upload-assets.yml) -GitHub Actions workflow when a new release is created. Manual building is not -required. +No build step is required. The extension is a set of metadata files +(`gemini-extension.json`, the context file, `LICENSE`); the MCP server is fetched +and run at launch via `npx`, so there is no binary to compile or package. ## Maintainer Information @@ -138,8 +133,4 @@ The process is handled by the [`mirror-changelog.yml`](.github/workflows/mirror- 2. **Merge Release PR:** A maintainer approves and merges the Release PR. This action triggers `release-please` to create a new GitHub tag and a corresponding GitHub Release. -3. **Package and Upload:** The new release triggers the - `package-and-upload-assets.yml` workflow. This workflow builds the - platform-specific extension archives and uploads them as assets to the - GitHub Release. From e8fa482e91a6b06c63fadf7a85347aa4060cf52e Mon Sep 17 00:00:00 2001 From: Juexin Wang Date: Mon, 17 Aug 2026 16:36:46 -0700 Subject: [PATCH 4/5] fix(ci): keep pull_request_target for mirror-changelog (fork Renovate PRs need a write token) --- .github/workflows/mirror-changelog.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/mirror-changelog.yml b/.github/workflows/mirror-changelog.yml index ed80d04..d923eca 100644 --- a/.github/workflows/mirror-changelog.yml +++ b/.github/workflows/mirror-changelog.yml @@ -15,7 +15,8 @@ name: Mirror Toolbox Changelog on: - pull_request: + # Fork Renovate PRs need a write token; safe (no PR-code checkout, API-only). + pull_request_target: # zizmor: ignore[dangerous-triggers] types: [opened, edited] jobs: From ebbf25c5c3b4fc0b5eab3e22b9786420c5b8ed71 Mon Sep 17 00:00:00 2001 From: Juexin Wang Date: Tue, 18 Aug 2026 13:48:05 -0700 Subject: [PATCH 5/5] docs: add Node.js prerequisite (MCP server runs via npx) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 086a80d..2556aea 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ Before you begin, ensure you have the following: * [Gemini CLI](https://github.com/google-gemini/gemini-cli) installed with version **+v0.6.0**. * Setup Gemini CLI [Authentication](https://github.com/google-gemini/gemini-cli/tree/main?tab=readme-ov-file#-authentication-options). +* [Node.js](https://nodejs.org/) (the MCP server runs via `npx`). * A Google Cloud project with the **Data Analytics API with Gemini**, **Gemini for Google Cloud API** and **BigQuery API** enabled. * Ensure [Application Default Credentials](https://cloud.google.com/docs/authentication/gcloud) are available in your environment. * IAM Roles: