#
tokens: 49428/50000 11/807 files (page 25/48)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 25 of 48. Use http://codebase.md/googleapis/genai-toolbox?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .ci
│   ├── continuous.release.cloudbuild.yaml
│   ├── generate_release_table.sh
│   ├── integration.cloudbuild.yaml
│   ├── quickstart_test
│   │   ├── go.integration.cloudbuild.yaml
│   │   ├── js.integration.cloudbuild.yaml
│   │   ├── py.integration.cloudbuild.yaml
│   │   ├── run_go_tests.sh
│   │   ├── run_js_tests.sh
│   │   ├── run_py_tests.sh
│   │   └── setup_hotels_sample.sql
│   ├── test_with_coverage.sh
│   └── versioned.release.cloudbuild.yaml
├── .github
│   ├── auto-label.yaml
│   ├── blunderbuss.yml
│   ├── CODEOWNERS
│   ├── header-checker-lint.yml
│   ├── ISSUE_TEMPLATE
│   │   ├── bug_report.yml
│   │   ├── config.yml
│   │   ├── feature_request.yml
│   │   └── question.yml
│   ├── label-sync.yml
│   ├── labels.yaml
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── release-please.yml
│   ├── renovate.json5
│   ├── sync-repo-settings.yaml
│   └── workflows
│       ├── cloud_build_failure_reporter.yml
│       ├── deploy_dev_docs.yaml
│       ├── deploy_previous_version_docs.yaml
│       ├── deploy_versioned_docs.yaml
│       ├── docs_deploy.yaml
│       ├── docs_preview_clean.yaml
│       ├── docs_preview_deploy.yaml
│       ├── lint.yaml
│       ├── schedule_reporter.yml
│       ├── sync-labels.yaml
│       └── tests.yaml
├── .gitignore
├── .gitmodules
├── .golangci.yaml
├── .hugo
│   ├── archetypes
│   │   └── default.md
│   ├── assets
│   │   ├── icons
│   │   │   └── logo.svg
│   │   └── scss
│   │       ├── _styles_project.scss
│   │       └── _variables_project.scss
│   ├── go.mod
│   ├── go.sum
│   ├── hugo.toml
│   ├── layouts
│   │   ├── _default
│   │   │   └── home.releases.releases
│   │   ├── index.llms-full.txt
│   │   ├── index.llms.txt
│   │   ├── partials
│   │   │   ├── hooks
│   │   │   │   └── head-end.html
│   │   │   ├── navbar-version-selector.html
│   │   │   ├── page-meta-links.html
│   │   │   └── td
│   │   │       └── render-heading.html
│   │   ├── robot.txt
│   │   └── shortcodes
│   │       ├── include.html
│   │       ├── ipynb.html
│   │       └── regionInclude.html
│   ├── package-lock.json
│   ├── package.json
│   └── static
│       ├── favicons
│       │   ├── android-chrome-192x192.png
│       │   ├── android-chrome-512x512.png
│       │   ├── apple-touch-icon.png
│       │   ├── favicon-16x16.png
│       │   ├── favicon-32x32.png
│       │   └── favicon.ico
│       └── js
│           └── w3.js
├── CHANGELOG.md
├── cmd
│   ├── options_test.go
│   ├── options.go
│   ├── root_test.go
│   ├── root.go
│   └── version.txt
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── DEVELOPER.md
├── Dockerfile
├── docs
│   └── en
│       ├── _index.md
│       ├── about
│       │   ├── _index.md
│       │   └── faq.md
│       ├── concepts
│       │   ├── _index.md
│       │   └── telemetry
│       │       ├── index.md
│       │       ├── telemetry_flow.png
│       │       └── telemetry_traces.png
│       ├── getting-started
│       │   ├── _index.md
│       │   ├── colab_quickstart.ipynb
│       │   ├── configure.md
│       │   ├── introduction
│       │   │   ├── _index.md
│       │   │   └── architecture.png
│       │   ├── local_quickstart_go.md
│       │   ├── local_quickstart_js.md
│       │   ├── local_quickstart.md
│       │   ├── mcp_quickstart
│       │   │   ├── _index.md
│       │   │   ├── inspector_tools.png
│       │   │   └── inspector.png
│       │   └── quickstart
│       │       ├── go
│       │       │   ├── genAI
│       │       │   │   ├── go.mod
│       │       │   │   ├── go.sum
│       │       │   │   └── quickstart.go
│       │       │   ├── genkit
│       │       │   │   ├── go.mod
│       │       │   │   ├── go.sum
│       │       │   │   └── quickstart.go
│       │       │   ├── langchain
│       │       │   │   ├── go.mod
│       │       │   │   ├── go.sum
│       │       │   │   └── quickstart.go
│       │       │   ├── openAI
│       │       │   │   ├── go.mod
│       │       │   │   ├── go.sum
│       │       │   │   └── quickstart.go
│       │       │   └── quickstart_test.go
│       │       ├── golden.txt
│       │       ├── js
│       │       │   ├── genAI
│       │       │   │   ├── package-lock.json
│       │       │   │   ├── package.json
│       │       │   │   └── quickstart.js
│       │       │   ├── genkit
│       │       │   │   ├── package-lock.json
│       │       │   │   ├── package.json
│       │       │   │   └── quickstart.js
│       │       │   ├── langchain
│       │       │   │   ├── package-lock.json
│       │       │   │   ├── package.json
│       │       │   │   └── quickstart.js
│       │       │   ├── llamaindex
│       │       │   │   ├── package-lock.json
│       │       │   │   ├── package.json
│       │       │   │   └── quickstart.js
│       │       │   └── quickstart.test.js
│       │       ├── python
│       │       │   ├── __init__.py
│       │       │   ├── adk
│       │       │   │   ├── quickstart.py
│       │       │   │   └── requirements.txt
│       │       │   ├── core
│       │       │   │   ├── quickstart.py
│       │       │   │   └── requirements.txt
│       │       │   ├── langchain
│       │       │   │   ├── quickstart.py
│       │       │   │   └── requirements.txt
│       │       │   ├── llamaindex
│       │       │   │   ├── quickstart.py
│       │       │   │   └── requirements.txt
│       │       │   └── quickstart_test.py
│       │       └── shared
│       │           ├── cloud_setup.md
│       │           ├── configure_toolbox.md
│       │           └── database_setup.md
│       ├── how-to
│       │   ├── _index.md
│       │   ├── connect_via_geminicli.md
│       │   ├── connect_via_mcp.md
│       │   ├── connect-ide
│       │   │   ├── _index.md
│       │   │   ├── alloydb_pg_admin_mcp.md
│       │   │   ├── alloydb_pg_mcp.md
│       │   │   ├── bigquery_mcp.md
│       │   │   ├── cloud_sql_mssql_admin_mcp.md
│       │   │   ├── cloud_sql_mssql_mcp.md
│       │   │   ├── cloud_sql_mysql_admin_mcp.md
│       │   │   ├── cloud_sql_mysql_mcp.md
│       │   │   ├── cloud_sql_pg_admin_mcp.md
│       │   │   ├── cloud_sql_pg_mcp.md
│       │   │   ├── firestore_mcp.md
│       │   │   ├── looker_mcp.md
│       │   │   ├── mssql_mcp.md
│       │   │   ├── mysql_mcp.md
│       │   │   ├── neo4j_mcp.md
│       │   │   ├── postgres_mcp.md
│       │   │   ├── spanner_mcp.md
│       │   │   └── sqlite_mcp.md
│       │   ├── deploy_docker.md
│       │   ├── deploy_gke.md
│       │   ├── deploy_toolbox.md
│       │   ├── export_telemetry.md
│       │   └── toolbox-ui
│       │       ├── edit-headers.gif
│       │       ├── edit-headers.png
│       │       ├── index.md
│       │       ├── optional-param-checked.png
│       │       ├── optional-param-unchecked.png
│       │       ├── run-tool.gif
│       │       ├── tools.png
│       │       └── toolsets.png
│       ├── reference
│       │   ├── _index.md
│       │   ├── cli.md
│       │   └── prebuilt-tools.md
│       ├── resources
│       │   ├── _index.md
│       │   ├── authServices
│       │   │   ├── _index.md
│       │   │   └── google.md
│       │   ├── sources
│       │   │   ├── _index.md
│       │   │   ├── alloydb-admin.md
│       │   │   ├── alloydb-pg.md
│       │   │   ├── bigquery.md
│       │   │   ├── bigtable.md
│       │   │   ├── cassandra.md
│       │   │   ├── clickhouse.md
│       │   │   ├── cloud-monitoring.md
│       │   │   ├── cloud-sql-admin.md
│       │   │   ├── cloud-sql-mssql.md
│       │   │   ├── cloud-sql-mysql.md
│       │   │   ├── cloud-sql-pg.md
│       │   │   ├── couchbase.md
│       │   │   ├── dataplex.md
│       │   │   ├── dgraph.md
│       │   │   ├── firebird.md
│       │   │   ├── firestore.md
│       │   │   ├── http.md
│       │   │   ├── looker.md
│       │   │   ├── mongodb.md
│       │   │   ├── mssql.md
│       │   │   ├── mysql.md
│       │   │   ├── neo4j.md
│       │   │   ├── oceanbase.md
│       │   │   ├── oracle.md
│       │   │   ├── postgres.md
│       │   │   ├── redis.md
│       │   │   ├── spanner.md
│       │   │   ├── sqlite.md
│       │   │   ├── tidb.md
│       │   │   ├── trino.md
│       │   │   ├── valkey.md
│       │   │   └── yugabytedb.md
│       │   └── tools
│       │       ├── _index.md
│       │       ├── alloydb
│       │       │   ├── _index.md
│       │       │   ├── alloydb-create-cluster.md
│       │       │   ├── alloydb-create-instance.md
│       │       │   ├── alloydb-create-user.md
│       │       │   ├── alloydb-get-cluster.md
│       │       │   ├── alloydb-get-instance.md
│       │       │   ├── alloydb-get-user.md
│       │       │   ├── alloydb-list-clusters.md
│       │       │   ├── alloydb-list-instances.md
│       │       │   ├── alloydb-list-users.md
│       │       │   └── alloydb-wait-for-operation.md
│       │       ├── alloydbainl
│       │       │   ├── _index.md
│       │       │   └── alloydb-ai-nl.md
│       │       ├── bigquery
│       │       │   ├── _index.md
│       │       │   ├── bigquery-analyze-contribution.md
│       │       │   ├── bigquery-conversational-analytics.md
│       │       │   ├── bigquery-execute-sql.md
│       │       │   ├── bigquery-forecast.md
│       │       │   ├── bigquery-get-dataset-info.md
│       │       │   ├── bigquery-get-table-info.md
│       │       │   ├── bigquery-list-dataset-ids.md
│       │       │   ├── bigquery-list-table-ids.md
│       │       │   ├── bigquery-search-catalog.md
│       │       │   └── bigquery-sql.md
│       │       ├── bigtable
│       │       │   ├── _index.md
│       │       │   └── bigtable-sql.md
│       │       ├── cassandra
│       │       │   ├── _index.md
│       │       │   └── cassandra-cql.md
│       │       ├── clickhouse
│       │       │   ├── _index.md
│       │       │   ├── clickhouse-execute-sql.md
│       │       │   ├── clickhouse-list-databases.md
│       │       │   ├── clickhouse-list-tables.md
│       │       │   └── clickhouse-sql.md
│       │       ├── cloudmonitoring
│       │       │   ├── _index.md
│       │       │   └── cloud-monitoring-query-prometheus.md
│       │       ├── cloudsql
│       │       │   ├── _index.md
│       │       │   ├── cloudsqlcreatedatabase.md
│       │       │   ├── cloudsqlcreateusers.md
│       │       │   ├── cloudsqlgetinstances.md
│       │       │   ├── cloudsqllistdatabases.md
│       │       │   ├── cloudsqllistinstances.md
│       │       │   ├── cloudsqlmssqlcreateinstance.md
│       │       │   ├── cloudsqlmysqlcreateinstance.md
│       │       │   ├── cloudsqlpgcreateinstances.md
│       │       │   └── cloudsqlwaitforoperation.md
│       │       ├── couchbase
│       │       │   ├── _index.md
│       │       │   └── couchbase-sql.md
│       │       ├── dataform
│       │       │   ├── _index.md
│       │       │   └── dataform-compile-local.md
│       │       ├── dataplex
│       │       │   ├── _index.md
│       │       │   ├── dataplex-lookup-entry.md
│       │       │   ├── dataplex-search-aspect-types.md
│       │       │   └── dataplex-search-entries.md
│       │       ├── dgraph
│       │       │   ├── _index.md
│       │       │   └── dgraph-dql.md
│       │       ├── firebird
│       │       │   ├── _index.md
│       │       │   ├── firebird-execute-sql.md
│       │       │   └── firebird-sql.md
│       │       ├── firestore
│       │       │   ├── _index.md
│       │       │   ├── firestore-add-documents.md
│       │       │   ├── firestore-delete-documents.md
│       │       │   ├── firestore-get-documents.md
│       │       │   ├── firestore-get-rules.md
│       │       │   ├── firestore-list-collections.md
│       │       │   ├── firestore-query-collection.md
│       │       │   ├── firestore-query.md
│       │       │   ├── firestore-update-document.md
│       │       │   └── firestore-validate-rules.md
│       │       ├── http
│       │       │   ├── _index.md
│       │       │   └── http.md
│       │       ├── looker
│       │       │   ├── _index.md
│       │       │   ├── looker-add-dashboard-element.md
│       │       │   ├── looker-conversational-analytics.md
│       │       │   ├── looker-create-project-file.md
│       │       │   ├── looker-delete-project-file.md
│       │       │   ├── looker-dev-mode.md
│       │       │   ├── looker-get-dashboards.md
│       │       │   ├── looker-get-dimensions.md
│       │       │   ├── looker-get-explores.md
│       │       │   ├── looker-get-filters.md
│       │       │   ├── looker-get-looks.md
│       │       │   ├── looker-get-measures.md
│       │       │   ├── looker-get-models.md
│       │       │   ├── looker-get-parameters.md
│       │       │   ├── looker-get-project-file.md
│       │       │   ├── looker-get-project-files.md
│       │       │   ├── looker-get-projects.md
│       │       │   ├── looker-health-analyze.md
│       │       │   ├── looker-health-pulse.md
│       │       │   ├── looker-health-vacuum.md
│       │       │   ├── looker-make-dashboard.md
│       │       │   ├── looker-make-look.md
│       │       │   ├── looker-query-sql.md
│       │       │   ├── looker-query-url.md
│       │       │   ├── looker-query.md
│       │       │   ├── looker-run-look.md
│       │       │   └── looker-update-project-file.md
│       │       ├── mongodb
│       │       │   ├── _index.md
│       │       │   ├── mongodb-aggregate.md
│       │       │   ├── mongodb-delete-many.md
│       │       │   ├── mongodb-delete-one.md
│       │       │   ├── mongodb-find-one.md
│       │       │   ├── mongodb-find.md
│       │       │   ├── mongodb-insert-many.md
│       │       │   ├── mongodb-insert-one.md
│       │       │   ├── mongodb-update-many.md
│       │       │   └── mongodb-update-one.md
│       │       ├── mssql
│       │       │   ├── _index.md
│       │       │   ├── mssql-execute-sql.md
│       │       │   ├── mssql-list-tables.md
│       │       │   └── mssql-sql.md
│       │       ├── mysql
│       │       │   ├── _index.md
│       │       │   ├── mysql-execute-sql.md
│       │       │   ├── mysql-list-active-queries.md
│       │       │   ├── mysql-list-table-fragmentation.md
│       │       │   ├── mysql-list-tables-missing-unique-indexes.md
│       │       │   ├── mysql-list-tables.md
│       │       │   └── mysql-sql.md
│       │       ├── neo4j
│       │       │   ├── _index.md
│       │       │   ├── neo4j-cypher.md
│       │       │   ├── neo4j-execute-cypher.md
│       │       │   └── neo4j-schema.md
│       │       ├── oceanbase
│       │       │   ├── _index.md
│       │       │   ├── oceanbase-execute-sql.md
│       │       │   └── oceanbase-sql.md
│       │       ├── oracle
│       │       │   ├── _index.md
│       │       │   ├── oracle-execute-sql.md
│       │       │   └── oracle-sql.md
│       │       ├── postgres
│       │       │   ├── _index.md
│       │       │   ├── postgres-execute-sql.md
│       │       │   ├── postgres-list-active-queries.md
│       │       │   ├── postgres-list-available-extensions.md
│       │       │   ├── postgres-list-installed-extensions.md
│       │       │   ├── postgres-list-tables.md
│       │       │   └── postgres-sql.md
│       │       ├── redis
│       │       │   ├── _index.md
│       │       │   └── redis.md
│       │       ├── spanner
│       │       │   ├── _index.md
│       │       │   ├── spanner-execute-sql.md
│       │       │   ├── spanner-list-tables.md
│       │       │   └── spanner-sql.md
│       │       ├── sqlite
│       │       │   ├── _index.md
│       │       │   ├── sqlite-execute-sql.md
│       │       │   └── sqlite-sql.md
│       │       ├── tidb
│       │       │   ├── _index.md
│       │       │   ├── tidb-execute-sql.md
│       │       │   └── tidb-sql.md
│       │       ├── trino
│       │       │   ├── _index.md
│       │       │   ├── trino-execute-sql.md
│       │       │   └── trino-sql.md
│       │       ├── utility
│       │       │   ├── _index.md
│       │       │   └── wait.md
│       │       ├── valkey
│       │       │   ├── _index.md
│       │       │   └── valkey.md
│       │       └── yuagbytedb
│       │           ├── _index.md
│       │           └── yugabytedb-sql.md
│       ├── samples
│       │   ├── _index.md
│       │   ├── alloydb
│       │   │   ├── _index.md
│       │   │   ├── ai-nl
│       │   │   │   ├── alloydb_ai_nl.ipynb
│       │   │   │   └── index.md
│       │   │   └── mcp_quickstart.md
│       │   ├── bigquery
│       │   │   ├── _index.md
│       │   │   ├── colab_quickstart_bigquery.ipynb
│       │   │   ├── local_quickstart.md
│       │   │   └── mcp_quickstart
│       │   │       ├── _index.md
│       │   │       ├── inspector_tools.png
│       │   │       └── inspector.png
│       │   └── looker
│       │       ├── _index.md
│       │       ├── looker_gemini_oauth
│       │       │   ├── _index.md
│       │       │   ├── authenticated.png
│       │       │   ├── authorize.png
│       │       │   └── registration.png
│       │       ├── looker_gemini.md
│       │       └── looker_mcp_inspector
│       │           ├── _index.md
│       │           ├── inspector_tools.png
│       │           └── inspector.png
│       └── sdks
│           ├── _index.md
│           ├── go-sdk.md
│           ├── js-sdk.md
│           └── python-sdk.md
├── gemini-extension.json
├── go.mod
├── go.sum
├── internal
│   ├── auth
│   │   ├── auth.go
│   │   └── google
│   │       └── google.go
│   ├── log
│   │   ├── handler.go
│   │   ├── log_test.go
│   │   ├── log.go
│   │   └── logger.go
│   ├── prebuiltconfigs
│   │   ├── prebuiltconfigs_test.go
│   │   ├── prebuiltconfigs.go
│   │   └── tools
│   │       ├── alloydb-postgres-admin.yaml
│   │       ├── alloydb-postgres-observability.yaml
│   │       ├── alloydb-postgres.yaml
│   │       ├── bigquery.yaml
│   │       ├── clickhouse.yaml
│   │       ├── cloud-sql-mssql-admin.yaml
│   │       ├── cloud-sql-mssql-observability.yaml
│   │       ├── cloud-sql-mssql.yaml
│   │       ├── cloud-sql-mysql-admin.yaml
│   │       ├── cloud-sql-mysql-observability.yaml
│   │       ├── cloud-sql-mysql.yaml
│   │       ├── cloud-sql-postgres-admin.yaml
│   │       ├── cloud-sql-postgres-observability.yaml
│   │       ├── cloud-sql-postgres.yaml
│   │       ├── dataplex.yaml
│   │       ├── firestore.yaml
│   │       ├── looker-conversational-analytics.yaml
│   │       ├── looker.yaml
│   │       ├── mssql.yaml
│   │       ├── mysql.yaml
│   │       ├── neo4j.yaml
│   │       ├── oceanbase.yaml
│   │       ├── postgres.yaml
│   │       ├── spanner-postgres.yaml
│   │       ├── spanner.yaml
│   │       └── sqlite.yaml
│   ├── server
│   │   ├── api_test.go
│   │   ├── api.go
│   │   ├── common_test.go
│   │   ├── config.go
│   │   ├── mcp
│   │   │   ├── jsonrpc
│   │   │   │   ├── jsonrpc_test.go
│   │   │   │   └── jsonrpc.go
│   │   │   ├── mcp.go
│   │   │   ├── util
│   │   │   │   └── lifecycle.go
│   │   │   ├── v20241105
│   │   │   │   ├── method.go
│   │   │   │   └── types.go
│   │   │   ├── v20250326
│   │   │   │   ├── method.go
│   │   │   │   └── types.go
│   │   │   └── v20250618
│   │   │       ├── method.go
│   │   │       └── types.go
│   │   ├── mcp_test.go
│   │   ├── mcp.go
│   │   ├── server_test.go
│   │   ├── server.go
│   │   ├── static
│   │   │   ├── assets
│   │   │   │   └── mcptoolboxlogo.png
│   │   │   ├── css
│   │   │   │   └── style.css
│   │   │   ├── index.html
│   │   │   ├── js
│   │   │   │   ├── auth.js
│   │   │   │   ├── loadTools.js
│   │   │   │   ├── mainContent.js
│   │   │   │   ├── navbar.js
│   │   │   │   ├── runTool.js
│   │   │   │   ├── toolDisplay.js
│   │   │   │   ├── tools.js
│   │   │   │   └── toolsets.js
│   │   │   ├── tools.html
│   │   │   └── toolsets.html
│   │   ├── web_test.go
│   │   └── web.go
│   ├── sources
│   │   ├── alloydbadmin
│   │   │   ├── alloydbadmin_test.go
│   │   │   └── alloydbadmin.go
│   │   ├── alloydbpg
│   │   │   ├── alloydb_pg_test.go
│   │   │   └── alloydb_pg.go
│   │   ├── bigquery
│   │   │   ├── bigquery_test.go
│   │   │   └── bigquery.go
│   │   ├── bigtable
│   │   │   ├── bigtable_test.go
│   │   │   └── bigtable.go
│   │   ├── cassandra
│   │   │   ├── cassandra_test.go
│   │   │   └── cassandra.go
│   │   ├── clickhouse
│   │   │   ├── clickhouse_test.go
│   │   │   └── clickhouse.go
│   │   ├── cloudmonitoring
│   │   │   ├── cloud_monitoring_test.go
│   │   │   └── cloud_monitoring.go
│   │   ├── cloudsqladmin
│   │   │   ├── cloud_sql_admin_test.go
│   │   │   └── cloud_sql_admin.go
│   │   ├── cloudsqlmssql
│   │   │   ├── cloud_sql_mssql_test.go
│   │   │   └── cloud_sql_mssql.go
│   │   ├── cloudsqlmysql
│   │   │   ├── cloud_sql_mysql_test.go
│   │   │   └── cloud_sql_mysql.go
│   │   ├── cloudsqlpg
│   │   │   ├── cloud_sql_pg_test.go
│   │   │   └── cloud_sql_pg.go
│   │   ├── couchbase
│   │   │   ├── couchbase_test.go
│   │   │   └── couchbase.go
│   │   ├── dataplex
│   │   │   ├── dataplex_test.go
│   │   │   └── dataplex.go
│   │   ├── dgraph
│   │   │   ├── dgraph_test.go
│   │   │   └── dgraph.go
│   │   ├── dialect.go
│   │   ├── firebird
│   │   │   ├── firebird_test.go
│   │   │   └── firebird.go
│   │   ├── firestore
│   │   │   ├── firestore_test.go
│   │   │   └── firestore.go
│   │   ├── http
│   │   │   ├── http_test.go
│   │   │   └── http.go
│   │   ├── ip_type.go
│   │   ├── looker
│   │   │   ├── looker_test.go
│   │   │   └── looker.go
│   │   ├── mongodb
│   │   │   ├── mongodb_test.go
│   │   │   └── mongodb.go
│   │   ├── mssql
│   │   │   ├── mssql_test.go
│   │   │   └── mssql.go
│   │   ├── mysql
│   │   │   ├── mysql_test.go
│   │   │   └── mysql.go
│   │   ├── neo4j
│   │   │   ├── neo4j_test.go
│   │   │   └── neo4j.go
│   │   ├── oceanbase
│   │   │   ├── oceanbase_test.go
│   │   │   └── oceanbase.go
│   │   ├── oracle
│   │   │   └── oracle.go
│   │   ├── postgres
│   │   │   ├── postgres_test.go
│   │   │   └── postgres.go
│   │   ├── redis
│   │   │   ├── redis_test.go
│   │   │   └── redis.go
│   │   ├── sources.go
│   │   ├── spanner
│   │   │   ├── spanner_test.go
│   │   │   └── spanner.go
│   │   ├── sqlite
│   │   │   ├── sqlite_test.go
│   │   │   └── sqlite.go
│   │   ├── tidb
│   │   │   ├── tidb_test.go
│   │   │   └── tidb.go
│   │   ├── trino
│   │   │   ├── trino_test.go
│   │   │   └── trino.go
│   │   ├── util.go
│   │   ├── valkey
│   │   │   ├── valkey_test.go
│   │   │   └── valkey.go
│   │   └── yugabytedb
│   │       ├── yugabytedb_test.go
│   │       └── yugabytedb.go
│   ├── telemetry
│   │   ├── instrumentation.go
│   │   └── telemetry.go
│   ├── testutils
│   │   └── testutils.go
│   ├── tools
│   │   ├── alloydb
│   │   │   ├── alloydbcreatecluster
│   │   │   │   ├── alloydbcreatecluster_test.go
│   │   │   │   └── alloydbcreatecluster.go
│   │   │   ├── alloydbcreateinstance
│   │   │   │   ├── alloydbcreateinstance_test.go
│   │   │   │   └── alloydbcreateinstance.go
│   │   │   ├── alloydbcreateuser
│   │   │   │   ├── alloydbcreateuser_test.go
│   │   │   │   └── alloydbcreateuser.go
│   │   │   ├── alloydbgetcluster
│   │   │   │   ├── alloydbgetcluster_test.go
│   │   │   │   └── alloydbgetcluster.go
│   │   │   ├── alloydbgetinstance
│   │   │   │   ├── alloydbgetinstance_test.go
│   │   │   │   └── alloydbgetinstance.go
│   │   │   ├── alloydbgetuser
│   │   │   │   ├── alloydbgetuser_test.go
│   │   │   │   └── alloydbgetuser.go
│   │   │   ├── alloydblistclusters
│   │   │   │   ├── alloydblistclusters_test.go
│   │   │   │   └── alloydblistclusters.go
│   │   │   ├── alloydblistinstances
│   │   │   │   ├── alloydblistinstances_test.go
│   │   │   │   └── alloydblistinstances.go
│   │   │   ├── alloydblistusers
│   │   │   │   ├── alloydblistusers_test.go
│   │   │   │   └── alloydblistusers.go
│   │   │   └── alloydbwaitforoperation
│   │   │       ├── alloydbwaitforoperation_test.go
│   │   │       └── alloydbwaitforoperation.go
│   │   ├── alloydbainl
│   │   │   ├── alloydbainl_test.go
│   │   │   └── alloydbainl.go
│   │   ├── bigquery
│   │   │   ├── bigqueryanalyzecontribution
│   │   │   │   ├── bigqueryanalyzecontribution_test.go
│   │   │   │   └── bigqueryanalyzecontribution.go
│   │   │   ├── bigquerycommon
│   │   │   │   ├── table_name_parser_test.go
│   │   │   │   ├── table_name_parser.go
│   │   │   │   └── util.go
│   │   │   ├── bigqueryconversationalanalytics
│   │   │   │   ├── bigqueryconversationalanalytics_test.go
│   │   │   │   └── bigqueryconversationalanalytics.go
│   │   │   ├── bigqueryexecutesql
│   │   │   │   ├── bigqueryexecutesql_test.go
│   │   │   │   └── bigqueryexecutesql.go
│   │   │   ├── bigqueryforecast
│   │   │   │   ├── bigqueryforecast_test.go
│   │   │   │   └── bigqueryforecast.go
│   │   │   ├── bigquerygetdatasetinfo
│   │   │   │   ├── bigquerygetdatasetinfo_test.go
│   │   │   │   └── bigquerygetdatasetinfo.go
│   │   │   ├── bigquerygettableinfo
│   │   │   │   ├── bigquerygettableinfo_test.go
│   │   │   │   └── bigquerygettableinfo.go
│   │   │   ├── bigquerylistdatasetids
│   │   │   │   ├── bigquerylistdatasetids_test.go
│   │   │   │   └── bigquerylistdatasetids.go
│   │   │   ├── bigquerylisttableids
│   │   │   │   ├── bigquerylisttableids_test.go
│   │   │   │   └── bigquerylisttableids.go
│   │   │   ├── bigquerysearchcatalog
│   │   │   │   ├── bigquerysearchcatalog_test.go
│   │   │   │   └── bigquerysearchcatalog.go
│   │   │   └── bigquerysql
│   │   │       ├── bigquerysql_test.go
│   │   │       └── bigquerysql.go
│   │   ├── bigtable
│   │   │   ├── bigtable_test.go
│   │   │   └── bigtable.go
│   │   ├── cassandra
│   │   │   └── cassandracql
│   │   │       ├── cassandracql_test.go
│   │   │       └── cassandracql.go
│   │   ├── clickhouse
│   │   │   ├── clickhouseexecutesql
│   │   │   │   ├── clickhouseexecutesql_test.go
│   │   │   │   └── clickhouseexecutesql.go
│   │   │   ├── clickhouselistdatabases
│   │   │   │   ├── clickhouselistdatabases_test.go
│   │   │   │   └── clickhouselistdatabases.go
│   │   │   ├── clickhouselisttables
│   │   │   │   ├── clickhouselisttables_test.go
│   │   │   │   └── clickhouselisttables.go
│   │   │   └── clickhousesql
│   │   │       ├── clickhousesql_test.go
│   │   │       └── clickhousesql.go
│   │   ├── cloudmonitoring
│   │   │   ├── cloudmonitoring_test.go
│   │   │   └── cloudmonitoring.go
│   │   ├── cloudsql
│   │   │   ├── cloudsqlcreatedatabase
│   │   │   │   ├── cloudsqlcreatedatabase_test.go
│   │   │   │   └── cloudsqlcreatedatabase.go
│   │   │   ├── cloudsqlcreateusers
│   │   │   │   ├── cloudsqlcreateusers_test.go
│   │   │   │   └── cloudsqlcreateusers.go
│   │   │   ├── cloudsqlgetinstances
│   │   │   │   ├── cloudsqlgetinstances_test.go
│   │   │   │   └── cloudsqlgetinstances.go
│   │   │   ├── cloudsqllistdatabases
│   │   │   │   ├── cloudsqllistdatabases_test.go
│   │   │   │   └── cloudsqllistdatabases.go
│   │   │   ├── cloudsqllistinstances
│   │   │   │   ├── cloudsqllistinstances_test.go
│   │   │   │   └── cloudsqllistinstances.go
│   │   │   └── cloudsqlwaitforoperation
│   │   │       ├── cloudsqlwaitforoperation_test.go
│   │   │       └── cloudsqlwaitforoperation.go
│   │   ├── cloudsqlmssql
│   │   │   └── cloudsqlmssqlcreateinstance
│   │   │       ├── cloudsqlmssqlcreateinstance_test.go
│   │   │       └── cloudsqlmssqlcreateinstance.go
│   │   ├── cloudsqlmysql
│   │   │   └── cloudsqlmysqlcreateinstance
│   │   │       ├── cloudsqlmysqlcreateinstance_test.go
│   │   │       └── cloudsqlmysqlcreateinstance.go
│   │   ├── cloudsqlpg
│   │   │   └── cloudsqlpgcreateinstances
│   │   │       ├── cloudsqlpgcreateinstances_test.go
│   │   │       └── cloudsqlpgcreateinstances.go
│   │   ├── common_test.go
│   │   ├── common.go
│   │   ├── couchbase
│   │   │   ├── couchbase_test.go
│   │   │   └── couchbase.go
│   │   ├── dataform
│   │   │   └── dataformcompilelocal
│   │   │       ├── dataformcompilelocal_test.go
│   │   │       └── dataformcompilelocal.go
│   │   ├── dataplex
│   │   │   ├── dataplexlookupentry
│   │   │   │   ├── dataplexlookupentry_test.go
│   │   │   │   └── dataplexlookupentry.go
│   │   │   ├── dataplexsearchaspecttypes
│   │   │   │   ├── dataplexsearchaspecttypes_test.go
│   │   │   │   └── dataplexsearchaspecttypes.go
│   │   │   └── dataplexsearchentries
│   │   │       ├── dataplexsearchentries_test.go
│   │   │       └── dataplexsearchentries.go
│   │   ├── dgraph
│   │   │   ├── dgraph_test.go
│   │   │   └── dgraph.go
│   │   ├── firebird
│   │   │   ├── firebirdexecutesql
│   │   │   │   ├── firebirdexecutesql_test.go
│   │   │   │   └── firebirdexecutesql.go
│   │   │   └── firebirdsql
│   │   │       ├── firebirdsql_test.go
│   │   │       └── firebirdsql.go
│   │   ├── firestore
│   │   │   ├── firestoreadddocuments
│   │   │   │   ├── firestoreadddocuments_test.go
│   │   │   │   └── firestoreadddocuments.go
│   │   │   ├── firestoredeletedocuments
│   │   │   │   ├── firestoredeletedocuments_test.go
│   │   │   │   └── firestoredeletedocuments.go
│   │   │   ├── firestoregetdocuments
│   │   │   │   ├── firestoregetdocuments_test.go
│   │   │   │   └── firestoregetdocuments.go
│   │   │   ├── firestoregetrules
│   │   │   │   ├── firestoregetrules_test.go
│   │   │   │   └── firestoregetrules.go
│   │   │   ├── firestorelistcollections
│   │   │   │   ├── firestorelistcollections_test.go
│   │   │   │   └── firestorelistcollections.go
│   │   │   ├── firestorequery
│   │   │   │   ├── firestorequery_test.go
│   │   │   │   └── firestorequery.go
│   │   │   ├── firestorequerycollection
│   │   │   │   ├── firestorequerycollection_test.go
│   │   │   │   └── firestorequerycollection.go
│   │   │   ├── firestoreupdatedocument
│   │   │   │   ├── firestoreupdatedocument_test.go
│   │   │   │   └── firestoreupdatedocument.go
│   │   │   ├── firestorevalidaterules
│   │   │   │   ├── firestorevalidaterules_test.go
│   │   │   │   └── firestorevalidaterules.go
│   │   │   └── util
│   │   │       ├── converter_test.go
│   │   │       ├── converter.go
│   │   │       ├── validator_test.go
│   │   │       └── validator.go
│   │   ├── http
│   │   │   ├── http_test.go
│   │   │   └── http.go
│   │   ├── http_method.go
│   │   ├── looker
│   │   │   ├── lookeradddashboardelement
│   │   │   │   ├── lookeradddashboardelement_test.go
│   │   │   │   └── lookeradddashboardelement.go
│   │   │   ├── lookercommon
│   │   │   │   ├── lookercommon_test.go
│   │   │   │   └── lookercommon.go
│   │   │   ├── lookerconversationalanalytics
│   │   │   │   ├── lookerconversationalanalytics_test.go
│   │   │   │   └── lookerconversationalanalytics.go
│   │   │   ├── lookercreateprojectfile
│   │   │   │   ├── lookercreateprojectfile_test.go
│   │   │   │   └── lookercreateprojectfile.go
│   │   │   ├── lookerdeleteprojectfile
│   │   │   │   ├── lookerdeleteprojectfile_test.go
│   │   │   │   └── lookerdeleteprojectfile.go
│   │   │   ├── lookerdevmode
│   │   │   │   ├── lookerdevmode_test.go
│   │   │   │   └── lookerdevmode.go
│   │   │   ├── lookergetdashboards
│   │   │   │   ├── lookergetdashboards_test.go
│   │   │   │   └── lookergetdashboards.go
│   │   │   ├── lookergetdimensions
│   │   │   │   ├── lookergetdimensions_test.go
│   │   │   │   └── lookergetdimensions.go
│   │   │   ├── lookergetexplores
│   │   │   │   ├── lookergetexplores_test.go
│   │   │   │   └── lookergetexplores.go
│   │   │   ├── lookergetfilters
│   │   │   │   ├── lookergetfilters_test.go
│   │   │   │   └── lookergetfilters.go
│   │   │   ├── lookergetlooks
│   │   │   │   ├── lookergetlooks_test.go
│   │   │   │   └── lookergetlooks.go
│   │   │   ├── lookergetmeasures
│   │   │   │   ├── lookergetmeasures_test.go
│   │   │   │   └── lookergetmeasures.go
│   │   │   ├── lookergetmodels
│   │   │   │   ├── lookergetmodels_test.go
│   │   │   │   └── lookergetmodels.go
│   │   │   ├── lookergetparameters
│   │   │   │   ├── lookergetparameters_test.go
│   │   │   │   └── lookergetparameters.go
│   │   │   ├── lookergetprojectfile
│   │   │   │   ├── lookergetprojectfile_test.go
│   │   │   │   └── lookergetprojectfile.go
│   │   │   ├── lookergetprojectfiles
│   │   │   │   ├── lookergetprojectfiles_test.go
│   │   │   │   └── lookergetprojectfiles.go
│   │   │   ├── lookergetprojects
│   │   │   │   ├── lookergetprojects_test.go
│   │   │   │   └── lookergetprojects.go
│   │   │   ├── lookerhealthanalyze
│   │   │   │   ├── lookerhealthanalyze_test.go
│   │   │   │   └── lookerhealthanalyze.go
│   │   │   ├── lookerhealthpulse
│   │   │   │   ├── lookerhealthpulse_test.go
│   │   │   │   └── lookerhealthpulse.go
│   │   │   ├── lookerhealthvacuum
│   │   │   │   ├── lookerhealthvacuum_test.go
│   │   │   │   └── lookerhealthvacuum.go
│   │   │   ├── lookermakedashboard
│   │   │   │   ├── lookermakedashboard_test.go
│   │   │   │   └── lookermakedashboard.go
│   │   │   ├── lookermakelook
│   │   │   │   ├── lookermakelook_test.go
│   │   │   │   └── lookermakelook.go
│   │   │   ├── lookerquery
│   │   │   │   ├── lookerquery_test.go
│   │   │   │   └── lookerquery.go
│   │   │   ├── lookerquerysql
│   │   │   │   ├── lookerquerysql_test.go
│   │   │   │   └── lookerquerysql.go
│   │   │   ├── lookerqueryurl
│   │   │   │   ├── lookerqueryurl_test.go
│   │   │   │   └── lookerqueryurl.go
│   │   │   ├── lookerrunlook
│   │   │   │   ├── lookerrunlook_test.go
│   │   │   │   └── lookerrunlook.go
│   │   │   └── lookerupdateprojectfile
│   │   │       ├── lookerupdateprojectfile_test.go
│   │   │       └── lookerupdateprojectfile.go
│   │   ├── mongodb
│   │   │   ├── mongodbaggregate
│   │   │   │   ├── mongodbaggregate_test.go
│   │   │   │   └── mongodbaggregate.go
│   │   │   ├── mongodbdeletemany
│   │   │   │   ├── mongodbdeletemany_test.go
│   │   │   │   └── mongodbdeletemany.go
│   │   │   ├── mongodbdeleteone
│   │   │   │   ├── mongodbdeleteone_test.go
│   │   │   │   └── mongodbdeleteone.go
│   │   │   ├── mongodbfind
│   │   │   │   ├── mongodbfind_test.go
│   │   │   │   └── mongodbfind.go
│   │   │   ├── mongodbfindone
│   │   │   │   ├── mongodbfindone_test.go
│   │   │   │   └── mongodbfindone.go
│   │   │   ├── mongodbinsertmany
│   │   │   │   ├── mongodbinsertmany_test.go
│   │   │   │   └── mongodbinsertmany.go
│   │   │   ├── mongodbinsertone
│   │   │   │   ├── mongodbinsertone_test.go
│   │   │   │   └── mongodbinsertone.go
│   │   │   ├── mongodbupdatemany
│   │   │   │   ├── mongodbupdatemany_test.go
│   │   │   │   └── mongodbupdatemany.go
│   │   │   └── mongodbupdateone
│   │   │       ├── mongodbupdateone_test.go
│   │   │       └── mongodbupdateone.go
│   │   ├── mssql
│   │   │   ├── mssqlexecutesql
│   │   │   │   ├── mssqlexecutesql_test.go
│   │   │   │   └── mssqlexecutesql.go
│   │   │   ├── mssqllisttables
│   │   │   │   ├── mssqllisttables_test.go
│   │   │   │   └── mssqllisttables.go
│   │   │   └── mssqlsql
│   │   │       ├── mssqlsql_test.go
│   │   │       └── mssqlsql.go
│   │   ├── mysql
│   │   │   ├── mysqlcommon
│   │   │   │   └── mysqlcommon.go
│   │   │   ├── mysqlexecutesql
│   │   │   │   ├── mysqlexecutesql_test.go
│   │   │   │   └── mysqlexecutesql.go
│   │   │   ├── mysqllistactivequeries
│   │   │   │   ├── mysqllistactivequeries_test.go
│   │   │   │   └── mysqllistactivequeries.go
│   │   │   ├── mysqllisttablefragmentation
│   │   │   │   ├── mysqllisttablefragmentation_test.go
│   │   │   │   └── mysqllisttablefragmentation.go
│   │   │   ├── mysqllisttables
│   │   │   │   ├── mysqllisttables_test.go
│   │   │   │   └── mysqllisttables.go
│   │   │   ├── mysqllisttablesmissinguniqueindexes
│   │   │   │   ├── mysqllisttablesmissinguniqueindexes_test.go
│   │   │   │   └── mysqllisttablesmissinguniqueindexes.go
│   │   │   └── mysqlsql
│   │   │       ├── mysqlsql_test.go
│   │   │       └── mysqlsql.go
│   │   ├── neo4j
│   │   │   ├── neo4jcypher
│   │   │   │   ├── neo4jcypher_test.go
│   │   │   │   └── neo4jcypher.go
│   │   │   ├── neo4jexecutecypher
│   │   │   │   ├── classifier
│   │   │   │   │   ├── classifier_test.go
│   │   │   │   │   └── classifier.go
│   │   │   │   ├── neo4jexecutecypher_test.go
│   │   │   │   └── neo4jexecutecypher.go
│   │   │   └── neo4jschema
│   │   │       ├── cache
│   │   │       │   ├── cache_test.go
│   │   │       │   └── cache.go
│   │   │       ├── helpers
│   │   │       │   ├── helpers_test.go
│   │   │       │   └── helpers.go
│   │   │       ├── neo4jschema_test.go
│   │   │       ├── neo4jschema.go
│   │   │       └── types
│   │   │           └── types.go
│   │   ├── oceanbase
│   │   │   ├── oceanbaseexecutesql
│   │   │   │   ├── oceanbaseexecutesql_test.go
│   │   │   │   └── oceanbaseexecutesql.go
│   │   │   └── oceanbasesql
│   │   │       ├── oceanbasesql_test.go
│   │   │       └── oceanbasesql.go
│   │   ├── oracle
│   │   │   ├── oracleexecutesql
│   │   │   │   └── oracleexecutesql.go
│   │   │   └── oraclesql
│   │   │       └── oraclesql.go
│   │   ├── parameters_test.go
│   │   ├── parameters.go
│   │   ├── postgres
│   │   │   ├── postgresexecutesql
│   │   │   │   ├── postgresexecutesql_test.go
│   │   │   │   └── postgresexecutesql.go
│   │   │   ├── postgreslistactivequeries
│   │   │   │   ├── postgreslistactivequeries_test.go
│   │   │   │   └── postgreslistactivequeries.go
│   │   │   ├── postgreslistavailableextensions
│   │   │   │   ├── postgreslistavailableextensions_test.go
│   │   │   │   └── postgreslistavailableextensions.go
│   │   │   ├── postgreslistinstalledextensions
│   │   │   │   ├── postgreslistinstalledextensions_test.go
│   │   │   │   └── postgreslistinstalledextensions.go
│   │   │   ├── postgreslisttables
│   │   │   │   ├── postgreslisttables_test.go
│   │   │   │   └── postgreslisttables.go
│   │   │   └── postgressql
│   │   │       ├── postgressql_test.go
│   │   │       └── postgressql.go
│   │   ├── redis
│   │   │   ├── redis_test.go
│   │   │   └── redis.go
│   │   ├── spanner
│   │   │   ├── spannerexecutesql
│   │   │   │   ├── spannerexecutesql_test.go
│   │   │   │   └── spannerexecutesql.go
│   │   │   ├── spannerlisttables
│   │   │   │   ├── spannerlisttables_test.go
│   │   │   │   └── spannerlisttables.go
│   │   │   └── spannersql
│   │   │       ├── spanner_test.go
│   │   │       └── spannersql.go
│   │   ├── sqlite
│   │   │   ├── sqliteexecutesql
│   │   │   │   ├── sqliteexecutesql_test.go
│   │   │   │   └── sqliteexecutesql.go
│   │   │   └── sqlitesql
│   │   │       ├── sqlitesql_test.go
│   │   │       └── sqlitesql.go
│   │   ├── tidb
│   │   │   ├── tidbexecutesql
│   │   │   │   ├── tidbexecutesql_test.go
│   │   │   │   └── tidbexecutesql.go
│   │   │   └── tidbsql
│   │   │       ├── tidbsql_test.go
│   │   │       └── tidbsql.go
│   │   ├── tools_test.go
│   │   ├── tools.go
│   │   ├── toolsets.go
│   │   ├── trino
│   │   │   ├── trinoexecutesql
│   │   │   │   ├── trinoexecutesql_test.go
│   │   │   │   └── trinoexecutesql.go
│   │   │   └── trinosql
│   │   │       ├── trinosql_test.go
│   │   │       └── trinosql.go
│   │   ├── utility
│   │   │   └── wait
│   │   │       ├── wait_test.go
│   │   │       └── wait.go
│   │   ├── valkey
│   │   │   ├── valkey_test.go
│   │   │   └── valkey.go
│   │   └── yugabytedbsql
│   │       ├── yugabytedbsql_test.go
│   │       └── yugabytedbsql.go
│   └── util
│       └── util.go
├── LICENSE
├── logo.png
├── main.go
├── MCP-TOOLBOX-EXTENSION.md
├── README.md
└── tests
    ├── alloydb
    │   ├── alloydb_integration_test.go
    │   └── alloydb_wait_for_operation_test.go
    ├── alloydbainl
    │   └── alloydb_ai_nl_integration_test.go
    ├── alloydbpg
    │   └── alloydb_pg_integration_test.go
    ├── auth.go
    ├── bigquery
    │   └── bigquery_integration_test.go
    ├── bigtable
    │   └── bigtable_integration_test.go
    ├── cassandra
    │   └── cassandra_integration_test.go
    ├── clickhouse
    │   └── clickhouse_integration_test.go
    ├── cloudmonitoring
    │   └── cloud_monitoring_integration_test.go
    ├── cloudsql
    │   ├── cloud_sql_create_database_test.go
    │   ├── cloud_sql_create_users_test.go
    │   ├── cloud_sql_get_instances_test.go
    │   ├── cloud_sql_list_databases_test.go
    │   ├── cloudsql_list_instances_test.go
    │   └── cloudsql_wait_for_operation_test.go
    ├── cloudsqlmssql
    │   ├── cloud_sql_mssql_create_instance_integration_test.go
    │   └── cloud_sql_mssql_integration_test.go
    ├── cloudsqlmysql
    │   ├── cloud_sql_mysql_create_instance_integration_test.go
    │   └── cloud_sql_mysql_integration_test.go
    ├── cloudsqlpg
    │   ├── cloud_sql_pg_create_instances_test.go
    │   └── cloud_sql_pg_integration_test.go
    ├── common.go
    ├── couchbase
    │   └── couchbase_integration_test.go
    ├── dataform
    │   └── dataform_integration_test.go
    ├── dataplex
    │   └── dataplex_integration_test.go
    ├── dgraph
    │   └── dgraph_integration_test.go
    ├── firebird
    │   └── firebird_integration_test.go
    ├── firestore
    │   └── firestore_integration_test.go
    ├── http
    │   └── http_integration_test.go
    ├── looker
    │   └── looker_integration_test.go
    ├── mongodb
    │   └── mongodb_integration_test.go
    ├── mssql
    │   └── mssql_integration_test.go
    ├── mysql
    │   └── mysql_integration_test.go
    ├── neo4j
    │   └── neo4j_integration_test.go
    ├── oceanbase
    │   └── oceanbase_integration_test.go
    ├── option.go
    ├── oracle
    │   └── oracle_integration_test.go
    ├── postgres
    │   └── postgres_integration_test.go
    ├── redis
    │   └── redis_test.go
    ├── server.go
    ├── source.go
    ├── spanner
    │   └── spanner_integration_test.go
    ├── sqlite
    │   └── sqlite_integration_test.go
    ├── tidb
    │   └── tidb_integration_test.go
    ├── tool.go
    ├── trino
    │   └── trino_integration_test.go
    ├── utility
    │   └── wait_integration_test.go
    ├── valkey
    │   └── valkey_test.go
    └── yugabytedb
        └── yugabytedb_integration_test.go
```

# Files

--------------------------------------------------------------------------------
/internal/tools/mysql/mysqllistactivequeries/mysqllistactivequeries.go:
--------------------------------------------------------------------------------

```go
  1 | // Copyright 2025 Google LLC
  2 | //
  3 | // Licensed under the Apache License, Version 2.0 (the "License");
  4 | // you may not use this file except in compliance with the License.
  5 | // You may obtain a copy of the License at
  6 | //
  7 | //     http://www.apache.org/licenses/LICENSE-2.0
  8 | //
  9 | // Unless required by applicable law or agreed to in writing, software
 10 | // distributed under the License is distributed on an "AS IS" BASIS,
 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12 | // See the License for the specific language governing permissions and
 13 | // limitations under the License.
 14 | 
 15 | package mysqllistactivequeries
 16 | 
 17 | import (
 18 | 	"context"
 19 | 	"database/sql"
 20 | 	"fmt"
 21 | 
 22 | 	yaml "github.com/goccy/go-yaml"
 23 | 	"github.com/googleapis/genai-toolbox/internal/sources"
 24 | 	"github.com/googleapis/genai-toolbox/internal/sources/cloudsqlmysql"
 25 | 	"github.com/googleapis/genai-toolbox/internal/sources/mysql"
 26 | 	"github.com/googleapis/genai-toolbox/internal/tools"
 27 | 	"github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlcommon"
 28 | 	"github.com/googleapis/genai-toolbox/internal/util"
 29 | )
 30 | 
 31 | const kind string = "mysql-list-active-queries"
 32 | 
 33 | const listActiveQueriesStatementMySQL = `
 34 | 	SELECT
 35 | 		p.id AS processlist_id,
 36 | 		substring(IFNULL(p.info, t.trx_query), 1, 100) AS query,
 37 | 		t.trx_started AS trx_started,
 38 | 		(UNIX_TIMESTAMP(UTC_TIMESTAMP()) - UNIX_TIMESTAMP(t.trx_started)) AS trx_duration_seconds,
 39 | 		(UNIX_TIMESTAMP(UTC_TIMESTAMP()) - UNIX_TIMESTAMP(t.trx_wait_started)) AS trx_wait_duration_seconds,
 40 | 		p.time AS query_time,
 41 | 		t.trx_state AS trx_state,
 42 | 		p.state AS process_state,
 43 | 		IF(p.host IS NULL OR p.host = '', p.user, concat(p.user, '@', SUBSTRING_INDEX(p.host, ':', 1))) AS user,
 44 | 		t.trx_rows_locked AS trx_rows_locked,
 45 | 		t.trx_rows_modified AS trx_rows_modified,
 46 | 		p.db AS db
 47 | 	FROM
 48 | 		information_schema.processlist p
 49 | 		LEFT OUTER JOIN
 50 | 		information_schema.innodb_trx t
 51 | 		ON p.id = t.trx_mysql_thread_id
 52 | 	WHERE
 53 | 		(? IS NULL OR p.time >= ?)
 54 | 		AND p.id != CONNECTION_ID()
 55 | 		AND Command NOT IN ('Binlog Dump', 'Binlog Dump GTID', 'Connect', 'Connect Out', 'Register Slave')
 56 | 		AND User NOT IN ('system user', 'event_scheduler')
 57 | 		AND (t.trx_id is NOT NULL OR command != 'Sleep')
 58 | 	ORDER BY
 59 | 		t.trx_started
 60 | 	LIMIT ?;
 61 | `
 62 | 
 63 | const listActiveQueriesStatementCloudSQLMySQL = `
 64 | 	SELECT
 65 | 		p.id AS processlist_id,
 66 | 		substring(IFNULL(p.info, t.trx_query), 1, 100) AS query,
 67 | 		t.trx_started AS trx_started,
 68 | 		(UNIX_TIMESTAMP(UTC_TIMESTAMP()) - UNIX_TIMESTAMP(t.trx_started)) AS trx_duration_seconds,
 69 | 		(UNIX_TIMESTAMP(UTC_TIMESTAMP()) - UNIX_TIMESTAMP(t.trx_wait_started)) AS trx_wait_duration_seconds,
 70 | 		p.time AS query_time,
 71 | 		t.trx_state AS trx_state,
 72 | 		p.state AS process_state,
 73 | 		IF(p.host IS NULL OR p.host = '', p.user, concat(p.user, '@', SUBSTRING_INDEX(p.host, ':', 1))) AS user,
 74 | 		t.trx_rows_locked AS trx_rows_locked,
 75 | 		t.trx_rows_modified AS trx_rows_modified,
 76 | 		p.db AS db
 77 | 	FROM
 78 | 		information_schema.processlist p
 79 | 		LEFT OUTER JOIN
 80 | 		information_schema.innodb_trx t
 81 | 		ON p.id = t.trx_mysql_thread_id
 82 | 	WHERE
 83 | 		(? IS NULL OR p.time >= ?)
 84 | 		AND p.id != CONNECTION_ID()
 85 | 		AND SUBSTRING_INDEX(IFNULL(p.host,''), ':', 1) NOT IN ('localhost', '127.0.0.1')
 86 | 		AND IFNULL(p.host,'') NOT LIKE '::1%'
 87 | 		AND Command NOT IN ('Binlog Dump', 'Binlog Dump GTID', 'Connect', 'Connect Out', 'Register Slave')
 88 | 		AND User NOT IN ('system user', 'event_scheduler')
 89 | 		AND (t.trx_id is NOT NULL OR command != 'sleep')
 90 | 	ORDER BY
 91 | 		t.trx_started
 92 | 	LIMIT ?;
 93 | `
 94 | 
 95 | func init() {
 96 | 	if !tools.Register(kind, newConfig) {
 97 | 		panic(fmt.Sprintf("tool kind %q already registered", kind))
 98 | 	}
 99 | }
100 | 
101 | func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.ToolConfig, error) {
102 | 	actual := Config{Name: name}
103 | 	if err := decoder.DecodeContext(ctx, &actual); err != nil {
104 | 		return nil, err
105 | 	}
106 | 	return actual, nil
107 | }
108 | 
109 | type compatibleSource interface {
110 | 	MySQLPool() *sql.DB
111 | }
112 | 
113 | // validate compatible sources are still compatible
114 | var _ compatibleSource = &mysql.Source{}
115 | var _ compatibleSource = &cloudsqlmysql.Source{}
116 | 
117 | var compatibleSources = [...]string{mysql.SourceKind, cloudsqlmysql.SourceKind}
118 | 
119 | type Config struct {
120 | 	Name         string   `yaml:"name" validate:"required"`
121 | 	Kind         string   `yaml:"kind" validate:"required"`
122 | 	Source       string   `yaml:"source" validate:"required"`
123 | 	Description  string   `yaml:"description" validate:"required"`
124 | 	AuthRequired []string `yaml:"authRequired"`
125 | }
126 | 
127 | // validate interface
128 | var _ tools.ToolConfig = Config{}
129 | 
130 | func (cfg Config) ToolConfigKind() string {
131 | 	return kind
132 | }
133 | 
134 | func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) {
135 | 	// verify source exists
136 | 	rawS, ok := srcs[cfg.Source]
137 | 	if !ok {
138 | 		return nil, fmt.Errorf("no source named %q configured", cfg.Source)
139 | 	}
140 | 
141 | 	// verify the source is compatible
142 | 	s, ok := rawS.(compatibleSource)
143 | 	if !ok {
144 | 		return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources)
145 | 	}
146 | 
147 | 	allParameters := tools.Parameters{
148 | 		tools.NewIntParameterWithDefault("min_duration_secs", 0, "Optional: Only show queries running for at least this long in seconds"),
149 | 		tools.NewIntParameterWithDefault("limit", 100, "Optional: The maximum number of rows to return."),
150 | 	}
151 | 	mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters)
152 | 
153 | 	var statement string
154 | 	sourceKind := rawS.SourceKind()
155 | 
156 | 	switch sourceKind {
157 | 	case mysql.SourceKind:
158 | 		statement = listActiveQueriesStatementMySQL
159 | 	case cloudsqlmysql.SourceKind:
160 | 		statement = listActiveQueriesStatementCloudSQLMySQL
161 | 	default:
162 | 		return nil, fmt.Errorf("unsupported source kind kind: %q", sourceKind)
163 | 	}
164 | 	// finish tool setup
165 | 	t := Tool{
166 | 		Name:         cfg.Name,
167 | 		Kind:         kind,
168 | 		AuthRequired: cfg.AuthRequired,
169 | 		Pool:         s.MySQLPool(),
170 | 		allParams:    allParameters,
171 | 		manifest:     tools.Manifest{Description: cfg.Description, Parameters: allParameters.Manifest(), AuthRequired: cfg.AuthRequired},
172 | 		mcpManifest:  mcpManifest,
173 | 		statement:    statement,
174 | 	}
175 | 	return t, nil
176 | }
177 | 
178 | // validate interface
179 | var _ tools.Tool = Tool{}
180 | 
181 | type Tool struct {
182 | 	Name         string           `yaml:"name"`
183 | 	Kind         string           `yaml:"kind"`
184 | 	AuthRequired []string         `yaml:"authRequired"`
185 | 	allParams    tools.Parameters `yaml:"parameters"`
186 | 	Pool         *sql.DB
187 | 	manifest     tools.Manifest
188 | 	mcpManifest  tools.McpManifest
189 | 	statement    string
190 | }
191 | 
192 | func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) {
193 | 	paramsMap := params.AsMap()
194 | 
195 | 	duration, ok := paramsMap["min_duration_secs"].(int)
196 | 	if !ok {
197 | 		return nil, fmt.Errorf("invalid 'min_duration_secs' parameter; expected an integer")
198 | 	}
199 | 	limit, ok := paramsMap["limit"].(int)
200 | 	if !ok {
201 | 		return nil, fmt.Errorf("invalid 'limit' parameter; expected an integer")
202 | 	}
203 | 
204 | 	// Log the query executed for debugging.
205 | 	logger, err := util.LoggerFromContext(ctx)
206 | 	if err != nil {
207 | 		return nil, fmt.Errorf("error getting logger: %s", err)
208 | 	}
209 | 	logger.DebugContext(ctx, "executing `%s` tool query: %s", kind, t.statement)
210 | 
211 | 	results, err := t.Pool.QueryContext(ctx, t.statement, duration, duration, limit)
212 | 	if err != nil {
213 | 		return nil, fmt.Errorf("unable to execute query: %w", err)
214 | 	}
215 | 	defer results.Close()
216 | 
217 | 	cols, err := results.Columns()
218 | 	if err != nil {
219 | 		return nil, fmt.Errorf("unable to retrieve rows column name: %w", err)
220 | 	}
221 | 
222 | 	// create an array of values for each column, which can be re-used to scan each row
223 | 	rawValues := make([]any, len(cols))
224 | 	values := make([]any, len(cols))
225 | 	for i := range rawValues {
226 | 		values[i] = &rawValues[i]
227 | 	}
228 | 
229 | 	colTypes, err := results.ColumnTypes()
230 | 	if err != nil {
231 | 		return nil, fmt.Errorf("unable to get column types: %w", err)
232 | 	}
233 | 
234 | 	var out []any
235 | 	for results.Next() {
236 | 		err := results.Scan(values...)
237 | 		if err != nil {
238 | 			return nil, fmt.Errorf("unable to parse row: %w", err)
239 | 		}
240 | 		vMap := make(map[string]any)
241 | 		for i, name := range cols {
242 | 			val := rawValues[i]
243 | 			if val == nil {
244 | 				vMap[name] = nil
245 | 				continue
246 | 			}
247 | 
248 | 			vMap[name], err = mysqlcommon.ConvertToType(colTypes[i], val)
249 | 			if err != nil {
250 | 				return nil, fmt.Errorf("errors encountered when converting values: %w", err)
251 | 			}
252 | 		}
253 | 		out = append(out, vMap)
254 | 	}
255 | 
256 | 	if err := results.Err(); err != nil {
257 | 		return nil, fmt.Errorf("errors encountered during row iteration: %w", err)
258 | 	}
259 | 
260 | 	return out, nil
261 | }
262 | 
263 | func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) {
264 | 	return tools.ParseParams(t.allParams, data, claims)
265 | }
266 | 
267 | func (t Tool) Manifest() tools.Manifest {
268 | 	return t.manifest
269 | }
270 | 
271 | func (t Tool) McpManifest() tools.McpManifest {
272 | 	return t.mcpManifest
273 | }
274 | 
275 | func (t Tool) Authorized(verifiedAuthServices []string) bool {
276 | 	return tools.IsAuthorized(t.AuthRequired, verifiedAuthServices)
277 | }
278 | 
279 | func (t Tool) RequiresClientAuthorization() bool {
280 | 	return false
281 | }
282 | 
```

--------------------------------------------------------------------------------
/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules.go:
--------------------------------------------------------------------------------

```go
  1 | // Copyright 2025 Google LLC
  2 | //
  3 | // Licensed under the Apache License, Version 2.0 (the "License");
  4 | // you may not use this file except in compliance with the License.
  5 | // You may obtain a copy of the License at
  6 | //
  7 | //     http://www.apache.org/licenses/LICENSE-2.0
  8 | //
  9 | // Unless required by applicable law or agreed to in writing, software
 10 | // distributed under the License is distributed on an "AS IS" BASIS,
 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12 | // See the License for the specific language governing permissions and
 13 | // limitations under the License.
 14 | 
 15 | package firestorevalidaterules
 16 | 
 17 | import (
 18 | 	"context"
 19 | 	"fmt"
 20 | 	"strings"
 21 | 
 22 | 	yaml "github.com/goccy/go-yaml"
 23 | 	"github.com/googleapis/genai-toolbox/internal/sources"
 24 | 	firestoreds "github.com/googleapis/genai-toolbox/internal/sources/firestore"
 25 | 	"github.com/googleapis/genai-toolbox/internal/tools"
 26 | 	"google.golang.org/api/firebaserules/v1"
 27 | )
 28 | 
 29 | const kind string = "firestore-validate-rules"
 30 | 
 31 | // Parameter keys
 32 | const (
 33 | 	sourceKey = "source"
 34 | )
 35 | 
 36 | func init() {
 37 | 	if !tools.Register(kind, newConfig) {
 38 | 		panic(fmt.Sprintf("tool kind %q already registered", kind))
 39 | 	}
 40 | }
 41 | 
 42 | func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.ToolConfig, error) {
 43 | 	actual := Config{Name: name}
 44 | 	if err := decoder.DecodeContext(ctx, &actual); err != nil {
 45 | 		return nil, err
 46 | 	}
 47 | 	return actual, nil
 48 | }
 49 | 
 50 | type compatibleSource interface {
 51 | 	FirebaseRulesClient() *firebaserules.Service
 52 | 	GetProjectId() string
 53 | }
 54 | 
 55 | // validate compatible sources are still compatible
 56 | var _ compatibleSource = &firestoreds.Source{}
 57 | 
 58 | var compatibleSources = [...]string{firestoreds.SourceKind}
 59 | 
 60 | type Config struct {
 61 | 	Name         string   `yaml:"name" validate:"required"`
 62 | 	Kind         string   `yaml:"kind" validate:"required"`
 63 | 	Source       string   `yaml:"source" validate:"required"`
 64 | 	Description  string   `yaml:"description" validate:"required"`
 65 | 	AuthRequired []string `yaml:"authRequired"`
 66 | }
 67 | 
 68 | // validate interface
 69 | var _ tools.ToolConfig = Config{}
 70 | 
 71 | func (cfg Config) ToolConfigKind() string {
 72 | 	return kind
 73 | }
 74 | 
 75 | func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) {
 76 | 	// verify source exists
 77 | 	rawS, ok := srcs[cfg.Source]
 78 | 	if !ok {
 79 | 		return nil, fmt.Errorf("no source named %q configured", cfg.Source)
 80 | 	}
 81 | 
 82 | 	// verify the source is compatible
 83 | 	s, ok := rawS.(compatibleSource)
 84 | 	if !ok {
 85 | 		return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources)
 86 | 	}
 87 | 
 88 | 	// Create parameters
 89 | 	parameters := createParameters()
 90 | 	mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, parameters)
 91 | 
 92 | 	// finish tool setup
 93 | 	t := Tool{
 94 | 		Name:         cfg.Name,
 95 | 		Kind:         kind,
 96 | 		Parameters:   parameters,
 97 | 		AuthRequired: cfg.AuthRequired,
 98 | 		RulesClient:  s.FirebaseRulesClient(),
 99 | 		ProjectId:    s.GetProjectId(),
100 | 		manifest:     tools.Manifest{Description: cfg.Description, Parameters: parameters.Manifest(), AuthRequired: cfg.AuthRequired},
101 | 		mcpManifest:  mcpManifest,
102 | 	}
103 | 	return t, nil
104 | }
105 | 
106 | // createParameters creates the parameter definitions for the tool
107 | func createParameters() tools.Parameters {
108 | 	sourceParameter := tools.NewStringParameter(
109 | 		sourceKey,
110 | 		"The Firestore Rules source code to validate",
111 | 	)
112 | 
113 | 	return tools.Parameters{sourceParameter}
114 | }
115 | 
116 | // validate interface
117 | var _ tools.Tool = Tool{}
118 | 
119 | type Tool struct {
120 | 	Name         string           `yaml:"name"`
121 | 	Kind         string           `yaml:"kind"`
122 | 	AuthRequired []string         `yaml:"authRequired"`
123 | 	Parameters   tools.Parameters `yaml:"parameters"`
124 | 
125 | 	RulesClient *firebaserules.Service
126 | 	ProjectId   string
127 | 	manifest    tools.Manifest
128 | 	mcpManifest tools.McpManifest
129 | }
130 | 
131 | // Issue represents a validation issue in the rules
132 | type Issue struct {
133 | 	SourcePosition SourcePosition `json:"sourcePosition"`
134 | 	Description    string         `json:"description"`
135 | 	Severity       string         `json:"severity"`
136 | }
137 | 
138 | // SourcePosition represents the location of an issue in the source
139 | type SourcePosition struct {
140 | 	FileName      string `json:"fileName,omitempty"`
141 | 	Line          int64  `json:"line"`          // 1-based
142 | 	Column        int64  `json:"column"`        // 1-based
143 | 	CurrentOffset int64  `json:"currentOffset"` // 0-based, inclusive start
144 | 	EndOffset     int64  `json:"endOffset"`     // 0-based, exclusive end
145 | }
146 | 
147 | // ValidationResult represents the result of rules validation
148 | type ValidationResult struct {
149 | 	Valid           bool    `json:"valid"`
150 | 	IssueCount      int     `json:"issueCount"`
151 | 	FormattedIssues string  `json:"formattedIssues,omitempty"`
152 | 	RawIssues       []Issue `json:"rawIssues,omitempty"`
153 | }
154 | 
155 | func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken tools.AccessToken) (any, error) {
156 | 	mapParams := params.AsMap()
157 | 
158 | 	// Get source parameter
159 | 	source, ok := mapParams[sourceKey].(string)
160 | 	if !ok || source == "" {
161 | 		return nil, fmt.Errorf("invalid or missing '%s' parameter", sourceKey)
162 | 	}
163 | 
164 | 	// Create test request
165 | 	testRequest := &firebaserules.TestRulesetRequest{
166 | 		Source: &firebaserules.Source{
167 | 			Files: []*firebaserules.File{
168 | 				{
169 | 					Name:    "firestore.rules",
170 | 					Content: source,
171 | 				},
172 | 			},
173 | 		},
174 | 		// We don't need test cases for validation only
175 | 		TestSuite: &firebaserules.TestSuite{
176 | 			TestCases: []*firebaserules.TestCase{},
177 | 		},
178 | 	}
179 | 
180 | 	// Call the test API
181 | 	projectName := fmt.Sprintf("projects/%s", t.ProjectId)
182 | 	response, err := t.RulesClient.Projects.Test(projectName, testRequest).Context(ctx).Do()
183 | 	if err != nil {
184 | 		return nil, fmt.Errorf("failed to validate rules: %w", err)
185 | 	}
186 | 
187 | 	// Process the response
188 | 	result := t.processValidationResponse(response, source)
189 | 
190 | 	return result, nil
191 | }
192 | 
193 | func (t Tool) processValidationResponse(response *firebaserules.TestRulesetResponse, source string) ValidationResult {
194 | 	if len(response.Issues) == 0 {
195 | 		return ValidationResult{
196 | 			Valid:           true,
197 | 			IssueCount:      0,
198 | 			FormattedIssues: "✓ No errors detected. Rules are valid.",
199 | 		}
200 | 	}
201 | 
202 | 	// Convert issues to our format
203 | 	issues := make([]Issue, len(response.Issues))
204 | 	for i, issue := range response.Issues {
205 | 		issues[i] = Issue{
206 | 			Description: issue.Description,
207 | 			Severity:    issue.Severity,
208 | 			SourcePosition: SourcePosition{
209 | 				FileName:      issue.SourcePosition.FileName,
210 | 				Line:          issue.SourcePosition.Line,
211 | 				Column:        issue.SourcePosition.Column,
212 | 				CurrentOffset: issue.SourcePosition.CurrentOffset,
213 | 				EndOffset:     issue.SourcePosition.EndOffset,
214 | 			},
215 | 		}
216 | 	}
217 | 
218 | 	// Format issues
219 | 	formattedIssues := t.formatRulesetIssues(issues, source)
220 | 
221 | 	return ValidationResult{
222 | 		Valid:           false,
223 | 		IssueCount:      len(issues),
224 | 		FormattedIssues: formattedIssues,
225 | 		RawIssues:       issues,
226 | 	}
227 | }
228 | 
229 | // formatRulesetIssues formats validation issues into a human-readable string with code snippets
230 | func (t Tool) formatRulesetIssues(issues []Issue, rulesSource string) string {
231 | 	sourceLines := strings.Split(rulesSource, "\n")
232 | 	var formattedOutput []string
233 | 
234 | 	formattedOutput = append(formattedOutput, fmt.Sprintf("Found %d issue(s) in rules source:\n", len(issues)))
235 | 
236 | 	for _, issue := range issues {
237 | 		issueString := fmt.Sprintf("%s: %s [Ln %d, Col %d]",
238 | 			issue.Severity,
239 | 			issue.Description,
240 | 			issue.SourcePosition.Line,
241 | 			issue.SourcePosition.Column)
242 | 
243 | 		if issue.SourcePosition.Line > 0 {
244 | 			lineIndex := int(issue.SourcePosition.Line - 1) // 0-based index
245 | 			if lineIndex >= 0 && lineIndex < len(sourceLines) {
246 | 				errorLine := sourceLines[lineIndex]
247 | 				issueString += fmt.Sprintf("\n```\n%s", errorLine)
248 | 
249 | 				// Add carets if we have column and offset information
250 | 				if issue.SourcePosition.Column > 0 &&
251 | 					issue.SourcePosition.CurrentOffset >= 0 &&
252 | 					issue.SourcePosition.EndOffset > issue.SourcePosition.CurrentOffset {
253 | 
254 | 					startColumn := int(issue.SourcePosition.Column - 1) // 0-based
255 | 					errorTokenLength := int(issue.SourcePosition.EndOffset - issue.SourcePosition.CurrentOffset)
256 | 
257 | 					if startColumn >= 0 && errorTokenLength > 0 && startColumn <= len(errorLine) {
258 | 						padding := strings.Repeat(" ", startColumn)
259 | 						carets := strings.Repeat("^", errorTokenLength)
260 | 						issueString += fmt.Sprintf("\n%s%s", padding, carets)
261 | 					}
262 | 				}
263 | 				issueString += "\n```"
264 | 			}
265 | 		}
266 | 
267 | 		formattedOutput = append(formattedOutput, issueString)
268 | 	}
269 | 
270 | 	return strings.Join(formattedOutput, "\n\n")
271 | }
272 | 
273 | func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (tools.ParamValues, error) {
274 | 	return tools.ParseParams(t.Parameters, data, claims)
275 | }
276 | 
277 | func (t Tool) Manifest() tools.Manifest {
278 | 	return t.manifest
279 | }
280 | 
281 | func (t Tool) McpManifest() tools.McpManifest {
282 | 	return t.mcpManifest
283 | }
284 | 
285 | func (t Tool) Authorized(verifiedAuthServices []string) bool {
286 | 	return tools.IsAuthorized(t.AuthRequired, verifiedAuthServices)
287 | }
288 | 
289 | func (t Tool) RequiresClientAuthorization() bool {
290 | 	return false
291 | }
292 | 
```

--------------------------------------------------------------------------------
/docs/en/how-to/connect-ide/cloud_sql_mysql_admin_mcp.md:
--------------------------------------------------------------------------------

```markdown
  1 | ---
  2 | title: "Cloud SQL for MySQL Admin using MCP"
  3 | type: docs
  4 | weight: 4
  5 | description: >
  6 |   Create and manage Cloud SQL for MySQL (Admin) using Toolbox.
  7 | ---
  8 | 
  9 | This guide covers how to use [MCP Toolbox for Databases][toolbox] to expose your
 10 | developer assistant tools to create and manage Cloud SQL for MySQL instance,
 11 | database and users:
 12 | 
 13 | * [Cursor][cursor]
 14 | * [Windsurf][windsurf] (Codium)
 15 | * [Visual Studio Code][vscode] (Copilot)
 16 | * [Cline][cline]  (VS Code extension)
 17 | * [Claude desktop][claudedesktop]
 18 | * [Claude code][claudecode]
 19 | * [Gemini CLI][geminicli]
 20 | * [Gemini Code Assist][geminicodeassist]
 21 | 
 22 | [toolbox]: https://github.com/googleapis/genai-toolbox
 23 | [cursor]: #configure-your-mcp-client
 24 | [windsurf]: #configure-your-mcp-client
 25 | [vscode]: #configure-your-mcp-client
 26 | [cline]: #configure-your-mcp-client
 27 | [claudedesktop]: #configure-your-mcp-client
 28 | [claudecode]: #configure-your-mcp-client
 29 | [geminicli]: #configure-your-mcp-client
 30 | [geminicodeassist]: #configure-your-mcp-client
 31 | 
 32 | ## Before you begin
 33 | 
 34 | 1. In the Google Cloud console, on the [project selector
 35 |    page](https://console.cloud.google.com/projectselector2/home/dashboard),
 36 |    select or create a Google Cloud project.
 37 | 
 38 | 1. [Make sure that billing is enabled for your Google Cloud
 39 |    project](https://cloud.google.com/billing/docs/how-to/verify-billing-enabled#confirm_billing_is_enabled_on_a_project).
 40 | 
 41 | 1. Grant the necessary IAM roles to the user that will be running the MCP
 42 |    server. The tools available will depend on the roles granted:
 43 |     * `roles/cloudsql.viewer`: Provides read-only access to resources.
 44 |         * `get_instance`
 45 |         * `list_instances`
 46 |         * `list_databases`
 47 |         * `wait_for_operation`
 48 |     * `roles/cloudsql.editor`: Provides permissions to manage existing resources.
 49 |         * All `viewer` tools
 50 |         * `create_database`
 51 |     * `roles/cloudsql.admin`: Provides full control over all resources.
 52 |         * All `editor` and `viewer` tools
 53 |         * `create_instance`
 54 |         * `create_user`
 55 | 
 56 | ## Install MCP Toolbox
 57 | 
 58 | 1. Download the latest version of Toolbox as a binary. Select the [correct
 59 |    binary](https://github.com/googleapis/genai-toolbox/releases) corresponding
 60 |    to your OS and CPU architecture. You are required to use Toolbox version
 61 |    V0.15.0+:
 62 | 
 63 |    <!-- {x-release-please-start-version} -->
 64 |    {{< tabpane persist=header >}}
 65 | {{< tab header="linux/amd64" lang="bash" >}}
 66 | curl -O https://storage.googleapis.com/genai-toolbox/v0.15.0/linux/amd64/toolbox
 67 | {{< /tab >}}
 68 | 
 69 | {{< tab header="darwin/arm64" lang="bash" >}}
 70 | curl -O https://storage.googleapis.com/genai-toolbox/v0.15.0/darwin/arm64/toolbox
 71 | {{< /tab >}}
 72 | 
 73 | {{< tab header="darwin/amd64" lang="bash" >}}
 74 | curl -O https://storage.googleapis.com/genai-toolbox/v0.15.0/darwin/amd64/toolbox
 75 | {{< /tab >}}
 76 | 
 77 | {{< tab header="windows/amd64" lang="bash" >}}
 78 | curl -O https://storage.googleapis.com/genai-toolbox/v0.15.0/windows/amd64/toolbox.exe
 79 | {{< /tab >}}
 80 | {{< /tabpane >}}
 81 |     <!-- {x-release-please-end} -->
 82 | 
 83 | 1. Make the binary executable:
 84 | 
 85 |     ```bash
 86 |     chmod +x toolbox
 87 |     ```
 88 | 
 89 | 1. Verify the installation:
 90 | 
 91 |     ```bash
 92 |     ./toolbox --version
 93 |     ```
 94 | 
 95 | ## Configure your MCP Client
 96 | 
 97 | {{< tabpane text=true >}}
 98 | {{% tab header="Claude code" lang="en" %}}
 99 | 
100 | 1. Install [Claude
101 |    Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview).
102 | 1. Create a `.mcp.json` file in your project root if it doesn't exist.
103 | 1. Add the following configuration and save:
104 | 
105 |     ```json
106 |     {
107 |       "mcpServers": {
108 |         "cloud-sql-mysql-admin": {
109 |           "command": "./PATH/TO/toolbox",
110 |           "args": ["--prebuilt","cloud-sql-mysql-admin","--stdio"],
111 |           "env": {
112 |           }
113 |         }
114 |       }
115 |     }
116 |     ```
117 | 
118 | 1. Restart Claude code to apply the new configuration.
119 | {{% /tab %}}
120 | 
121 | {{% tab header="Claude desktop" lang="en" %}}
122 | 
123 | 1. Open [Claude desktop](https://claude.ai/download) and navigate to Settings.
124 | 1. Under the Developer tab, tap Edit Config to open the configuration file.
125 | 1. Add the following configuration and save:
126 | 
127 |     ```json
128 |     {
129 |       "mcpServers": {
130 |         "cloud-sql-mysql-admin": {
131 |           "command": "./PATH/TO/toolbox",
132 |           "args": ["--prebuilt","cloud-sql-mysql-admin","--stdio"],
133 |           "env": {
134 |           }
135 |         }
136 |       }
137 |     }
138 |     ```
139 | 
140 | 1. Restart Claude desktop.
141 | 1. From the new chat screen, you should see a hammer (MCP) icon appear with the
142 |    new MCP server available.
143 | {{% /tab %}}
144 | 
145 | {{% tab header="Cline" lang="en" %}}
146 | 
147 | 1. Open the [Cline](https://github.com/cline/cline) extension in VS Code and tap
148 |    the **MCP Servers** icon.
149 | 1. Tap Configure MCP Servers to open the configuration file.
150 | 1. Add the following configuration and save:
151 | 
152 |     ```json
153 |     {
154 |       "mcpServers": {
155 |         "cloud-sql-mysql-admin": {
156 |           "command": "./PATH/TO/toolbox",
157 |           "args": ["--prebuilt","cloud-sql-mysql-admin","--stdio"],
158 |           "env": {
159 |           }
160 |         }
161 |       }
162 |     }
163 |     ```
164 | 
165 | 1. You should see a green active status after the server is successfully
166 |    connected.
167 | {{% /tab %}}
168 | 
169 | {{% tab header="Cursor" lang="en" %}}
170 | 
171 | 1. Create a `.cursor` directory in your project root if it doesn't exist.
172 | 1. Create a `.cursor/mcp.json` file if it doesn't exist and open it.
173 | 1. Add the following configuration and save:
174 | 
175 |     ```json
176 |     {
177 |       "mcpServers": {
178 |         "cloud-sql-mysql-admin": {
179 |           "command": "./PATH/TO/toolbox",
180 |           "args": ["--prebuilt","cloud-sql-mysql-admin","--stdio"],
181 |           "env": {
182 |           }
183 |         }
184 |       }
185 |     }
186 |     ```
187 | 
188 | 1. [Cursor](https://www.cursor.com/) and navigate to **Settings > Cursor
189 |    Settings > MCP**. You should see a green active status after the server is
190 |    successfully connected.
191 | {{% /tab %}}
192 | 
193 | {{% tab header="Visual Studio Code (Copilot)" lang="en" %}}
194 | 
195 | 1. Open [VS Code](https://code.visualstudio.com/docs/copilot/overview) and
196 |    create a `.vscode` directory in your project root if it doesn't exist.
197 | 1. Create a `.vscode/mcp.json` file if it doesn't exist and open it.
198 | 1. Add the following configuration and save:
199 | 
200 |     ```json
201 |     {
202 |       "servers": {
203 |         "cloud-sql-mysql-admin": {
204 |           "command": "./PATH/TO/toolbox",
205 |           "args": ["--prebuilt","cloud-sql-mysql-admin","--stdio"],
206 |           "env": {
207 |           }
208 |         }
209 |       }
210 |     }
211 |     ```
212 | 
213 | {{% /tab %}}
214 | 
215 | {{% tab header="Windsurf" lang="en" %}}
216 | 
217 | 1. Open [Windsurf](https://docs.codeium.com/windsurf) and navigate to the
218 |    Cascade assistant.
219 | 1. Tap on the hammer (MCP) icon, then Configure to open the configuration file.
220 | 1. Add the following configuration and save:
221 | 
222 |     ```json
223 |     {
224 |       "mcpServers": {
225 |         "cloud-sql-mysql-admin": {
226 |           "command": "./PATH/TO/toolbox",
227 |           "args": ["--prebuilt","cloud-sql-mysql-admin","--stdio"],
228 |           "env": {
229 |           }
230 |         }
231 |       }
232 |     }
233 |     ```
234 | 
235 | {{% /tab %}}
236 | 
237 | {{% tab header="Gemini CLI" lang="en" %}}
238 | 
239 | 1.  Install the [Gemini
240 |     CLI](https://github.com/google-gemini/gemini-cli?tab=readme-ov-file#quickstart).
241 | 1.  In your working directory, create a folder named `.gemini`. Within it,
242 |     create a `settings.json` file.
243 | 1.  Add the following configuration and save:
244 | 
245 |     ```json
246 |     {
247 |       "mcpServers": {
248 |         "cloud-sql-mysql-admin": {
249 |           "command": "./PATH/TO/toolbox",
250 |           "args": ["--prebuilt","cloud-sql-mysql-admin","--stdio"],
251 |           "env": {
252 |           }
253 |         }
254 |       }
255 |     }
256 |     ```
257 | {{% /tab %}}
258 | 
259 | {{% tab header="Gemini Code Assist" lang="en" %}}
260 | 
261 | 1.  Install the [Gemini Code
262 |     Assist](https://marketplace.visualstudio.com/items?itemName=Google.geminicodeassist)
263 |     extension in Visual Studio Code.
264 | 1.  Enable Agent Mode in Gemini Code Assist chat.
265 | 1.  In your working directory, create a folder named `.gemini`. Within it,
266 |     create a `settings.json` file.
267 | 1.  Add the following configuration and save:
268 | 
269 |     ```json
270 |     {
271 |       "mcpServers": {
272 |         "cloud-sql-mysql-admin": {
273 |           "command": "./PATH/TO/toolbox",
274 |           "args": ["--prebuilt","cloud-sql-mysql-admin","--stdio"],
275 |           "env": {
276 |           }
277 |         }
278 |       }
279 |     }
280 |     ```
281 | {{% /tab %}}
282 | {{< /tabpane >}}
283 | 
284 | ## Use Tools
285 | 
286 | Your AI tool is now connected to Cloud SQL for MySQL using MCP.
287 | 
288 | The `cloud-sql-mysql-admin` server provides tools for managing your Cloud SQL
289 | instances and interacting with your database:
290 | * **create_instance**: Creates a new Cloud SQL for MySQL instance.
291 | * **get_instance**: Gets information about a Cloud SQL instance.
292 | * **list_instances**: Lists Cloud SQL instances in a project.
293 | * **create_database**: Creates a new database in a Cloud SQL instance.
294 | * **list_databases**: Lists all databases for a Cloud SQL instance.
295 | * **create_user**: Creates a new user in a Cloud SQL instance.
296 | * **wait_for_operation**: Waits for a Cloud SQL operation to complete.
297 | 
298 | {{< notice note >}}
299 | Prebuilt tools are pre-1.0, so expect some tool changes between versions. LLMs
300 | will adapt to the tools available, so this shouldn't affect most users.
301 | {{< /notice >}}
302 | 
```

--------------------------------------------------------------------------------
/docs/en/how-to/connect-ide/cloud_sql_mssql_admin_mcp.md:
--------------------------------------------------------------------------------

```markdown
  1 | ---
  2 | title: "Cloud SQL for SQL Server Admin using MCP"
  3 | type: docs
  4 | weight: 5
  5 | description: >
  6 |   Create and manage Cloud SQL for SQL Server (Admin) using Toolbox.
  7 | ---
  8 | 
  9 | This guide covers how to use [MCP Toolbox for Databases][toolbox] to expose your
 10 | developer assistant tools to create and manage Cloud SQL for SQL Server
 11 | instance, database and users:
 12 | 
 13 | * [Cursor][cursor]
 14 | * [Windsurf][windsurf] (Codium)
 15 | * [Visual Studio Code][vscode] (Copilot)
 16 | * [Cline][cline]  (VS Code extension)
 17 | * [Claude desktop][claudedesktop]
 18 | * [Claude code][claudecode]
 19 | * [Gemini CLI][geminicli]
 20 | * [Gemini Code Assist][geminicodeassist]
 21 | 
 22 | [toolbox]: https://github.com/googleapis/genai-toolbox
 23 | [cursor]: #configure-your-mcp-client
 24 | [windsurf]: #configure-your-mcp-client
 25 | [vscode]: #configure-your-mcp-client
 26 | [cline]: #configure-your-mcp-client
 27 | [claudedesktop]: #configure-your-mcp-client
 28 | [claudecode]: #configure-your-mcp-client
 29 | [geminicli]: #configure-your-mcp-client
 30 | [geminicodeassist]: #configure-your-mcp-client
 31 | 
 32 | ## Before you begin
 33 | 
 34 | 1. In the Google Cloud console, on the [project selector
 35 |    page](https://console.cloud.google.com/projectselector2/home/dashboard),
 36 |    select or create a Google Cloud project.
 37 | 
 38 | 1. [Make sure that billing is enabled for your Google Cloud
 39 |    project](https://cloud.google.com/billing/docs/how-to/verify-billing-enabled#confirm_billing_is_enabled_on_a_project).
 40 | 
 41 | 1. Grant the necessary IAM roles to the user that will be running the MCP
 42 |    server. The tools available will depend on the roles granted:
 43 |     * `roles/cloudsql.viewer`: Provides read-only access to resources.
 44 |         * `get_instance`
 45 |         * `list_instances`
 46 |         * `list_databases`
 47 |         * `wait_for_operation`
 48 |     * `roles/cloudsql.editor`: Provides permissions to manage existing resources.
 49 |         * All `viewer` tools
 50 |         * `create_database`
 51 |     * `roles/cloudsql.admin`: Provides full control over all resources.
 52 |         * All `editor` and `viewer` tools
 53 |         * `create_instance`
 54 |         * `create_user`
 55 | 
 56 | ## Install MCP Toolbox
 57 | 
 58 | 1. Download the latest version of Toolbox as a binary. Select the [correct
 59 |    binary](https://github.com/googleapis/genai-toolbox/releases) corresponding
 60 |    to your OS and CPU architecture. You are required to use Toolbox version
 61 |    V0.15.0+:
 62 | 
 63 |    <!-- {x-release-please-start-version} -->
 64 |    {{< tabpane persist=header >}}
 65 | {{< tab header="linux/amd64" lang="bash" >}}
 66 | curl -O https://storage.googleapis.com/genai-toolbox/v0.15.0/linux/amd64/toolbox
 67 | {{< /tab >}}
 68 | 
 69 | {{< tab header="darwin/arm64" lang="bash" >}}
 70 | curl -O https://storage.googleapis.com/genai-toolbox/v0.15.0/darwin/arm64/toolbox
 71 | {{< /tab >}}
 72 | 
 73 | {{< tab header="darwin/amd64" lang="bash" >}}
 74 | curl -O https://storage.googleapis.com/genai-toolbox/v0.15.0/darwin/amd64/toolbox
 75 | {{< /tab >}}
 76 | 
 77 | {{< tab header="windows/amd64" lang="bash" >}}
 78 | curl -O https://storage.googleapis.com/genai-toolbox/v0.15.0/windows/amd64/toolbox.exe
 79 | {{< /tab >}}
 80 | {{< /tabpane >}}
 81 |     <!-- {x-release-please-end} -->
 82 | 
 83 | 1. Make the binary executable:
 84 | 
 85 |     ```bash
 86 |     chmod +x toolbox
 87 |     ```
 88 | 
 89 | 1. Verify the installation:
 90 | 
 91 |     ```bash
 92 |     ./toolbox --version
 93 |     ```
 94 | 
 95 | ## Configure your MCP Client
 96 | 
 97 | {{< tabpane text=true >}}
 98 | {{% tab header="Claude code" lang="en" %}}
 99 | 
100 | 1. Install [Claude
101 |    Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview).
102 | 1. Create a `.mcp.json` file in your project root if it doesn't exist.
103 | 1. Add the following configuration and save:
104 | 
105 |     ```json
106 |     {
107 |       "mcpServers": {
108 |         "cloud-sql-mssql-admin": {
109 |           "command": "./PATH/TO/toolbox",
110 |           "args": ["--prebuilt","cloud-sql-mssql-admin","--stdio"],
111 |           "env": {
112 |           }
113 |         }
114 |       }
115 |     }
116 |     ```
117 | 
118 | 1. Restart Claude code to apply the new configuration.
119 | {{% /tab %}}
120 | 
121 | {{% tab header="Claude desktop" lang="en" %}}
122 | 
123 | 1. Open [Claude desktop](https://claude.ai/download) and navigate to Settings.
124 | 1. Under the Developer tab, tap Edit Config to open the configuration file.
125 | 1. Add the following configuration and save:
126 | 
127 |     ```json
128 |     {
129 |       "mcpServers": {
130 |         "cloud-sql-mssql-admin": {
131 |           "command": "./PATH/TO/toolbox",
132 |           "args": ["--prebuilt","cloud-sql-mssql-admin","--stdio"],
133 |           "env": {
134 |           }
135 |         }
136 |       }
137 |     }
138 |     ```
139 | 
140 | 1. Restart Claude desktop.
141 | 1. From the new chat screen, you should see a hammer (MCP) icon appear with the
142 |    new MCP server available.
143 | {{% /tab %}}
144 | 
145 | {{% tab header="Cline" lang="en" %}}
146 | 
147 | 1. Open the [Cline](https://github.com/cline/cline) extension in VS Code and tap
148 |    the **MCP Servers** icon.
149 | 1. Tap Configure MCP Servers to open the configuration file.
150 | 1. Add the following configuration and save:
151 | 
152 |     ```json
153 |     {
154 |       "mcpServers": {
155 |         "cloud-sql-mssql-admin": {
156 |           "command": "./PATH/TO/toolbox",
157 |           "args": ["--prebuilt","cloud-sql-mssql-admin","--stdio"],
158 |           "env": {
159 |           }
160 |         }
161 |       }
162 |     }
163 |     ```
164 | 
165 | 1. You should see a green active status after the server is successfully
166 |    connected.
167 | {{% /tab %}}
168 | 
169 | {{% tab header="Cursor" lang="en" %}}
170 | 
171 | 1. Create a `.cursor` directory in your project root if it doesn't exist.
172 | 1. Create a `.cursor/mcp.json` file if it doesn't exist and open it.
173 | 1. Add the following configuration and save:
174 | 
175 |     ```json
176 |     {
177 |       "mcpServers": {
178 |         "cloud-sql-mssql-admin": {
179 |           "command": "./PATH/TO/toolbox",
180 |           "args": ["--prebuilt","cloud-sql-mssql-admin","--stdio"],
181 |           "env": {
182 |           }
183 |         }
184 |       }
185 |     }
186 |     ```
187 | 
188 | 1. [Cursor](https://www.cursor.com/) and navigate to **Settings > Cursor
189 |    Settings > MCP**. You should see a green active status after the server is
190 |    successfully connected.
191 | {{% /tab %}}
192 | 
193 | {{% tab header="Visual Studio Code (Copilot)" lang="en" %}}
194 | 
195 | 1. Open [VS Code](https://code.visualstudio.com/docs/copilot/overview) and
196 |    create a `.vscode` directory in your project root if it doesn't exist.
197 | 1. Create a `.vscode/mcp.json` file if it doesn't exist and open it.
198 | 1. Add the following configuration and save:
199 | 
200 |     ```json
201 |     {
202 |       "servers": {
203 |         "cloud-sql-mssql-admin": {
204 |           "command": "./PATH/TO/toolbox",
205 |           "args": ["--prebuilt","cloud-sql-mssql-admin","--stdio"],
206 |           "env": {
207 |           }
208 |         }
209 |       }
210 |     }
211 |     ```
212 | 
213 | {{% /tab %}}
214 | 
215 | {{% tab header="Windsurf" lang="en" %}}
216 | 
217 | 1. Open [Windsurf](https://docs.codeium.com/windsurf) and navigate to the
218 |    Cascade assistant.
219 | 1. Tap on the hammer (MCP) icon, then Configure to open the configuration file.
220 | 1. Add the following configuration and save:
221 | 
222 |     ```json
223 |     {
224 |       "mcpServers": {
225 |         "cloud-sql-mssql-admin": {
226 |           "command": "./PATH/TO/toolbox",
227 |           "args": ["--prebuilt","cloud-sql-mssql-admin","--stdio"],
228 |           "env": {
229 |           }
230 |         }
231 |       }
232 |     }
233 |     ```
234 | 
235 | {{% /tab %}}
236 | 
237 | {{% tab header="Gemini CLI" lang="en" %}}
238 | 
239 | 1.  Install the [Gemini
240 |     CLI](https://github.com/google-gemini/gemini-cli?tab=readme-ov-file#quickstart).
241 | 1.  In your working directory, create a folder named `.gemini`. Within it,
242 |     create a `settings.json` file.
243 | 1.  Add the following configuration and save:
244 | 
245 |     ```json
246 |     {
247 |       "mcpServers": {
248 |         "cloud-sql-mssql-admin": {
249 |           "command": "./PATH/TO/toolbox",
250 |           "args": ["--prebuilt","cloud-sql-mssql-admin","--stdio"],
251 |           "env": {
252 |           }
253 |         }
254 |       }
255 |     }
256 |     ```
257 | {{% /tab %}}
258 | 
259 | {{% tab header="Gemini Code Assist" lang="en" %}}
260 | 
261 | 1.  Install the [Gemini Code
262 |     Assist](https://marketplace.visualstudio.com/items?itemName=Google.geminicodeassist)
263 |     extension in Visual Studio Code.
264 | 1.  Enable Agent Mode in Gemini Code Assist chat.
265 | 1.  In your working directory, create a folder named `.gemini`. Within it,
266 |     create a `settings.json` file.
267 | 1.  Add the following configuration and save:
268 | 
269 |     ```json
270 |     {
271 |       "mcpServers": {
272 |         "cloud-sql-mssql-admin": {
273 |           "command": "./PATH/TO/toolbox",
274 |           "args": ["--prebuilt","cloud-sql-mssql-admin","--stdio"],
275 |           "env": {
276 |           }
277 |         }
278 |       }
279 |     }
280 |     ```
281 | {{% /tab %}}
282 | {{< /tabpane >}}
283 | 
284 | ## Use Tools
285 | 
286 | Your AI tool is now connected to Cloud SQL for SQL Server using MCP.
287 | 
288 | The `cloud-sql-mssql-admin` server provides tools for managing your Cloud SQL
289 | instances and interacting with your database:
290 | * **create_instance**: Creates a new Cloud SQL for SQL Server instance.
291 | * **get_instance**: Gets information about a Cloud SQL instance.
292 | * **list_instances**: Lists Cloud SQL instances in a project.
293 | * **create_database**: Creates a new database in a Cloud SQL instance.
294 | * **list_databases**: Lists all databases for a Cloud SQL instance.
295 | * **create_user**: Creates a new user in a Cloud SQL instance.
296 | * **wait_for_operation**: Waits for a Cloud SQL operation to complete.
297 | 
298 | {{< notice note >}}
299 | Prebuilt tools are pre-1.0, so expect some tool changes between versions. LLMs
300 | will adapt to the tools available, so this shouldn't affect most users.
301 | {{< /notice >}}
302 | 
```

--------------------------------------------------------------------------------
/tests/cloudsql/cloudsql_wait_for_operation_test.go:
--------------------------------------------------------------------------------

```go
  1 | // Copyright 2025 Google LLC
  2 | //
  3 | // Licensed under the Apache License, Version 2.0 (the "License");
  4 | // you may not use this file except in compliance with the License.
  5 | // You may obtain a copy of the License at
  6 | //
  7 | //      http://www.apache.org/licenses/LICENSE-2.0
  8 | //
  9 | // Unless required by applicable law or agreed to in writing, software
 10 | // distributed under the License is distributed on an "AS IS" BASIS,
 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12 | // See the License for the specific language governing permissions and
 13 | // limitations under the License.
 14 | 
 15 | package cloudsql
 16 | 
 17 | import (
 18 | 	"bytes"
 19 | 	"context"
 20 | 	"encoding/json"
 21 | 	"fmt"
 22 | 	"io"
 23 | 	"net/http"
 24 | 	"net/http/httptest"
 25 | 	"net/url"
 26 | 	"reflect"
 27 | 	"regexp"
 28 | 	"strings"
 29 | 	"sync"
 30 | 	"testing"
 31 | 	"time"
 32 | 
 33 | 	"github.com/googleapis/genai-toolbox/internal/testutils"
 34 | 	"github.com/googleapis/genai-toolbox/tests"
 35 | 
 36 | 	_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqlwaitforoperation"
 37 | )
 38 | 
 39 | var (
 40 | 	cloudsqlWaitToolKind = "cloud-sql-wait-for-operation"
 41 | )
 42 | 
 43 | type waitForOperationTransport struct {
 44 | 	transport http.RoundTripper
 45 | 	url       *url.URL
 46 | }
 47 | 
 48 | func (t *waitForOperationTransport) RoundTrip(req *http.Request) (*http.Response, error) {
 49 | 	if strings.HasPrefix(req.URL.String(), "https://sqladmin.googleapis.com") {
 50 | 		req.URL.Scheme = t.url.Scheme
 51 | 		req.URL.Host = t.url.Host
 52 | 	}
 53 | 	return t.transport.RoundTrip(req)
 54 | }
 55 | 
 56 | type cloudsqlOperation struct {
 57 | 	Name          string `json:"name"`
 58 | 	Status        string `json:"status"`
 59 | 	TargetLink    string `json:"targetLink"`
 60 | 	OperationType string `json:"operationType"`
 61 | 	Error         *struct {
 62 | 		Errors []struct {
 63 | 			Code    string `json:"code"`
 64 | 			Message string `json:"message"`
 65 | 		} `json:"errors"`
 66 | 	} `json:"error,omitempty"`
 67 | }
 68 | 
 69 | type cloudsqlInstance struct {
 70 | 	Region          string `json:"region"`
 71 | 	DatabaseVersion string `json:"databaseVersion"`
 72 | }
 73 | 
 74 | type cloudsqlHandler struct {
 75 | 	mu         sync.Mutex
 76 | 	operations map[string]*cloudsqlOperation
 77 | 	instances  map[string]*cloudsqlInstance
 78 | 	t          *testing.T
 79 | }
 80 | 
 81 | func (h *cloudsqlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 82 | 	h.mu.Lock()
 83 | 	defer h.mu.Unlock()
 84 | 
 85 | 	if !strings.Contains(r.UserAgent(), "genai-toolbox/") {
 86 | 		h.t.Errorf("User-Agent header not found")
 87 | 	}
 88 | 
 89 | 	if match, _ := regexp.MatchString("/v1/projects/p1/operations/.*", r.URL.Path); match {
 90 | 		parts := regexp.MustCompile("/").Split(r.URL.Path, -1)
 91 | 		opName := parts[len(parts)-1]
 92 | 
 93 | 		op, ok := h.operations[opName]
 94 | 		if !ok {
 95 | 			http.NotFound(w, r)
 96 | 			return
 97 | 		}
 98 | 
 99 | 		if op.Status != "DONE" {
100 | 			op.Status = "DONE"
101 | 		}
102 | 
103 | 		w.Header().Set("Content-Type", "application/json")
104 | 		if err := json.NewEncoder(w).Encode(op); err != nil {
105 | 			http.Error(w, err.Error(), http.StatusInternalServerError)
106 | 		}
107 | 	} else if match, _ := regexp.MatchString("/v1/projects/p1/instances/.*", r.URL.Path); match {
108 | 		parts := regexp.MustCompile("/").Split(r.URL.Path, -1)
109 | 		instanceName := parts[len(parts)-1]
110 | 
111 | 		instance, ok := h.instances[instanceName]
112 | 		if !ok {
113 | 			http.NotFound(w, r)
114 | 			return
115 | 		}
116 | 		w.Header().Set("Content-Type", "application/json")
117 | 		if err := json.NewEncoder(w).Encode(instance); err != nil {
118 | 			http.Error(w, err.Error(), http.StatusInternalServerError)
119 | 		}
120 | 	} else {
121 | 		http.NotFound(w, r)
122 | 	}
123 | }
124 | 
125 | func TestCloudSQLWaitToolEndpoints(t *testing.T) {
126 | 	h := &cloudsqlHandler{
127 | 		operations: map[string]*cloudsqlOperation{
128 | 			"op1": {Name: "op1", Status: "PENDING", OperationType: "CREATE_DATABASE"},
129 | 			"op2": {Name: "op2", Status: "PENDING", OperationType: "CREATE_DATABASE", Error: &struct {
130 | 				Errors []struct {
131 | 					Code    string `json:"code"`
132 | 					Message string `json:"message"`
133 | 				} `json:"errors"`
134 | 			}{
135 | 				Errors: []struct {
136 | 					Code    string `json:"code"`
137 | 					Message string `json:"message"`
138 | 				}{
139 | 					{Code: "ERROR_CODE", Message: "failed"},
140 | 				},
141 | 			}},
142 | 			"op3": {Name: "op3", Status: "PENDING", OperationType: "CREATE"},
143 | 		},
144 | 		instances: map[string]*cloudsqlInstance{
145 | 			"i1": {Region: "r1", DatabaseVersion: "POSTGRES_13"},
146 | 		},
147 | 		t: t,
148 | 	}
149 | 	server := httptest.NewServer(h)
150 | 	defer server.Close()
151 | 
152 | 	h.operations["op1"].TargetLink = "https://sqladmin.googleapis.com/v1/projects/p1/instances/i1/databases/d1"
153 | 	h.operations["op2"].TargetLink = "https://sqladmin.googleapis.com/v1/projects/p1/instances/i2/databases/d2"
154 | 	h.operations["op3"].TargetLink = "https://sqladmin.googleapis.com/v1/projects/p1/instances/i1"
155 | 
156 | 	serverURL, err := url.Parse(server.URL)
157 | 	if err != nil {
158 | 		t.Fatalf("failed to parse server URL: %v", err)
159 | 	}
160 | 
161 | 	originalTransport := http.DefaultClient.Transport
162 | 	if originalTransport == nil {
163 | 		originalTransport = http.DefaultTransport
164 | 	}
165 | 	http.DefaultClient.Transport = &waitForOperationTransport{
166 | 		transport: originalTransport,
167 | 		url:       serverURL,
168 | 	}
169 | 	t.Cleanup(func() {
170 | 		http.DefaultClient.Transport = originalTransport
171 | 	})
172 | 
173 | 	ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
174 | 	defer cancel()
175 | 
176 | 	var args []string
177 | 
178 | 	toolsFile := getCloudSQLWaitToolsConfig()
179 | 	cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...)
180 | 	if err != nil {
181 | 		t.Fatalf("command initialization returned an error: %s", err)
182 | 	}
183 | 	defer cleanup()
184 | 
185 | 	waitCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
186 | 	defer cancel()
187 | 	out, err := testutils.WaitForString(waitCtx, regexp.MustCompile(`Server ready to serve`), cmd.Out)
188 | 	if err != nil {
189 | 		t.Logf("toolbox command logs: \n%s", out)
190 | 		t.Fatalf("toolbox didn't start successfully: %s", err)
191 | 	}
192 | 
193 | 	tcs := []struct {
194 | 		name          string
195 | 		toolName      string
196 | 		body          string
197 | 		want          string
198 | 		expectError   bool
199 | 		wantSubstring bool
200 | 	}{
201 | 		{
202 | 			name:          "successful operation",
203 | 			toolName:      "wait-for-op1",
204 | 			body:          `{"project": "p1", "operation": "op1"}`,
205 | 			want:          "Your Cloud SQL resource is ready",
206 | 			wantSubstring: true,
207 | 		},
208 | 		{
209 | 			name:        "failed operation",
210 | 			toolName:    "wait-for-op2",
211 | 			body:        `{"project": "p1", "operation": "op2"}`,
212 | 			expectError: true,
213 | 		},
214 | 		{
215 | 			name:     "non-database create operation",
216 | 			toolName: "wait-for-op3",
217 | 			body:     `{"project": "p1", "operation": "op3"}`,
218 | 			want:     `{"name":"op3","status":"DONE","targetLink":"` + h.operations["op3"].TargetLink + `","operationType":"CREATE"}`,
219 | 		},
220 | 	}
221 | 
222 | 	for _, tc := range tcs {
223 | 		t.Run(tc.name, func(t *testing.T) {
224 | 			api := fmt.Sprintf("http://127.0.0.1:5000/api/tool/%s/invoke", tc.toolName)
225 | 			req, err := http.NewRequest(http.MethodPost, api, bytes.NewBufferString(tc.body))
226 | 			if err != nil {
227 | 				t.Fatalf("unable to create request: %s", err)
228 | 			}
229 | 			req.Header.Add("Content-type", "application/json")
230 | 			resp, err := http.DefaultClient.Do(req)
231 | 			if err != nil {
232 | 				t.Fatalf("unable to send request: %s", err)
233 | 			}
234 | 			defer resp.Body.Close()
235 | 
236 | 			if tc.expectError {
237 | 				if resp.StatusCode == http.StatusOK {
238 | 					t.Fatal("expected error but got status 200")
239 | 				}
240 | 				return
241 | 			}
242 | 
243 | 			if resp.StatusCode != http.StatusOK {
244 | 				bodyBytes, _ := io.ReadAll(resp.Body)
245 | 				t.Fatalf("response status code is not 200, got %d: %s", resp.StatusCode, string(bodyBytes))
246 | 			}
247 | 
248 | 			if tc.wantSubstring {
249 | 				var result struct {
250 | 					Result string `json:"result"`
251 | 				}
252 | 				if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
253 | 					t.Fatalf("failed to decode response: %v", err)
254 | 				}
255 | 
256 | 				if !bytes.Contains([]byte(result.Result), []byte(tc.want)) {
257 | 					t.Fatalf("unexpected result: got %q, want substring %q", result.Result, tc.want)
258 | 				}
259 | 				return
260 | 			}
261 | 
262 | 			var result struct {
263 | 				Result string `json:"result"`
264 | 			}
265 | 			if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
266 | 				t.Fatalf("failed to decode response: %v", err)
267 | 			}
268 | 
269 | 			var tempString string
270 | 			if err := json.Unmarshal([]byte(result.Result), &tempString); err != nil {
271 | 				t.Fatalf("failed to unmarshal outer JSON string: %v", err)
272 | 			}
273 | 
274 | 			var got, want map[string]any
275 | 			if err := json.Unmarshal([]byte(tempString), &got); err != nil {
276 | 				t.Fatalf("failed to unmarshal inner JSON object: %v", err)
277 | 			}
278 | 
279 | 			if err := json.Unmarshal([]byte(tc.want), &want); err != nil {
280 | 				t.Fatalf("failed to unmarshal want: %v", err)
281 | 			}
282 | 
283 | 			if !reflect.DeepEqual(got, want) {
284 | 				t.Fatalf("unexpected result: got %+v, want %+v", got, want)
285 | 			}
286 | 		})
287 | 	}
288 | }
289 | 
290 | func getCloudSQLWaitToolsConfig() map[string]any {
291 | 	return map[string]any{
292 | 		"sources": map[string]any{
293 | 			"my-cloud-sql-source": map[string]any{
294 | 				"kind": "cloud-sql-admin",
295 | 			},
296 | 		},
297 | 		"tools": map[string]any{
298 | 			"wait-for-op1": map[string]any{
299 | 				"kind":        cloudsqlWaitToolKind,
300 | 				"source":      "my-cloud-sql-source",
301 | 				"description": "wait for op1",
302 | 			},
303 | 			"wait-for-op2": map[string]any{
304 | 				"kind":        cloudsqlWaitToolKind,
305 | 				"source":      "my-cloud-sql-source",
306 | 				"description": "wait for op2",
307 | 			},
308 | 			"wait-for-op3": map[string]any{
309 | 				"kind":        cloudsqlWaitToolKind,
310 | 				"source":      "my-cloud-sql-source",
311 | 				"description": "wait for op3",
312 | 			},
313 | 		},
314 | 	}
315 | }
316 | 
```

--------------------------------------------------------------------------------
/tests/oceanbase/oceanbase_integration_test.go:
--------------------------------------------------------------------------------

```go
  1 | // Copyright 2025 Google LLC
  2 | //
  3 | // Licensed under the Apache License, Version 2.0 (the "License");
  4 | // you may not use this file except in compliance with the License.
  5 | // You may obtain a copy of the License at
  6 | //
  7 | //     http://www.apache.org/licenses/LICENSE-2.0
  8 | //
  9 | // Unless required by applicable law or agreed to in writing, software
 10 | // distributed under the License is distributed on an "AS IS" BASIS,
 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12 | // See the License for the specific language governing permissions and
 13 | // limitations under the License.
 14 | 
 15 | package oceanbase
 16 | 
 17 | import (
 18 | 	"context"
 19 | 	"database/sql"
 20 | 	"fmt"
 21 | 	"os"
 22 | 	"regexp"
 23 | 	"strings"
 24 | 	"testing"
 25 | 	"time"
 26 | 
 27 | 	"github.com/google/uuid"
 28 | 	"github.com/googleapis/genai-toolbox/internal/testutils"
 29 | 	"github.com/googleapis/genai-toolbox/tests"
 30 | 
 31 | 	_ "github.com/go-sql-driver/mysql"
 32 | )
 33 | 
 34 | var (
 35 | 	OceanBaseSourceKind = "oceanbase"
 36 | 	OceanBaseToolKind   = "oceanbase-sql"
 37 | 	OceanBaseDatabase   = os.Getenv("OCEANBASE_DATABASE")
 38 | 	OceanBaseHost       = os.Getenv("OCEANBASE_HOST")
 39 | 	OceanBasePort       = os.Getenv("OCEANBASE_PORT")
 40 | 	OceanBaseUser       = os.Getenv("OCEANBASE_USER")
 41 | 	OceanBasePass       = os.Getenv("OCEANBASE_PASSWORD")
 42 | )
 43 | 
 44 | func getOceanBaseVars(t *testing.T) map[string]any {
 45 | 	switch "" {
 46 | 	case OceanBaseDatabase:
 47 | 		t.Fatal("'OCEANBASE_DATABASE' not set")
 48 | 	case OceanBaseHost:
 49 | 		t.Fatal("'OCEANBASE_HOST' not set")
 50 | 	case OceanBasePort:
 51 | 		t.Fatal("'OCEANBASE_PORT' not set")
 52 | 	case OceanBaseUser:
 53 | 		t.Fatal("'OCEANBASE_USER' not set")
 54 | 	case OceanBasePass:
 55 | 		t.Fatal("'OCEANBASE_PASSWORD' not set")
 56 | 	}
 57 | 
 58 | 	return map[string]any{
 59 | 		"kind":     OceanBaseSourceKind,
 60 | 		"host":     OceanBaseHost,
 61 | 		"port":     OceanBasePort,
 62 | 		"database": OceanBaseDatabase,
 63 | 		"user":     OceanBaseUser,
 64 | 		"password": OceanBasePass,
 65 | 	}
 66 | }
 67 | 
 68 | // Copied over from oceanbase.go
 69 | func initOceanBaseConnectionPool(host, port, user, pass, dbname string) (*sql.DB, error) {
 70 | 	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?parseTime=true", user, pass, host, port, dbname)
 71 | 
 72 | 	// Interact with the driver directly as you normally would
 73 | 	pool, err := sql.Open("mysql", dsn)
 74 | 	if err != nil {
 75 | 		return nil, fmt.Errorf("sql.Open: %w", err)
 76 | 	}
 77 | 	return pool, nil
 78 | }
 79 | 
 80 | func TestOceanBaseToolEndpoints(t *testing.T) {
 81 | 	sourceConfig := getOceanBaseVars(t)
 82 | 	ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
 83 | 	defer cancel()
 84 | 
 85 | 	var args []string
 86 | 
 87 | 	pool, err := initOceanBaseConnectionPool(OceanBaseHost, OceanBasePort, OceanBaseUser, OceanBasePass, OceanBaseDatabase)
 88 | 	if err != nil {
 89 | 		t.Fatalf("unable to create OceanBase connection pool: %s", err)
 90 | 	}
 91 | 
 92 | 	// create table name with UUID
 93 | 	tableNameParam := "param_table_" + strings.ReplaceAll(uuid.New().String(), "-", "")
 94 | 	tableNameAuth := "auth_table_" + strings.ReplaceAll(uuid.New().String(), "-", "")
 95 | 	tableNameTemplateParam := "template_param_table_" + strings.ReplaceAll(uuid.New().String(), "-", "")
 96 | 
 97 | 	// set up data for param tool
 98 | 	createParamTableStmt, insertParamTableStmt, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, paramTestParams := getOceanBaseParamToolInfo(tableNameParam)
 99 | 	teardownTable1 := setupOceanBaseTable(t, ctx, pool, createParamTableStmt, insertParamTableStmt, tableNameParam, paramTestParams)
100 | 	defer teardownTable1(t)
101 | 
102 | 	// set up data for auth tool
103 | 	createAuthTableStmt, insertAuthTableStmt, authToolStmt, authTestParams := getOceanBaseAuthToolInfo(tableNameAuth)
104 | 	teardownTable2 := setupOceanBaseTable(t, ctx, pool, createAuthTableStmt, insertAuthTableStmt, tableNameAuth, authTestParams)
105 | 	defer teardownTable2(t)
106 | 
107 | 	// Write config into a file and pass it to command
108 | 	toolsFile := tests.GetToolsConfig(sourceConfig, OceanBaseToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt)
109 | 	toolsFile = addOceanBaseExecuteSqlConfig(t, toolsFile)
110 | 	tmplSelectCombined, tmplSelectFilterCombined := getOceanBaseTmplToolStatement()
111 | 	toolsFile = tests.AddTemplateParamConfig(t, toolsFile, OceanBaseToolKind, tmplSelectCombined, tmplSelectFilterCombined, "")
112 | 
113 | 	cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...)
114 | 	if err != nil {
115 | 		t.Fatalf("command initialization returned an error: %s", err)
116 | 	}
117 | 	defer cleanup()
118 | 
119 | 	waitCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
120 | 	defer cancel()
121 | 	out, err := testutils.WaitForString(waitCtx, regexp.MustCompile(`Server ready to serve`), cmd.Out)
122 | 	if err != nil {
123 | 		t.Logf("toolbox command logs: \n%s", out)
124 | 		t.Fatalf("toolbox didn't start successfully: %s", err)
125 | 	}
126 | 
127 | 	// Get configs for tests
128 | 	select1Want, mcpMyFailToolWant, createTableStatement, mcpSelect1Want := getOceanBaseWants()
129 | 
130 | 	// Run tests
131 | 	tests.RunToolGetTest(t)
132 | 	tests.RunToolInvokeTest(t, select1Want, tests.DisableArrayTest())
133 | 	tests.RunMCPToolCallMethod(t, mcpMyFailToolWant, mcpSelect1Want)
134 | 	tests.RunExecuteSqlToolInvokeTest(t, createTableStatement, select1Want)
135 | 	tests.RunToolInvokeWithTemplateParameters(t, tableNameTemplateParam)
136 | }
137 | 
138 | // OceanBase specific parameter tool info
139 | func getOceanBaseParamToolInfo(tableName string) (string, string, string, string, string, string, []any) {
140 | 	createStatement := fmt.Sprintf("CREATE TABLE %s (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255));", tableName)
141 | 	insertStatement := fmt.Sprintf("INSERT INTO %s (name) VALUES (?), (?), (?), (?);", tableName)
142 | 	toolStatement := fmt.Sprintf("SELECT * FROM %s WHERE id = ? OR name = ?;", tableName)
143 | 	idParamStatement := fmt.Sprintf("SELECT * FROM %s WHERE id = ?;", tableName)
144 | 	nameParamStatement := fmt.Sprintf("SELECT * FROM %s WHERE name = ?;", tableName)
145 | 	arrayToolStatement := fmt.Sprintf("SELECT * FROM %s WHERE id = ANY(?) AND name = ANY(?);", tableName)
146 | 	params := []any{"Alice", "Jane", "Sid", nil}
147 | 	return createStatement, insertStatement, toolStatement, idParamStatement, nameParamStatement, arrayToolStatement, params
148 | }
149 | 
150 | // OceanBase specific auth tool info
151 | func getOceanBaseAuthToolInfo(tableName string) (string, string, string, []any) {
152 | 	createStatement := fmt.Sprintf("CREATE TABLE %s (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), email VARCHAR(255));", tableName)
153 | 	insertStatement := fmt.Sprintf("INSERT INTO %s (name, email) VALUES (?, ?), (?, ?)", tableName)
154 | 	toolStatement := fmt.Sprintf("SELECT name FROM %s WHERE email = ?;", tableName)
155 | 	params := []any{"Alice", tests.ServiceAccountEmail, "Jane", "[email protected]"}
156 | 	return createStatement, insertStatement, toolStatement, params
157 | }
158 | 
159 | // OceanBase specific template tool statements
160 | func getOceanBaseTmplToolStatement() (string, string) {
161 | 	tmplSelectCombined := "SELECT * FROM {{.tableName}} WHERE id = ?"
162 | 	tmplSelectFilterCombined := "SELECT * FROM {{.tableName}} WHERE {{.columnFilter}} = ?"
163 | 	return tmplSelectCombined, tmplSelectFilterCombined
164 | }
165 | 
166 | // OceanBase specific expected results
167 | func getOceanBaseWants() (string, string, string, string) {
168 | 	select1Want := "[{\"1\":1}]"
169 | 	mcpMyFailToolWant := `{"jsonrpc":"2.0","id":"invoke-fail-tool","result":{"content":[{"type":"text","text":"unable to execute query: Error 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your OceanBase version for the right syntax to use near 'SELEC 1;' at line 1"}],"isError":true}}`
170 | 	createTableStatement := `"CREATE TABLE t (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255))"`
171 | 	mcpSelect1Want := `{"jsonrpc":"2.0","id":"invoke my-auth-required-tool","result":{"content":[{"type":"text","text":"{\"1\":1}"}]}}`
172 | 	return select1Want, mcpMyFailToolWant, createTableStatement, mcpSelect1Want
173 | }
174 | 
175 | // Add OceanBase Execute SQL configuration
176 | func addOceanBaseExecuteSqlConfig(t *testing.T, config map[string]any) map[string]any {
177 | 	tools, ok := config["tools"].(map[string]any)
178 | 	if !ok {
179 | 		t.Fatalf("unable to get tools from config")
180 | 	}
181 | 	tools["my-exec-sql-tool"] = map[string]any{
182 | 		"kind":        "oceanbase-execute-sql",
183 | 		"source":      "my-instance",
184 | 		"description": "Tool to execute sql",
185 | 	}
186 | 	tools["my-auth-exec-sql-tool"] = map[string]any{
187 | 		"kind":        "oceanbase-execute-sql",
188 | 		"source":      "my-instance",
189 | 		"description": "Tool to execute sql",
190 | 		"authRequired": []string{
191 | 			"my-google-auth",
192 | 		},
193 | 	}
194 | 	config["tools"] = tools
195 | 	return config
196 | }
197 | 
198 | // Setup OceanBase table
199 | func setupOceanBaseTable(t *testing.T, ctx context.Context, pool *sql.DB, createStatement, insertStatement, tableName string, params []any) func(*testing.T) {
200 | 	err := pool.PingContext(ctx)
201 | 	if err != nil {
202 | 		t.Fatalf("unable to connect to test database: %s", err)
203 | 	}
204 | 
205 | 	// Create table
206 | 	_, err = pool.QueryContext(ctx, createStatement)
207 | 	if err != nil {
208 | 		t.Fatalf("unable to create test table %s: %s", tableName, err)
209 | 	}
210 | 
211 | 	// Insert test data
212 | 	_, err = pool.QueryContext(ctx, insertStatement, params...)
213 | 	if err != nil {
214 | 		t.Fatalf("unable to insert test data: %s", err)
215 | 	}
216 | 
217 | 	return func(t *testing.T) {
218 | 		// tear down test
219 | 		_, err = pool.ExecContext(ctx, fmt.Sprintf("DROP TABLE %s;", tableName))
220 | 		if err != nil {
221 | 			t.Errorf("Teardown failed: %s", err)
222 | 		}
223 | 	}
224 | }
225 | 
```

--------------------------------------------------------------------------------
/docs/en/how-to/connect-ide/cloud_sql_pg_admin_mcp.md:
--------------------------------------------------------------------------------

```markdown
  1 | ---
  2 | title: "Cloud SQL for PostgreSQL Admin using MCP"
  3 | type: docs
  4 | weight: 3
  5 | description: >
  6 |   Create and manage Cloud SQL for PostgreSQL (Admin) using Toolbox.
  7 | ---
  8 | 
  9 | This guide covers how to use [MCP Toolbox for Databases][toolbox] to expose your
 10 | developer assistant tools to create and manage Cloud SQL for PostgreSQL
 11 | instance, database and users:
 12 | 
 13 | * [Cursor][cursor]
 14 | * [Windsurf][windsurf] (Codium)
 15 | * [Visual Studio Code][vscode] (Copilot)
 16 | * [Cline][cline]  (VS Code extension)
 17 | * [Claude desktop][claudedesktop]
 18 | * [Claude code][claudecode]
 19 | * [Gemini CLI][geminicli]
 20 | * [Gemini Code Assist][geminicodeassist]
 21 | 
 22 | [toolbox]: https://github.com/googleapis/genai-toolbox
 23 | [cursor]: #configure-your-mcp-client
 24 | [windsurf]: #configure-your-mcp-client
 25 | [vscode]: #configure-your-mcp-client
 26 | [cline]: #configure-your-mcp-client
 27 | [claudedesktop]: #configure-your-mcp-client
 28 | [claudecode]: #configure-your-mcp-client
 29 | [geminicli]: #configure-your-mcp-client
 30 | [geminicodeassist]: #configure-your-mcp-client
 31 | 
 32 | ## Before you begin
 33 | 
 34 | 1. In the Google Cloud console, on the [project selector
 35 |    page](https://console.cloud.google.com/projectselector2/home/dashboard),
 36 |    select or create a Google Cloud project.
 37 | 
 38 | 1. [Make sure that billing is enabled for your Google Cloud
 39 |    project](https://cloud.google.com/billing/docs/how-to/verify-billing-enabled#confirm_billing_is_enabled_on_a_project).
 40 | 
 41 | 1. Grant the necessary IAM roles to the user that will be running the MCP
 42 |    server. The tools available will depend on the roles granted:
 43 |     * `roles/cloudsql.viewer`: Provides read-only access to resources.
 44 |         * `get_instance`
 45 |         * `list_instances`
 46 |         * `list_databases`
 47 |         * `wait_for_operation`
 48 |     * `roles/cloudsql.editor`: Provides permissions to manage existing resources.
 49 |         * All `viewer` tools
 50 |         * `create_database`
 51 |     * `roles/cloudsql.admin`: Provides full control over all resources.
 52 |         * All `editor` and `viewer` tools
 53 |         * `create_instance`
 54 |         * `create_user`
 55 | 
 56 | ## Install MCP Toolbox
 57 | 
 58 | 1. Download the latest version of Toolbox as a binary. Select the [correct
 59 |    binary](https://github.com/googleapis/genai-toolbox/releases) corresponding
 60 |    to your OS and CPU architecture. You are required to use Toolbox version
 61 |    V0.15.0+:
 62 | 
 63 |    <!-- {x-release-please-start-version} -->
 64 |    {{< tabpane persist=header >}}
 65 | {{< tab header="linux/amd64" lang="bash" >}}
 66 | curl -O https://storage.googleapis.com/genai-toolbox/v0.15.0/linux/amd64/toolbox
 67 | {{< /tab >}}
 68 | 
 69 | {{< tab header="darwin/arm64" lang="bash" >}}
 70 | curl -O https://storage.googleapis.com/genai-toolbox/v0.15.0/darwin/arm64/toolbox
 71 | {{< /tab >}}
 72 | 
 73 | {{< tab header="darwin/amd64" lang="bash" >}}
 74 | curl -O https://storage.googleapis.com/genai-toolbox/v0.15.0/darwin/amd64/toolbox
 75 | {{< /tab >}}
 76 | 
 77 | {{< tab header="windows/amd64" lang="bash" >}}
 78 | curl -O https://storage.googleapis.com/genai-toolbox/v0.15.0/windows/amd64/toolbox.exe
 79 | {{< /tab >}}
 80 | {{< /tabpane >}}
 81 |     <!-- {x-release-please-end} -->
 82 | 
 83 | 1. Make the binary executable:
 84 | 
 85 |     ```bash
 86 |     chmod +x toolbox
 87 |     ```
 88 | 
 89 | 1. Verify the installation:
 90 | 
 91 |     ```bash
 92 |     ./toolbox --version
 93 |     ```
 94 | 
 95 | ## Configure your MCP Client
 96 | 
 97 | {{< tabpane text=true >}}
 98 | {{% tab header="Claude code" lang="en" %}}
 99 | 
100 | 1. Install [Claude
101 |    Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview).
102 | 1. Create a `.mcp.json` file in your project root if it doesn't exist.
103 | 1. Add the following configuration and save:
104 | 
105 |     ```json
106 |     {
107 |       "mcpServers": {
108 |         "cloud-sql-postgres-admin": {
109 |           "command": "./PATH/TO/toolbox",
110 |           "args": ["--prebuilt","cloud-sql-postgres-admin","--stdio"],
111 |           "env": {
112 |           }
113 |         }
114 |       }
115 |     }
116 |     ```
117 | 
118 | 1. Restart Claude code to apply the new configuration.
119 | {{% /tab %}}
120 | 
121 | {{% tab header="Claude desktop" lang="en" %}}
122 | 
123 | 1. Open [Claude desktop](https://claude.ai/download) and navigate to Settings.
124 | 1. Under the Developer tab, tap Edit Config to open the configuration file.
125 | 1. Add the following configuration and save:
126 | 
127 |     ```json
128 |     {
129 |       "mcpServers": {
130 |         "cloud-sql-postgres-admin": {
131 |           "command": "./PATH/TO/toolbox",
132 |           "args": ["--prebuilt","cloud-sql-postgres-admin","--stdio"],
133 |           "env": {
134 |           }
135 |         }
136 |       }
137 |     }
138 |     ```
139 | 
140 | 1. Restart Claude desktop.
141 | 1. From the new chat screen, you should see a hammer (MCP) icon appear with the
142 |    new MCP server available.
143 | {{% /tab %}}
144 | 
145 | {{% tab header="Cline" lang="en" %}}
146 | 
147 | 1. Open the [Cline](https://github.com/cline/cline) extension in VS Code and tap
148 |    the **MCP Servers** icon.
149 | 1. Tap Configure MCP Servers to open the configuration file.
150 | 1. Add the following configuration and save:
151 | 
152 |     ```json
153 |     {
154 |       "mcpServers": {
155 |         "cloud-sql-postgres-admin": {
156 |           "command": "./PATH/TO/toolbox",
157 |           "args": ["--prebuilt","cloud-sql-postgres-admin","--stdio"],
158 |           "env": {
159 |           }
160 |         }
161 |       }
162 |     }
163 |     ```
164 | 
165 | 1. You should see a green active status after the server is successfully
166 |    connected.
167 | {{% /tab %}}
168 | 
169 | {{% tab header="Cursor" lang="en" %}}
170 | 
171 | 1. Create a `.cursor` directory in your project root if it doesn't exist.
172 | 1. Create a `.cursor/mcp.json` file if it doesn't exist and open it.
173 | 1. Add the following configuration and save:
174 | 
175 |     ```json
176 |     {
177 |       "mcpServers": {
178 |         "cloud-sql-postgres-admin": {
179 |           "command": "./PATH/TO/toolbox",
180 |           "args": ["--prebuilt","cloud-sql-postgres-admin","--stdio"],
181 |           "env": {
182 |           }
183 |         }
184 |       }
185 |     }
186 |     ```
187 | 
188 | 1. [Cursor](https://www.cursor.com/) and navigate to **Settings > Cursor
189 |    Settings > MCP**. You should see a green active status after the server is
190 |    successfully connected.
191 | {{% /tab %}}
192 | 
193 | {{% tab header="Visual Studio Code (Copilot)" lang="en" %}}
194 | 
195 | 1. Open [VS Code](https://code.visualstudio.com/docs/copilot/overview) and
196 |    create a `.vscode` directory in your project root if it doesn't exist.
197 | 1. Create a `.vscode/mcp.json` file if it doesn't exist and open it.
198 | 1. Add the following configuration and save:
199 | 
200 |     ```json
201 |     {
202 |       "servers": {
203 |         "cloud-sql-postgres-admin": {
204 |           "command": "./PATH/TO/toolbox",
205 |           "args": ["--prebuilt","cloud-sql-postgres-admin","--stdio"],
206 |           "env": {
207 |           }
208 |         }
209 |       }
210 |     }
211 |     ```
212 | 
213 | {{% /tab %}}
214 | 
215 | {{% tab header="Windsurf" lang="en" %}}
216 | 
217 | 1. Open [Windsurf](https://docs.codeium.com/windsurf) and navigate to the
218 |    Cascade assistant.
219 | 1. Tap on the hammer (MCP) icon, then Configure to open the configuration file.
220 | 1. Add the following configuration and save:
221 | 
222 |     ```json
223 |     {
224 |       "mcpServers": {
225 |         "cloud-sql-postgres-admin": {
226 |           "command": "./PATH/TO/toolbox",
227 |           "args": ["--prebuilt","cloud-sql-postgres-admin","--stdio"],
228 |           "env": {
229 |           }
230 |         }
231 |       }
232 |     }
233 |     ```
234 | 
235 | {{% /tab %}}
236 | 
237 | {{% tab header="Gemini CLI" lang="en" %}}
238 | 
239 | 1.  Install the [Gemini
240 |     CLI](https://github.com/google-gemini/gemini-cli?tab=readme-ov-file#quickstart).
241 | 1.  In your working directory, create a folder named `.gemini`. Within it,
242 |     create a `settings.json` file.
243 | 1.  Add the following configuration and save:
244 | 
245 |     ```json
246 |     {
247 |       "mcpServers": {
248 |         "cloud-sql-postgres-admin": {
249 |           "command": "./PATH/TO/toolbox",
250 |           "args": ["--prebuilt","cloud-sql-postgres-admin","--stdio"],
251 |           "env": {
252 |           }
253 |         }
254 |       }
255 |     }
256 |     ```
257 | {{% /tab %}}
258 | 
259 | {{% tab header="Gemini Code Assist" lang="en" %}}
260 | 
261 | 1.  Install the [Gemini Code
262 |     Assist](https://marketplace.visualstudio.com/items?itemName=Google.geminicodeassist)
263 |     extension in Visual Studio Code.
264 | 1.  Enable Agent Mode in Gemini Code Assist chat.
265 | 1.  In your working directory, create a folder named `.gemini`. Within it,
266 |     create a `settings.json` file.
267 | 1.  Add the following configuration and save:
268 | 
269 |     ```json
270 |     {
271 |       "mcpServers": {
272 |         "cloud-sql-postgres-admin": {
273 |           "command": "./PATH/TO/toolbox",
274 |           "args": ["--prebuilt","cloud-sql-postgres-admin","--stdio"],
275 |           "env": {
276 |           }
277 |         }
278 |       }
279 |     }
280 |     ```
281 | {{% /tab %}}
282 | {{< /tabpane >}}
283 | 
284 | ## Use Tools
285 | 
286 | Your AI tool is now connected to Cloud SQL for PostgreSQL using MCP.
287 | 
288 | The `cloud-sql-postgres-admin` server provides tools for managing your Cloud SQL
289 | instances and interacting with your database:
290 | * **create_instance**: Creates a new Cloud SQL for PostgreSQL instance.
291 | * **get_instance**: Gets information about a Cloud SQL instance.
292 | * **list_instances**: Lists Cloud SQL instances in a project.
293 | * **create_database**: Creates a new database in a Cloud SQL instance.
294 | * **list_databases**: Lists all databases for a Cloud SQL instance.
295 | * **create_user**: Creates a new user in a Cloud SQL instance.
296 | * **wait_for_operation**: Waits for a Cloud SQL operation to complete.
297 | 
298 | {{< notice note >}}
299 | Prebuilt tools are pre-1.0, so expect some tool changes between versions. LLMs
300 | will adapt to the tools available, so this shouldn't affect most users.
301 | {{< /notice >}}
302 | 
```

--------------------------------------------------------------------------------
/docs/en/resources/authServices/_index.md:
--------------------------------------------------------------------------------

```markdown
  1 | ---
  2 | title: "AuthServices"
  3 | type: docs
  4 | weight: 1
  5 | description: >
  6 |   AuthServices represent services that handle authentication and authorization.
  7 | ---
  8 | 
  9 | AuthServices represent services that handle authentication and authorization. It
 10 | can primarily be used by [Tools](../tools/) in two different ways:
 11 | 
 12 | - [**Authorized Invocation**][auth-invoke] is when a tool
 13 |   is validated by the auth service before the call can be invoked. Toolbox
 14 |   will reject any calls that fail to validate or have an invalid token.
 15 | - [**Authenticated Parameters**][auth-params] replace the value of a parameter
 16 |   with a field from an [OIDC][openid-claims] claim. Toolbox will automatically
 17 |   resolve the ID token provided by the client and replace the parameter in the
 18 |   tool call.
 19 | 
 20 | [openid-claims]: https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
 21 | [auth-invoke]: ../tools/#authorized-invocations
 22 | [auth-params]: ../tools/#authenticated-parameters
 23 | 
 24 | ## Example
 25 | 
 26 | The following configurations are placed at the top level of a `tools.yaml` file.
 27 | 
 28 | {{< notice tip >}}
 29 | If you are accessing Toolbox with multiple applications, each
 30 |  application should register their own Client ID even if they use the same
 31 |  "kind" of auth provider.
 32 | {{< /notice >}}
 33 | 
 34 | ```yaml
 35 | authServices:
 36 |   my_auth_app_1:
 37 |     kind: google
 38 |     clientId: ${YOUR_CLIENT_ID_1}
 39 |   my_auth_app_2:
 40 |     kind: google
 41 |     clientId: ${YOUR_CLIENT_ID_2}
 42 | ```
 43 | 
 44 | {{< notice tip >}}
 45 | Use environment variable replacement with the format ${ENV_NAME}
 46 | instead of hardcoding your secrets into the configuration file.
 47 | {{< /notice >}}
 48 | 
 49 | After you've configured an `authService` you'll, need to reference it in the
 50 | configuration for each tool that should use it:
 51 | 
 52 | - **Authorized Invocations** for authorizing a tool call, [use the
 53 |   `authRequired` field in a tool config][auth-invoke]
 54 | - **Authenticated Parameters** for using the value from a OIDC claim, [use the
 55 |   `authServices` field in a parameter config][auth-params]
 56 | 
 57 | ## Specifying ID Tokens from Clients
 58 | 
 59 | After [configuring](#example) your `authServices` section, use a Toolbox SDK to
 60 | add your ID tokens to the header of a Tool invocation request. When specifying a
 61 | token you will provide a function (that returns an id). This function is called
 62 | when the tool is invoked. This allows you to cache and refresh the ID token as
 63 | needed.
 64 | 
 65 | The primary method for providing these getters is via the `auth_token_getters`
 66 | parameter when loading tools, or the `add_auth_token_getter`() /
 67 | `add_auth_token_getters()` methods on a loaded tool object.
 68 | 
 69 | ### Specifying tokens during load
 70 | 
 71 | #### Python
 72 | 
 73 | Use the [Python SDK](https://github.com/googleapis/mcp-toolbox-sdk-python/tree/main).
 74 | 
 75 | {{< tabpane persist=header >}}
 76 | {{< tab header="Core" lang="Python" >}}
 77 | import asyncio
 78 | from toolbox_core import ToolboxClient
 79 | 
 80 | async def get_auth_token():
 81 |     # ... Logic to retrieve ID token (e.g., from local storage, OAuth flow)
 82 |     # This example just returns a placeholder. Replace with your actual token retrieval.
 83 |     return "YOUR_ID_TOKEN" # Placeholder
 84 | 
 85 | async def main():
 86 |     async with ToolboxClient("<http://127.0.0.1:5000>") as toolbox:
 87 |         auth_tool = await toolbox.load_tool(
 88 |             "get_sensitive_data",
 89 |             auth_token_getters={"my_auth_app_1": get_auth_token}
 90 |         )
 91 |         result = await auth_tool(param="value")
 92 |         print(result)
 93 | 
 94 | if **name** == "**main**":
 95 |     asyncio.run(main())
 96 | {{< /tab >}}
 97 | {{< tab header="LangChain" lang="Python" >}}
 98 | import asyncio
 99 | from toolbox_langchain import ToolboxClient
100 | 
101 | async def get_auth_token():
102 |     # ... Logic to retrieve ID token (e.g., from local storage, OAuth flow)
103 |     # This example just returns a placeholder. Replace with your actual token retrieval.
104 |     return "YOUR_ID_TOKEN" # Placeholder
105 | 
106 | async def main():
107 |     toolbox = ToolboxClient("<http://127.0.0.1:5000>")
108 | 
109 |     auth_tool = await toolbox.aload_tool(
110 |         "get_sensitive_data",
111 |         auth_token_getters={"my_auth_app_1": get_auth_token}
112 |     )
113 |     result = await auth_tool.ainvoke({"param": "value"})
114 |     print(result)
115 | 
116 | if **name** == "**main**":
117 |     asyncio.run(main())
118 | {{< /tab >}}
119 | {{< tab header="Llamaindex" lang="Python" >}}
120 | import asyncio
121 | from toolbox_llamaindex import ToolboxClient
122 | 
123 | async def get_auth_token():
124 |     # ... Logic to retrieve ID token (e.g., from local storage, OAuth flow)
125 |     # This example just returns a placeholder. Replace with your actual token retrieval.
126 |     return "YOUR_ID_TOKEN" # Placeholder
127 | 
128 | async def main():
129 |     toolbox = ToolboxClient("<http://127.0.0.1:5000>")
130 | 
131 |     auth_tool = await toolbox.aload_tool(
132 |         "get_sensitive_data",
133 |         auth_token_getters={"my_auth_app_1": get_auth_token}
134 |     )
135 |     # result = await auth_tool.acall(param="value")
136 |     # print(result.content)
137 | 
138 | if **name** == "**main**":
139 |     asyncio.run(main()){{< /tab >}}
140 | {{< /tabpane >}}
141 | 
142 | #### Javascript/Typescript
143 | 
144 | Use the [JS SDK](https://github.com/googleapis/mcp-toolbox-sdk-js/tree/main).
145 | 
146 | ```javascript
147 | import { ToolboxClient } from '@toolbox-sdk/core';
148 | 
149 | async function getAuthToken() {
150 |     // ... Logic to retrieve ID token (e.g., from local storage, OAuth flow)
151 |     // This example just returns a placeholder. Replace with your actual token retrieval.
152 |     return "YOUR_ID_TOKEN" // Placeholder
153 | }
154 | 
155 | const URL = 'http://127.0.0.1:5000';
156 | let client = new ToolboxClient(URL);
157 | const authTool = await client.loadTool("my-tool", {"my_auth_app_1": getAuthToken});
158 | const result = await authTool({param:"value"});
159 | console.log(result);
160 | print(result)
161 | ```
162 | 
163 | #### Go
164 | 
165 | Use the [Go SDK](https://github.com/googleapis/mcp-toolbox-sdk-go/tree/main).
166 | 
167 | ```go
168 | import "github.com/googleapis/mcp-toolbox-sdk-go/core"
169 | import "fmt"
170 | 
171 | func getAuthToken() string {
172 | 	// ... Logic to retrieve ID token (e.g., from local storage, OAuth flow)
173 | 	// This example just returns a placeholder. Replace with your actual token retrieval.
174 | 	return "YOUR_ID_TOKEN" // Placeholder
175 | }
176 | 
177 | func main() {
178 | 	URL := 'http://127.0.0.1:5000'
179 | 	client, err := core.NewToolboxClient(URL)
180 | 	if err != nil {
181 | 		log.Fatalf("Failed to create Toolbox client: %v", err)
182 |   	}
183 | 	dynamicTokenSource := core.NewCustomTokenSource(getAuthToken)
184 | 	authTool, err := client.LoadTool(
185 | 		"my-tool",
186 | 		ctx,
187 | 		core.WithAuthTokenSource("my_auth_app_1", dynamicTokenSource))
188 | 	if err != nil {
189 | 		log.Fatalf("Failed to load tool: %v", err)
190 | 	}
191 | 	inputs := map[string]any{"param": "value"}
192 | 	result, err := authTool.Invoke(ctx, inputs)
193 | 	if err != nil {
194 | 		log.Fatalf("Failed to invoke tool: %v", err)
195 | 	}
196 | 	fmt.Println(result)
197 | }
198 | ```
199 | 
200 | ### Specifying tokens for existing tools
201 | 
202 | #### Python
203 | 
204 | Use the [Python
205 | SDK](https://github.com/googleapis/mcp-toolbox-sdk-python/tree/main).
206 | 
207 | {{< tabpane persist=header >}}
208 | {{< tab header="Core" lang="Python" >}}
209 | tools = await toolbox.load_toolset()
210 | 
211 | # for a single token
212 | 
213 | authorized_tool = tools[0].add_auth_token_getter("my_auth", get_auth_token)
214 | 
215 | # OR, if multiple tokens are needed
216 | 
217 | authorized_tool = tools[0].add_auth_token_getters({
218 |   "my_auth1": get_auth1_token,
219 |   "my_auth2": get_auth2_token,
220 | })
221 | {{< /tab >}}
222 | {{< tab header="LangChain" lang="Python" >}}
223 | tools = toolbox.load_toolset()
224 | 
225 | # for a single token
226 | 
227 | authorized_tool = tools[0].add_auth_token_getter("my_auth", get_auth_token)
228 | 
229 | # OR, if multiple tokens are needed
230 | 
231 | authorized_tool = tools[0].add_auth_token_getters({
232 |   "my_auth1": get_auth1_token,
233 |   "my_auth2": get_auth2_token,
234 | })
235 | {{< /tab >}}
236 | {{< tab header="Llamaindex" lang="Python" >}}
237 | tools = toolbox.load_toolset()
238 | 
239 | # for a single token
240 | 
241 | authorized_tool = tools[0].add_auth_token_getter("my_auth", get_auth_token)
242 | 
243 | # OR, if multiple tokens are needed
244 | 
245 | authorized_tool = tools[0].add_auth_token_getters({
246 |   "my_auth1": get_auth1_token,
247 |   "my_auth2": get_auth2_token,
248 | })
249 | {{< /tab >}}
250 | {{< /tabpane >}}
251 | 
252 | #### Javascript/Typescript
253 | 
254 | Use the [JS SDK](https://github.com/googleapis/mcp-toolbox-sdk-js/tree/main).
255 | 
256 | ```javascript
257 | const URL = 'http://127.0.0.1:5000';
258 | let client = new ToolboxClient(URL);
259 | let tool = await client.loadTool("my-tool")
260 | 
261 | // for a single token
262 | const authorizedTool = tool.addAuthTokenGetter("my_auth", get_auth_token)
263 | 
264 | // OR, if multiple tokens are needed
265 | const multiAuthTool = tool.addAuthTokenGetters({
266 |     "my_auth_1": getAuthToken1,
267 |     "my_auth_2": getAuthToken2,
268 | })
269 | 
270 | ```
271 | 
272 | #### Go
273 | 
274 | Use the [Go SDK](https://github.com/googleapis/mcp-toolbox-sdk-go/tree/main).
275 | 
276 | ```go
277 | import "github.com/googleapis/mcp-toolbox-sdk-go/core"
278 | 
279 | func main() {
280 | 	URL := 'http://127.0.0.1:5000'
281 | 	client, err := core.NewToolboxClient(URL)
282 | 	if err != nil {
283 | 		log.Fatalf("Failed to create Toolbox client: %v", err)
284 | 	}
285 | 	tool, err := client.LoadTool("my-tool", ctx))
286 | 	if err != nil {
287 | 		log.Fatalf("Failed to load tool: %v", err)
288 | 	}
289 | 	dynamicTokenSource1 := core.NewCustomTokenSource(getAuthToken1)
290 | 	dynamicTokenSource2 := core.NewCustomTokenSource(getAuthToken1)
291 | 
292 | 	// For a single token
293 | 	authTool, err := tool.ToolFrom(
294 | 		core.WithAuthTokenSource("my-auth", dynamicTokenSource),
295 | 	)
296 | 
297 | 	// OR, if multiple tokens are needed
298 | 	authTool, err := tool.ToolFrom(
299 | 		core.WithAuthTokenSource("my-auth_1", dynamicTokenSource1),
300 | 		core.WithAuthTokenSource("my-auth_2", dynamicTokenSource2),
301 | 	)
302 | }
303 | ```
304 | 
305 | ## Kinds of Auth Services
306 | 
```

--------------------------------------------------------------------------------
/docs/en/how-to/connect-ide/neo4j_mcp.md:
--------------------------------------------------------------------------------

```markdown
  1 | ---
  2 | title: Neo4j using MCP
  3 | type: docs
  4 | weight: 2
  5 | description: "Connect your IDE to Neo4j using Toolbox."
  6 | ---
  7 | 
  8 | [Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) is
  9 | an open protocol for connecting Large Language Models (LLMs) to data sources
 10 | like Neo4j. This guide covers how to use [MCP Toolbox for Databases][toolbox] to
 11 | expose your developer assistant tools to a Neo4j instance:
 12 | 
 13 | * [Cursor][cursor]
 14 | * [Windsurf][windsurf] (Codium)
 15 | * [Visual Studio Code][vscode] (Copilot)
 16 | * [Cline][cline] (VS Code extension)
 17 | * [Claude desktop][claudedesktop]
 18 | * [Claude code][claudecode]
 19 | * [Gemini CLI][geminicli]
 20 | * [Gemini Code Assist][geminicodeassist]
 21 | 
 22 | [toolbox]: https://github.com/googleapis/genai-toolbox
 23 | [cursor]: #configure-your-mcp-client
 24 | [windsurf]: #configure-your-mcp-client
 25 | [vscode]: #configure-your-mcp-client
 26 | [cline]: #configure-your-mcp-client
 27 | [claudedesktop]: #configure-your-mcp-client
 28 | [claudecode]: #configure-your-mcp-client
 29 | [geminicli]: #configure-your-mcp-client
 30 | [geminicodeassist]: #configure-your-mcp-client
 31 | 
 32 | ## Set up the database
 33 | 
 34 | 1.  [Create or select a Neo4j
 35 |     instance.](https://neo4j.com/cloud/platform/aura-graph-database/)
 36 | 
 37 | ## Install MCP Toolbox
 38 | 
 39 | 1. Download the latest version of Toolbox as a binary. Select the [correct
 40 |    binary](https://github.com/googleapis/genai-toolbox/releases) corresponding
 41 |    to your OS and CPU architecture. You are required to use Toolbox version
 42 |    v0.15.0+:
 43 | 
 44 |    <!-- {x-release-please-start-version} -->
 45 |    {{< tabpane persist=header >}}
 46 | {{< tab header="linux/amd64" lang="bash" >}}
 47 | curl -O https://storage.googleapis.com/genai-toolbox/v0.18.0/linux/amd64/toolbox
 48 | {{< /tab >}}
 49 | 
 50 | {{< tab header="darwin/arm64" lang="bash" >}}
 51 | curl -O https://storage.googleapis.com/genai-toolbox/v0.18.0/darwin/arm64/toolbox
 52 | {{< /tab >}}
 53 | 
 54 | {{< tab header="darwin/amd64" lang="bash" >}}
 55 | curl -O https://storage.googleapis.com/genai-toolbox/v0.18.0/darwin/amd64/toolbox
 56 | {{< /tab >}}
 57 | 
 58 | {{< tab header="windows/amd64" lang="bash" >}}
 59 | curl -O https://storage.googleapis.com/genai-toolbox/v0.18.0/windows/amd64/toolbox.exe
 60 | {{< /tab >}}
 61 | {{< /tabpane >}}
 62 |     <!-- {x-release-please-end} -->
 63 | 
 64 | 1. Make the binary executable:
 65 | 
 66 |     ```bash
 67 |     chmod +x toolbox
 68 |     ```
 69 | 
 70 | 1. Verify the installation:
 71 | 
 72 |     ```bash
 73 |     ./toolbox --version
 74 |     ```
 75 | 
 76 | ## Configure your MCP Client
 77 | 
 78 | {{< tabpane text=true >}}
 79 | {{% tab header="Claude code" lang="en" %}}
 80 | 
 81 | 1.  Install [Claude
 82 |     Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview). 
 83 | 1.  Create a `.mcp.json` file in your project root if it doesn't exist.
 84 | 1.  Add the following configuration, replace the environment variables with your
 85 |     values, and save: 
 86 | 
 87 |     ```json
 88 |     {
 89 |       "mcpServers": {
 90 |         "neo4j": {
 91 |           "command": "./PATH/TO/toolbox",
 92 |           "args": ["--prebuilt","neo4j","--stdio"],
 93 |           "env": {
 94 |             "NEO4J_URI": "",
 95 |             "NEO4J_DATABASE": "",
 96 |             "NEO4J_USERNAME": "",
 97 |             "NEO4J_PASSWORD": ""
 98 |           }
 99 |         }
100 |       }
101 |     }
102 |     ```
103 | 
104 | 1.  Restart Claude code to apply the new configuration.
105 | {{% /tab %}}
106 | {{% tab header="Claude desktop" lang="en" %}}
107 | 
108 | 1.  Open [Claude desktop](https://claude.ai/download) and navigate to Settings.
109 | 1.  Under the Developer tab, tap Edit Config to open the configuration file.
110 | 1.  Add the following configuration, replace the environment variables with your
111 |     values, and save: 
112 | 
113 |     ```json
114 |     {
115 |       "mcpServers": {
116 |         "neo4j": {
117 |           "command": "./PATH/TO/toolbox",
118 |           "args": ["--prebuilt","neo4j","--stdio"],
119 |           "env": {
120 |             "NEO4J_URI": "",
121 |             "NEO4J_DATABASE": "",
122 |             "NEO4J_USERNAME": "",
123 |             "NEO4J_PASSWORD": ""
124 |           }
125 |         }
126 |       }
127 |     }
128 |     ```
129 | 
130 | 1.  Restart Claude desktop.
131 | 1.  From the new chat screen, you should see a hammer (MCP) icon appear with the
132 |     new MCP server available. 
133 | {{% /tab %}}
134 | {{% tab header="Cline" lang="en" %}}
135 | 
136 | 1.  Open the [Cline](https://github.com/cline/cline) extension in VS Code and
137 |     tap the **MCP Servers** icon. 
138 | 1.  Tap Configure MCP Servers to open the configuration file.
139 | 1.  Add the following configuration, replace the environment variables with your
140 |     values, and save: 
141 | 
142 |     ```json
143 |     {
144 |       "mcpServers": {
145 |         "neo4j": {
146 |           "command": "./PATH/TO/toolbox",
147 |           "args": ["--prebuilt","neo4j","--stdio"],
148 |           "env": {
149 |             "NEO4J_URI": "",
150 |             "NEO4J_DATABASE": "",
151 |             "NEO4J_USERNAME": "",
152 |             "NEO4J_PASSWORD": ""
153 |           }
154 |         }
155 |       }
156 |     }
157 |     ```
158 | 
159 | 1.  You should see a green active status after the server is successfully connected.
160 | {{% /tab %}}
161 | {{% tab header="Cursor" lang="en" %}}
162 | 
163 | 1.  Create a `.cursor` directory in your project root if it doesn't exist.
164 | 1.  Create a `.cursor/mcp.json` file if it doesn't exist and open it.
165 | 1.  Add the following configuration, replace the environment variables with your values, and save:
166 | 
167 |     ```json
168 |     {
169 |       "mcpServers": {
170 |         "neo4j": {
171 |           "command": "./PATH/TO/toolbox",
172 |           "args": ["--prebuilt","neo4j","--stdio"],
173 |           "env": {
174 |             "NEO4J_URI": "",
175 |             "NEO4J_DATABASE": "",
176 |             "NEO4J_USERNAME": "",
177 |             "NEO4J_PASSWORD": ""
178 |           }
179 |         }
180 |       }
181 |     }
182 |     ```
183 | 
184 | 1.  Open [Cursor](https://www.cursor.com/) and navigate to **Settings > Cursor
185 |     Settings > MCP**. You should see a green active status after the server is
186 |     successfully connected.
187 | {{% /tab %}}
188 | {{% tab header="Visual Studio Code (Copilot)" lang="en" %}}
189 | 
190 | 1.  Open [VS Code](https://code.visualstudio.com/docs/copilot/overview) and
191 |     create a `.vscode` directory in your project root if it doesn't exist.
192 | 1.  Create a `.vscode/mcp.json` file if it doesn't exist and open it.
193 | 1.  Add the following configuration, replace the environment variables with your
194 |     values, and save:
195 | 
196 |     ```json
197 |     {
198 |     "mcp" : {
199 |         "servers": {
200 |         "neo4j": {
201 |             "command": "./PATH/TO/toolbox",
202 |             "args": ["--prebuilt","neo4j","--stdio"],
203 |             "env": {
204 |               "NEO4J_URI": "",
205 |               "NEO4J_DATABASE": "",
206 |               "NEO4J_USERNAME": "",
207 |               "NEO4J_PASSWORD": ""
208 |             }
209 |          }
210 |         }
211 |       }
212 |     }
213 |     ```
214 | {{% /tab %}}
215 | {{% tab header="Windsurf" lang="en" %}}
216 | 
217 | 1.  Open [Windsurf](https://docs.codeium.com/windsurf) and navigate to the
218 |     Cascade assistant.
219 | 1.  Tap on the hammer (MCP) icon, then Configure to open the configuration file.
220 | 1.  Add the following configuration, replace the environment variables with your
221 |     values, and save:
222 | 
223 |     ```json
224 |     {
225 |       "mcpServers": {
226 |         "neo4j": {
227 |           "command": "./PATH/TO/toolbox",
228 |           "args": ["--prebuilt","neo4j","--stdio"],
229 |           "env": {
230 |             "NEO4J_URI": "",
231 |             "NEO4J_DATABASE": "",
232 |             "NEO4J_USERNAME": "",
233 |             "NEO4J_PASSWORD": ""
234 |           }
235 |         }
236 |       }
237 |     }
238 |     ```
239 | {{% /tab %}}
240 | {{% tab header="Gemini CLI" lang="en" %}}
241 | 
242 | 1.  Install the [Gemini
243 |     CLI](https://github.com/google-gemini/gemini-cli?tab=readme-ov-file#quickstart).
244 | 1.  In your working directory, create a folder named `.gemini`. Within it,
245 |     create a `settings.json` file.
246 | 1.  Add the following configuration, replace the environment variables with your
247 |     values, and then save:
248 | 
249 |     ```json
250 |     {
251 |       "mcpServers": {
252 |         "neo4j": {
253 |           "command": "./PATH/TO/toolbox",
254 |           "args": ["--prebuilt","neo4j","--stdio"],
255 |           "env": {
256 |             "NEO4J_URI": "",
257 |             "NEO4J_DATABASE": "",
258 |             "NEO4J_USERNAME": "",
259 |             "NEO4J_PASSWORD": ""
260 |           }
261 |         }
262 |       }
263 |     }
264 |     ```
265 | {{% /tab %}}
266 | {{% tab header="Gemini Code Assist" lang="en" %}}
267 | 
268 | 1.  Install the [Gemini Code
269 |     Assist](https://marketplace.visualstudio.com/items?itemName=Google.geminicodeassist)
270 |     extension in Visual Studio Code.
271 | 1.  Enable Agent Mode in Gemini Code Assist chat.
272 | 1.  In your working directory, create a folder named `.gemini`. Within it,
273 |     create a `settings.json` file.
274 | 1.  Add the following configuration, replace the environment variables with your
275 |     values, and then save:
276 | 
277 |     ```json
278 |     {
279 |       "mcpServers": {
280 |         "neo4j": {
281 |           "command": "./PATH/TO/toolbox",
282 |           "args": ["--prebuilt","neo4j","--stdio"],
283 |           "env": {
284 |             "NEO4J_URI": "",
285 |             "NEO4J_DATABASE": "",
286 |             "NEO4J_USERNAME": "",
287 |             "NEO4J_PASSWORD": ""
288 |           }
289 |         }
290 |       }
291 |     }
292 |     ```
293 | {{% /tab %}}
294 | {{< /tabpane >}}
295 | 
296 | ## Use Tools
297 | 
298 | Your AI tool is now connected to Neo4j using MCP. Try asking your AI assistant
299 | to get the graph schema or execute Cypher statements.
300 | 
301 | The following tools are available to the LLM:
302 | 
303 | 1.  **get_schema**: extracts the complete database schema, including details
304 |     about node labels, relationships, properties, constraints, and indexes.
305 | 1.  **execute_cypher**: executes any arbitrary Cypher statement.
306 | 
307 | {{< notice note >}}
308 | Prebuilt tools are pre-1.0, so expect some tool changes between versions. LLMs
309 | will adapt to the tools available, so this shouldn't affect most users.
310 | {{< /notice >}}
311 | 
```

--------------------------------------------------------------------------------
/docs/en/how-to/connect-ide/mysql_mcp.md:
--------------------------------------------------------------------------------

```markdown
  1 | ---
  2 | title: MySQL using MCP
  3 | type: docs
  4 | weight: 2
  5 | description: "Connect your IDE to MySQL using Toolbox."
  6 | ---
  7 | 
  8 | [Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) is
  9 | an open protocol for connecting Large Language Models (LLMs) to data sources
 10 | like MySQL. This guide covers how to use [MCP Toolbox for Databases][toolbox] to
 11 | expose your developer assistant tools to a MySQL instance:
 12 | 
 13 | * [Cursor][cursor]
 14 | * [Windsurf][windsurf] (Codium)
 15 | * [Visual Studio Code][vscode] (Copilot)
 16 | * [Cline][cline] (VS Code extension)
 17 | * [Claude desktop][claudedesktop]
 18 | * [Claude code][claudecode]
 19 | * [Gemini CLI][geminicli]
 20 | * [Gemini Code Assist][geminicodeassist]
 21 | 
 22 | [toolbox]: https://github.com/googleapis/genai-toolbox
 23 | [cursor]: #configure-your-mcp-client
 24 | [windsurf]: #configure-your-mcp-client
 25 | [vscode]: #configure-your-mcp-client
 26 | [cline]: #configure-your-mcp-client
 27 | [claudedesktop]: #configure-your-mcp-client
 28 | [claudecode]: #configure-your-mcp-client
 29 | [geminicli]: #configure-your-mcp-client
 30 | [geminicodeassist]: #configure-your-mcp-client
 31 | 
 32 | ## Set up the database
 33 | 
 34 | 1.  [Create or select a MySQL instance.](https://dev.mysql.com/downloads/installer/)
 35 | 
 36 | ## Install MCP Toolbox
 37 | 
 38 | 1. Download the latest version of Toolbox as a binary. Select the [correct
 39 |    binary](https://github.com/googleapis/genai-toolbox/releases) corresponding
 40 |    to your OS and CPU architecture. You are required to use Toolbox version
 41 |    V0.10.0+:
 42 | 
 43 |    <!-- {x-release-please-start-version} -->
 44 |    {{< tabpane persist=header >}}
 45 | {{< tab header="linux/amd64" lang="bash" >}}
 46 | curl -O https://storage.googleapis.com/genai-toolbox/v0.18.0/linux/amd64/toolbox
 47 | {{< /tab >}}
 48 | 
 49 | {{< tab header="darwin/arm64" lang="bash" >}}
 50 | curl -O https://storage.googleapis.com/genai-toolbox/v0.18.0/darwin/arm64/toolbox
 51 | {{< /tab >}}
 52 | 
 53 | {{< tab header="darwin/amd64" lang="bash" >}}
 54 | curl -O https://storage.googleapis.com/genai-toolbox/v0.18.0/darwin/amd64/toolbox
 55 | {{< /tab >}}
 56 | 
 57 | {{< tab header="windows/amd64" lang="bash" >}}
 58 | curl -O https://storage.googleapis.com/genai-toolbox/v0.18.0/windows/amd64/toolbox.exe
 59 | {{< /tab >}}
 60 | {{< /tabpane >}}
 61 |     <!-- {x-release-please-end} -->
 62 | 
 63 | 1. Make the binary executable:
 64 | 
 65 |     ```bash
 66 |     chmod +x toolbox
 67 |     ```
 68 | 
 69 | 1. Verify the installation:
 70 | 
 71 |     ```bash
 72 |     ./toolbox --version
 73 |     ```
 74 | 
 75 | ## Configure your MCP Client
 76 | 
 77 | {{< tabpane text=true >}}
 78 | {{% tab header="Claude code" lang="en" %}}
 79 | 
 80 | 1.  Install [Claude
 81 |     Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview).
 82 | 1.  Create a `.mcp.json` file in your project root if it doesn't exist.
 83 | 1.  Add the following configuration, replace the environment variables with your
 84 |     values, and save:
 85 | 
 86 |     ```json
 87 |     {
 88 |       "mcpServers": {
 89 |         "mysql": {
 90 |           "command": "./PATH/TO/toolbox",
 91 |           "args": ["--prebuilt", "mysql", "--stdio"],
 92 |           "env": {
 93 |             "MYSQL_HOST": "",
 94 |             "MYSQL_PORT": "",
 95 |             "MYSQL_DATABASE": "",
 96 |             "MYSQL_USER": "",
 97 |             "MYSQL_PASSWORD": ""
 98 |           }
 99 |         }
100 |       }
101 |     }
102 |     ```
103 | 
104 | 1.  Restart Claude code to apply the new configuration.
105 | {{% /tab %}}
106 | {{% tab header="Claude desktop" lang="en" %}}
107 | 
108 | 1.  Open [Claude desktop](https://claude.ai/download) and navigate to Settings.
109 | 1.  Under the Developer tab, tap Edit Config to open the configuration file.
110 | 1.  Add the following configuration, replace the environment variables with your
111 |     values, and save:
112 | 
113 |     ```json
114 |     {
115 |       "mcpServers": {
116 |         "mysql": {
117 |           "command": "./PATH/TO/toolbox",
118 |           "args": ["--prebuilt", "mysql", "--stdio"],
119 |           "env": {
120 |             "MYSQL_HOST": "",
121 |             "MYSQL_PORT": "",
122 |             "MYSQL_DATABASE": "",
123 |             "MYSQL_USER": "",
124 |             "MYSQL_PASSWORD": ""
125 |           }
126 |         }
127 |       }
128 |     }
129 |     ```
130 | 
131 | 1.  Restart Claude desktop.
132 | 1.  From the new chat screen, you should see a hammer (MCP) icon appear with the
133 |     new MCP server available.
134 | {{% /tab %}}
135 | {{% tab header="Cline" lang="en" %}}
136 | 
137 | 1.  Open the [Cline](https://github.com/cline/cline) extension in VS Code and
138 |     tap the **MCP Servers** icon.
139 | 1.  Tap Configure MCP Servers to open the configuration file.
140 | 1.  Add the following configuration, replace the environment variables with your
141 |     values, and save:
142 | 
143 |     ```json
144 |     {
145 |       "mcpServers": {
146 |         "mysql": {
147 |           "command": "./PATH/TO/toolbox",
148 |           "args": ["--prebuilt", "mysql", "--stdio"],
149 |           "env": {
150 |             "MYSQL_HOST": "",
151 |             "MYSQL_PORT": "",
152 |             "MYSQL_DATABASE": "",
153 |             "MYSQL_USER": "",
154 |             "MYSQL_PASSWORD": ""
155 |           }
156 |         }
157 |       }
158 |     }
159 |     ```
160 | 
161 | 1.  You should see a green active status after the server is successfully
162 |     connected.
163 | {{% /tab %}}
164 | {{% tab header="Cursor" lang="en" %}}
165 | 
166 | 1.  Create a `.cursor` directory in your project root if it doesn't exist.
167 | 1.  Create a `.cursor/mcp.json` file if it doesn't exist and open it.
168 | 1.  Add the following configuration, replace the environment variables with your
169 |     values, and save:
170 | 
171 |     ```json
172 |     {
173 |       "mcpServers": {
174 |         "mysql": {
175 |           "command": "./PATH/TO/toolbox",
176 |           "args": ["--prebuilt", "mysql", "--stdio"],
177 |           "env": {
178 |             "MYSQL_HOST": "",
179 |             "MYSQL_PORT": "",
180 |             "MYSQL_DATABASE": "",
181 |             "MYSQL_USER": "",
182 |             "MYSQL_PASSWORD": ""
183 |           }
184 |         }
185 |       }
186 |     }
187 |     ```
188 | 
189 | 1.  Open [Cursor](https://www.cursor.com/) and navigate to **Settings > Cursor
190 |     Settings > MCP**. You should see a green active status after the server is
191 |     successfully connected.
192 | {{% /tab %}}
193 | {{% tab header="Visual Studio Code (Copilot)" lang="en" %}}
194 | 
195 | 1.  Open [VS Code](https://code.visualstudio.com/docs/copilot/overview) and
196 |     create a `.vscode` directory in your project root if it doesn't exist.
197 | 1.  Create a `.vscode/mcp.json` file if it doesn't exist and open it.
198 | 1.  Add the following configuration, replace the environment variables with your
199 |     values, and save:
200 | 
201 |     ```json
202 |     {
203 |       "servers": {
204 |         "mysql": {
205 |           "command": "./PATH/TO/toolbox",
206 |           "args": ["--prebuilt","mysql","--stdio"],
207 |           "env": {
208 |             "MYSQL_HOST": "",
209 |             "MYSQL_PORT": "",
210 |             "MYSQL_DATABASE": "",
211 |             "MYSQL_USER": "",
212 |             "MYSQL_PASSWORD": ""
213 |           }
214 |         }
215 |       }
216 |     }
217 |     ```
218 | {{% /tab %}}
219 | {{% tab header="Windsurf" lang="en" %}}
220 | 
221 | 1.  Open [Windsurf](https://docs.codeium.com/windsurf) and navigate to the
222 |     Cascade assistant.
223 | 1.  Tap on the hammer (MCP) icon, then Configure to open the configuration file.
224 | 1.  Add the following configuration, replace the environment variables with your
225 |     values, and save:
226 | 
227 |     ```json
228 |     {
229 |       "mcpServers": {
230 |         "mysql": {
231 |           "command": "./PATH/TO/toolbox",
232 |           "args": ["--prebuilt","mysql","--stdio"],
233 |           "env": {
234 |             "MYSQL_HOST": "",
235 |             "MYSQL_PORT": "",
236 |             "MYSQL_DATABASE": "",
237 |             "MYSQL_USER": "",
238 |             "MYSQL_PASSWORD": ""
239 |           }
240 |         }
241 |       }
242 |     }
243 |     ```
244 | {{% /tab %}}
245 | {{% tab header="Gemini CLI" lang="en" %}}
246 | 
247 | 1.  Install the [Gemini
248 |     CLI](https://github.com/google-gemini/gemini-cli?tab=readme-ov-file#quickstart).
249 | 1.  In your working directory, create a folder named `.gemini`. Within it,
250 |     create a `settings.json` file.
251 | 1.  Add the following configuration, replace the environment variables with your
252 |     values, and then save:
253 | 
254 |     ```json
255 |     {
256 |       "mcpServers": {
257 |         "mysql": {
258 |           "command": "./PATH/TO/toolbox",
259 |           "args": ["--prebuilt","mysql","--stdio"],
260 |           "env": {
261 |             "MYSQL_HOST": "",
262 |             "MYSQL_PORT": "",
263 |             "MYSQL_DATABASE": "",
264 |             "MYSQL_USER": "",
265 |             "MYSQL_PASSWORD": ""
266 |           }
267 |         }
268 |       }
269 |     }
270 |     ```
271 | {{% /tab %}}
272 | {{% tab header="Gemini Code Assist" lang="en" %}}
273 | 
274 | 1.  Install the [Gemini Code
275 |     Assist](https://marketplace.visualstudio.com/items?itemName=Google.geminicodeassist)
276 |     extension in Visual Studio Code.
277 | 1.  Enable Agent Mode in Gemini Code Assist chat.
278 | 1.  In your working directory, create a folder named `.gemini`. Within it,
279 |     create a `settings.json` file.
280 | 1.  Add the following configuration, replace the environment variables with your
281 |     values, and then save:
282 | 
283 |     ```json
284 |     {
285 |       "mcpServers": {
286 |         "mysql": {
287 |           "command": "./PATH/TO/toolbox",
288 |           "args": ["--prebuilt","mysql","--stdio"],
289 |           "env": {
290 |             "MYSQL_HOST": "",
291 |             "MYSQL_PORT": "",
292 |             "MYSQL_DATABASE": "",
293 |             "MYSQL_USER": "",
294 |             "MYSQL_PASSWORD": ""
295 |           }
296 |         }
297 |       }
298 |     }
299 |     ```
300 | {{% /tab %}}
301 | {{< /tabpane >}}
302 | 
303 | ## Use Tools
304 | 
305 | Your AI tool is now connected to MySQL using MCP. Try asking your AI assistant
306 | to list tables, create a table, or define and execute other SQL statements.
307 | 
308 | The following tools are available to the LLM:
309 | 
310 | 1.  **list_tables**: lists tables and descriptions
311 | 1.  **execute_sql**: execute any SQL statement
312 | 
313 | {{< notice note >}}
314 | Prebuilt tools are pre-1.0, so expect some tool changes between versions. LLMs
315 | will adapt to the tools available, so this shouldn't affect most users.
316 | {{< /notice >}}
317 | 
```

--------------------------------------------------------------------------------
/docs/en/how-to/connect-ide/mssql_mcp.md:
--------------------------------------------------------------------------------

```markdown
  1 | ---
  2 | title: SQL Server using MCP
  3 | type: docs
  4 | weight: 2
  5 | description: "Connect your IDE to SQL Server using Toolbox."
  6 | ---
  7 | 
  8 | [Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) is
  9 | an open protocol for connecting Large Language Models (LLMs) to data sources
 10 | like SQL Server. This guide covers how to use [MCP Toolbox for
 11 | Databases][toolbox] to expose your developer assistant tools to a SQL Server
 12 | instance:
 13 | 
 14 | * [Cursor][cursor]
 15 | * [Windsurf][windsurf] (Codium)
 16 | * [Visual Studio Code][vscode] (Copilot)
 17 | * [Cline][cline] (VS Code extension)
 18 | * [Claude desktop][claudedesktop]
 19 | * [Claude code][claudecode]
 20 | * [Gemini CLI][geminicli]
 21 | * [Gemini Code Assist][geminicodeassist]
 22 | 
 23 | [toolbox]: https://github.com/googleapis/genai-toolbox
 24 | [cursor]: #configure-your-mcp-client
 25 | [windsurf]: #configure-your-mcp-client
 26 | [vscode]: #configure-your-mcp-client
 27 | [cline]: #configure-your-mcp-client
 28 | [claudedesktop]: #configure-your-mcp-client
 29 | [claudecode]: #configure-your-mcp-client
 30 | [geminicli]: #configure-your-mcp-client
 31 | [geminicodeassist]: #configure-your-mcp-client
 32 | 
 33 | ## Set up the database
 34 | 
 35 | 1.  [Create or select a SQL Server
 36 |     instance.](https://www.microsoft.com/en-us/sql-server/sql-server-downloads)
 37 | 
 38 | ## Install MCP Toolbox
 39 | 
 40 | 1. Download the latest version of Toolbox as a binary. Select the [correct
 41 |    binary](https://github.com/googleapis/genai-toolbox/releases) corresponding
 42 |    to your OS and CPU architecture. You are required to use Toolbox version
 43 |    V0.10.0+:
 44 | 
 45 |    <!-- {x-release-please-start-version} -->
 46 |    {{< tabpane persist=header >}}
 47 | {{< tab header="linux/amd64" lang="bash" >}}
 48 | curl -O https://storage.googleapis.com/genai-toolbox/v0.18.0/linux/amd64/toolbox
 49 | {{< /tab >}}
 50 | 
 51 | {{< tab header="darwin/arm64" lang="bash" >}}
 52 | curl -O https://storage.googleapis.com/genai-toolbox/v0.18.0/darwin/arm64/toolbox
 53 | {{< /tab >}}
 54 | 
 55 | {{< tab header="darwin/amd64" lang="bash" >}}
 56 | curl -O https://storage.googleapis.com/genai-toolbox/v0.18.0/darwin/amd64/toolbox
 57 | {{< /tab >}}
 58 | 
 59 | {{< tab header="windows/amd64" lang="bash" >}}
 60 | curl -O https://storage.googleapis.com/genai-toolbox/v0.18.0/windows/amd64/toolbox.exe
 61 | {{< /tab >}}
 62 | {{< /tabpane >}}
 63 |     <!-- {x-release-please-end} -->
 64 | 
 65 | 1. Make the binary executable:
 66 | 
 67 |     ```bash
 68 |     chmod +x toolbox
 69 |     ```
 70 | 
 71 | 1. Verify the installation:
 72 | 
 73 |     ```bash
 74 |     ./toolbox --version
 75 |     ```
 76 | 
 77 | ## Configure your MCP Client
 78 | 
 79 | {{< tabpane text=true >}}
 80 | {{% tab header="Claude code" lang="en" %}}
 81 | 
 82 | 1.  Install [Claude
 83 |     Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview).
 84 | 1.  Create a `.mcp.json` file in your project root if it doesn't exist.
 85 | 1.  Add the following configuration, replace the environment variables with your
 86 |     values, and save:
 87 | 
 88 |     ```json
 89 |     {
 90 |       "mcpServers": {
 91 |         "sqlserver": {
 92 |           "command": "./PATH/TO/toolbox",
 93 |           "args": ["--prebuilt","mssql","--stdio"],
 94 |           "env": {
 95 |             "MSSQL_HOST": "",
 96 |             "MSSQL_PORT": "",
 97 |             "MSSQL_DATABASE": "",
 98 |             "MSSQL_USER": "",
 99 |             "MSSQL_PASSWORD": ""
100 |           }
101 |         }
102 |       }
103 |     }
104 |     ```
105 | 
106 | 1.  Restart Claude code to apply the new configuration.
107 | {{% /tab %}}
108 | {{% tab header="Claude desktop" lang="en" %}}
109 | 
110 | 1.  Open [Claude desktop](https://claude.ai/download) and navigate to Settings.
111 | 1.  Under the Developer tab, tap Edit Config to open the configuration file.
112 | 1.  Add the following configuration, replace the environment variables with your
113 |     values, and save:
114 | 
115 |     ```json
116 |     {
117 |       "mcpServers": {
118 |         "sqlserver": {
119 |           "command": "./PATH/TO/toolbox",
120 |           "args": ["--prebuilt","mssql","--stdio"],
121 |           "env": {
122 |             "MSSQL_HOST": "",
123 |             "MSSQL_PORT": "",
124 |             "MSSQL_DATABASE": "",
125 |             "MSSQL_USER": "",
126 |             "MSSQL_PASSWORD": ""
127 |           }
128 |         }
129 |       }
130 |     }
131 |     ```
132 | 
133 | 1.  Restart Claude desktop.
134 | 1.  From the new chat screen, you should see a hammer (MCP) icon appear with the
135 |     new MCP server available.
136 | {{% /tab %}}
137 | {{% tab header="Cline" lang="en" %}}
138 | 
139 | 1.  Open the [Cline](https://github.com/cline/cline) extension in VS Code and
140 |     tap the **MCP Servers** icon.
141 | 1.  Tap Configure MCP Servers to open the configuration file.
142 | 1.  Add the following configuration, replace the environment variables with your
143 |     values, and save:
144 | 
145 |     ```json
146 |     {
147 |       "mcpServers": {
148 |         "sqlserver": {
149 |           "command": "./PATH/TO/toolbox",
150 |           "args": ["--prebuilt","mssql","--stdio"],
151 |           "env": {
152 |             "MSSQL_HOST": "",
153 |             "MSSQL_PORT": "",
154 |             "MSSQL_DATABASE": "",
155 |             "MSSQL_USER": "",
156 |             "MSSQL_PASSWORD": ""
157 |           }
158 |         }
159 |       }
160 |     }
161 |     ```
162 | 
163 | 1.  You should see a green active status after the server is successfully
164 |     connected.
165 | {{% /tab %}}
166 | {{% tab header="Cursor" lang="en" %}}
167 | 
168 | 1.  Create a `.cursor` directory in your project root if it doesn't exist.
169 | 1.  Create a `.cursor/mcp.json` file if it doesn't exist and open it.
170 | 1.  Add the following configuration, replace the environment variables with your
171 |     values, and save:
172 | 
173 |     ```json
174 |     {
175 |       "mcpServers": {
176 |         "sqlserver": {
177 |           "command": "./PATH/TO/toolbox",
178 |           "args": ["--prebuilt","mssql","--stdio"],
179 |           "env": {
180 |             "MSSQL_HOST": "",
181 |             "MSSQL_PORT": "",
182 |             "MSSQL_DATABASE": "",
183 |             "MSSQL_USER": "",
184 |             "MSSQL_PASSWORD": ""
185 |           }
186 |         }
187 |       }
188 |     }
189 |     ```
190 | 
191 | 1.  Open [Cursor](https://www.cursor.com/) and navigate to **Settings > Cursor
192 |     Settings > MCP**. You should see a green active status after the server is
193 |     successfully connected.
194 | {{% /tab %}}
195 | {{% tab header="Visual Studio Code (Copilot)" lang="en" %}}
196 | 
197 | 1.  Open [VS Code](https://code.visualstudio.com/docs/copilot/overview) and
198 |     create a `.vscode` directory in your project root if it doesn't exist.
199 | 1.  Create a `.vscode/mcp.json` file if it doesn't exist and open it.
200 | 1.  Add the following configuration, replace the environment variables with your
201 |     values, and save:
202 | 
203 |     ```json
204 |     {
205 |       "servers": {
206 |         "mssql": {
207 |           "command": "./PATH/TO/toolbox",
208 |           "args": ["--prebuilt","mssql","--stdio"],
209 |           "env": {
210 |             "MSSQL_HOST": "",
211 |             "MSSQL_PORT": "",
212 |             "MSSQL_DATABASE": "",
213 |             "MSSQL_USER": "",
214 |             "MSSQL_PASSWORD": ""
215 |           }
216 |         }
217 |       }
218 |     }
219 |     ```
220 | {{% /tab %}}
221 | {{% tab header="Windsurf" lang="en" %}}
222 | 
223 | 1.  Open [Windsurf](https://docs.codeium.com/windsurf) and navigate to the
224 |     Cascade assistant.
225 | 1.  Tap on the hammer (MCP) icon, then Configure to open the configuration file.
226 | 1.  Add the following configuration, replace the environment variables with your
227 |     values, and save:
228 | 
229 |     ```json
230 |     {
231 |       "mcpServers": {
232 |         "sqlserver": {
233 |           "command": "./PATH/TO/toolbox",
234 |           "args": ["--prebuilt","mssql","--stdio"],
235 |           "env": {
236 |             "MSSQL_HOST": "",
237 |             "MSSQL_PORT": "",
238 |             "MSSQL_DATABASE": "",
239 |             "MSSQL_USER": "",
240 |             "MSSQL_PASSWORD": ""
241 |           }
242 |         }
243 |       }
244 |     }
245 |     ```
246 | {{% /tab %}}
247 | {{% tab header="Gemini CLI" lang="en" %}}
248 | 
249 | 1.  Install the [Gemini
250 |     CLI](https://github.com/google-gemini/gemini-cli?tab=readme-ov-file#quickstart).
251 | 1.  In your working directory, create a folder named `.gemini`. Within it,
252 |     create a `settings.json` file.
253 | 1.  Add the following configuration, replace the environment variables with your
254 |     values, and then save:
255 | 
256 |     ```json
257 |     {
258 |       "mcpServers": {
259 |         "sqlserver": {
260 |           "command": "./PATH/TO/toolbox",
261 |           "args": ["--prebuilt","mssql","--stdio"],
262 |           "env": {
263 |             "MSSQL_HOST": "",
264 |             "MSSQL_PORT": "",
265 |             "MSSQL_DATABASE": "",
266 |             "MSSQL_USER": "",
267 |             "MSSQL_PASSWORD": ""
268 |           }
269 |         }
270 |       }
271 |     }
272 |     ```
273 | {{% /tab %}}
274 | {{% tab header="Gemini Code Assist" lang="en" %}}
275 | 
276 | 1.  Install the [Gemini Code
277 |     Assist](https://marketplace.visualstudio.com/items?itemName=Google.geminicodeassist)
278 |     extension in Visual Studio Code.
279 | 1.  Enable Agent Mode in Gemini Code Assist chat.
280 | 1.  In your working directory, create a folder named `.gemini`. Within it,
281 |     create a `settings.json` file.
282 | 1.  Add the following configuration, replace the environment variables with your
283 |     values, and then save:
284 | 
285 |     ```json
286 |     {
287 |       "mcpServers": {
288 |         "sqlserver": {
289 |           "command": "./PATH/TO/toolbox",
290 |           "args": ["--prebuilt","mssql","--stdio"],
291 |           "env": {
292 |             "MSSQL_HOST": "",
293 |             "MSSQL_PORT": "",
294 |             "MSSQL_DATABASE": "",
295 |             "MSSQL_USER": "",
296 |             "MSSQL_PASSWORD": ""
297 |           }
298 |         }
299 |       }
300 |     }
301 |     ```
302 | {{% /tab %}}
303 | {{< /tabpane >}}
304 | 
305 | ## Use Tools
306 | 
307 | Your AI tool is now connected to SQL Server using MCP. Try asking your AI
308 | assistant to list tables, create a table, or define and execute other SQL
309 | statements.
310 | 
311 | The following tools are available to the LLM:
312 | 
313 | 1.  **list_tables**: lists tables and descriptions
314 | 1.  **execute_sql**: execute any SQL statement
315 | 
316 | {{< notice note >}}
317 | Prebuilt tools are pre-1.0, so expect some tool changes between versions. LLMs
318 | will adapt to the tools available, so this shouldn't affect most users.
319 | {{< /notice >}}
320 | 
```
Page 25/48FirstPrevNextLast