#
tokens: 49272/50000 49/784 files (page 4/33)
lines: off (toggle) GitHub
raw markdown copy
This is page 4 of 33. Use http://codebase.md/googleapis/genai-toolbox?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-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-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
│       │       ├── 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
├── 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
│   │   │   ├── 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
│   │   │   ├── 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
│   │   ├── 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
├── 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/alloydb/alloydblistinstances/alloydblistinstances_test.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package alloydblistinstances_test

import (
	"testing"

	yaml "github.com/goccy/go-yaml"
	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/genai-toolbox/internal/server"
	"github.com/googleapis/genai-toolbox/internal/testutils"
	alloydblistinstances "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydblistinstances"
)

func TestParseFromYaml(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		want server.ToolConfigs
	}{
		{
			desc: "basic example",
			in: `
			tools:
				list-my-instances:
					kind: alloydb-list-instances
					source: my-alloydb-admin-source
					description: some description
			`,
			want: server.ToolConfigs{
				"list-my-instances": alloydblistinstances.Config{
					Name:         "list-my-instances",
					Kind:         "alloydb-list-instances",
					Source:       "my-alloydb-admin-source",
					Description:  "some description",
					AuthRequired: []string{},
				},
			},
		},
		{
			desc: "with auth required",
			in: `
			tools:
				list-my-instances-auth:
					kind: alloydb-list-instances
					source: my-alloydb-admin-source
					description: some description
					authRequired:
						- my-google-auth-service
						- other-auth-service
			`,
			want: server.ToolConfigs{
				"list-my-instances-auth": alloydblistinstances.Config{
					Name:         "list-my-instances-auth",
					Kind:         "alloydb-list-instances",
					Source:       "my-alloydb-admin-source",
					Description:  "some description",
					AuthRequired: []string{"my-google-auth-service", "other-auth-service"},
				},
			},
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			// Parse contents
			err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err != nil {
				t.Fatalf("unable to unmarshal: %s", err)
			}
			if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
				t.Fatalf("incorrect parse: diff %v", diff)
			}
		})
	}
}

```

--------------------------------------------------------------------------------
/internal/tools/postgres/postgreslistavailableextensions/postgreslistavailableextensions_test.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package postgreslistavailableextensions_test

import (
	"testing"

	yaml "github.com/goccy/go-yaml"
	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/genai-toolbox/internal/server"
	"github.com/googleapis/genai-toolbox/internal/testutils"
	"github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistavailableextensions"
)

func TestParseFromYamlPostgres(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		want server.ToolConfigs
	}{
		{
			desc: "basic example",
			in: `
			tools:
				example_tool:
					kind: postgres-list-available-extensions
					source: my-pg-instance
					description: "some description"
					authRequired:
						- my-google-auth-service
						- other-auth-service
			`,
			want: server.ToolConfigs{
				"example_tool": postgreslistavailableextensions.Config{
					Name:         "example_tool",
					Kind:         "postgres-list-available-extensions",
					Source:       "my-pg-instance",
					Description:  "some description",
					AuthRequired: []string{"my-google-auth-service", "other-auth-service"},
				},
			},
		},
		{
			desc: "basic example without authRequired",
			in: `
			tools:
				example_tool:
					kind: postgres-list-available-extensions
					source: my-pg-instance
					description: "some description"
			`,
			want: server.ToolConfigs{
				"example_tool": postgreslistavailableextensions.Config{
					Name:         "example_tool",
					Kind:         "postgres-list-available-extensions",
					Source:       "my-pg-instance",
					Description:  "some description",
					AuthRequired: []string{},
				},
			},
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			// Parse contents
			err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err != nil {
				t.Fatalf("unable to unmarshal: %s", err)
			}
			if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
				t.Fatalf("incorrect parse: diff %v", diff)
			}
		})
	}

}

```

--------------------------------------------------------------------------------
/internal/tools/postgres/postgreslistinstalledextensions/postgreslistinstalledextensions_test.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package postgreslistinstalledextensions_test

import (
	"testing"

	yaml "github.com/goccy/go-yaml"
	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/genai-toolbox/internal/server"
	"github.com/googleapis/genai-toolbox/internal/testutils"
	"github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistinstalledextensions"
)

func TestParseFromYamlPostgres(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		want server.ToolConfigs
	}{
		{
			desc: "basic example",
			in: `
			tools:
				example_tool:
					kind: postgres-list-installed-extensions
					source: my-pg-instance
					description: "some description"
					authRequired:
						- my-google-auth-service
						- other-auth-service
			`,
			want: server.ToolConfigs{
				"example_tool": postgreslistinstalledextensions.Config{
					Name:         "example_tool",
					Kind:         "postgres-list-installed-extensions",
					Source:       "my-pg-instance",
					Description:  "some description",
					AuthRequired: []string{"my-google-auth-service", "other-auth-service"},
				},
			},
		},
		{
			desc: "basic example without authRequired",
			in: `
			tools:
				example_tool:
					kind: postgres-list-installed-extensions
					source: my-pg-instance
					description: "some description"
			`,
			want: server.ToolConfigs{
				"example_tool": postgreslistinstalledextensions.Config{
					Name:         "example_tool",
					Kind:         "postgres-list-installed-extensions",
					Source:       "my-pg-instance",
					Description:  "some description",
					AuthRequired: []string{},
				},
			},
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			// Parse contents
			err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err != nil {
				t.Fatalf("unable to unmarshal: %s", err)
			}
			if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
				t.Fatalf("incorrect parse: diff %v", diff)
			}
		})
	}

}

```

--------------------------------------------------------------------------------
/docs/en/resources/sources/dgraph.md:
--------------------------------------------------------------------------------

```markdown
---
title: "Dgraph"
type: docs
weight: 1
description: >
 Dgraph is fully open-source, built-for-scale graph database for Gen AI workloads

---

## About

[Dgraph][dgraph-docs] is an open-source graph database. It is designed for
real-time workloads, horizontal scalability, and data flexibility. Implemented
as a distributed system, Dgraph processes queries in parallel to deliver the
fastest result.

This source can connect to either a self-managed Dgraph cluster or one hosted on
Dgraph Cloud. If you're new to Dgraph, the fastest way to get started is to
[sign up for Dgraph Cloud][dgraph-login].

[dgraph-docs]: https://dgraph.io/docs
[dgraph-login]: https://cloud.dgraph.io/login

## Available Tools

- [`dgraph-dql`](../tools/dgraph/dgraph-dql.md)  
  Run DQL (Dgraph Query Language) queries.

## Requirements

### Database User

When **connecting to a hosted Dgraph database**, this source uses the API key
for access. If you are using a dedicated environment, you will additionally need
the namespace and user credentials for that namespace.

For **connecting to a local or self-hosted Dgraph database**, use the namespace
and user credentials for that namespace.

## Example

```yaml
sources:
    my-dgraph-source:
        kind: dgraph
        dgraphUrl: https://xxxx.cloud.dgraph.io
        user: ${USER_NAME}
        password: ${PASSWORD}
        apiKey: ${API_KEY}
        namespace : 0
```

{{< notice tip >}}
Use environment variable replacement with the format ${ENV_NAME}
instead of hardcoding your secrets into the configuration file.
{{< /notice >}}

## Reference

| **Field**   | **Type** | **Required** | **Description**                                                                                  |
|-------------|:--------:|:------------:|--------------------------------------------------------------------------------------------------|
| kind        |  string  |     true     | Must be "dgraph".                                                                                |
| dgraphUrl   |  string  |     true     | Connection URI (e.g. "<https://xxx.cloud.dgraph.io>", "<https://localhost:8080>").               |
| user        |  string  |     false    | Name of the Dgraph user to connect as (e.g., "groot").                                           |
| password    |  string  |     false    | Password of the Dgraph user (e.g., "password").                                                  |
| apiKey      |  string  |     false    | API key to connect to a Dgraph Cloud instance.                                                   |
| namespace   |  uint64  |     false    | Dgraph namespace (not required for Dgraph Cloud Shared Clusters).                                |

```

--------------------------------------------------------------------------------
/internal/prebuiltconfigs/prebuiltconfigs.go:
--------------------------------------------------------------------------------

```go
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package prebuiltconfigs

import (
	"embed"
	"fmt"
	"path"
	"strings"
)

var (
	//go:embed tools/*.yaml
	prebuiltConfigsFS embed.FS

	// Map of sources to their prebuilt tools
	prebuiltToolYAMLs map[string][]byte
	// List of sources with prebuilt tools
	prebuiltToolsSources []string
)

func init() {
	var err error
	prebuiltToolYAMLs, prebuiltToolsSources, err = loadPrebuiltToolYAMLs()
	if err != nil {
		panic(fmt.Sprintf("Unexpected Error: %v\n", err))
	}
}

// Getter for the prebuiltToolsSources
func GetPrebuiltSources() []string {
	return prebuiltToolsSources
}

// Get prebuilt tools for a source
func Get(prebuiltSourceConfig string) ([]byte, error) {
	content, ok := prebuiltToolYAMLs[prebuiltSourceConfig]
	if !ok {
		prebuiltHelpSuffix := "no prebuilt configurations found."
		if len(prebuiltToolsSources) > 0 {
			prebuiltHelpSuffix = fmt.Sprintf("available: %s", strings.Join(prebuiltToolsSources, ", "))
		}
		errMsg := fmt.Errorf("prebuilt source tool for '%s' not found. %s", prebuiltSourceConfig, prebuiltHelpSuffix)
		return nil, errMsg
	}
	return content, nil
}

// Load all available pre built tools
func loadPrebuiltToolYAMLs() (map[string][]byte, []string, error) {
	toolYAMLs := make(map[string][]byte)
	var sourceTypes []string
	entries, err := prebuiltConfigsFS.ReadDir("tools")
	if err != nil {
		errMsg := fmt.Errorf("failed to read prebuilt tools %w", err)
		return nil, nil, errMsg
	}

	for _, entry := range entries {
		lowerName := strings.ToLower(entry.Name())
		if !entry.IsDir() && (strings.HasSuffix(lowerName, ".yaml")) {
			filePathInFS := path.Join("tools", entry.Name())
			content, err := prebuiltConfigsFS.ReadFile(filePathInFS)
			if err != nil {
				errMsg := fmt.Errorf("failed to read a prebuilt tool %w", err)
				return nil, nil, errMsg
			}
			sourceTypeKey := entry.Name()[:len(entry.Name())-len(".yaml")]

			sourceTypes = append(sourceTypes, sourceTypeKey)
			toolYAMLs[sourceTypeKey] = content
		}
	}
	if len(toolYAMLs) == 0 {
		errMsg := fmt.Errorf("no prebuilt tool configurations were loaded.%w", err)
		return nil, nil, errMsg
	}

	return toolYAMLs, sourceTypes, nil
}

```

--------------------------------------------------------------------------------
/docs/en/resources/tools/mysql/mysql-list-table-fragmentation.md:
--------------------------------------------------------------------------------

```markdown
---
title: "mysql-list-table-fragmentation"
type: docs
weight: 1
description: >
  A "mysql-list-table-fragmentation" tool lists top N fragemented tables in MySQL.
aliases:
- /resources/tools/mysql-list-table-fragmentation
---

## About

A `mysql-list-table-fragmentation` tool checks table fragmentation of MySQL
tables by calculating the size of the data and index files in bytes and
comparing with free space allocated to each table. This tool calculates
`fragmentation_percentage` which represents the proportion of free space
relative to the total data and index size. It's compatible with

- [cloud-sql-mysql](../../sources/cloud-sql-mysql.md)
- [mysql](../../sources/mysql.md)

`mysql-list-table-fragmentation` outputs detailed information as JSON , ordered
by the fragmentation percentage in descending order.
This tool takes 4 optional input parameters:

- `table_schema` (optional): The database where fragmentation check is to be
  executed. Check all tables visible to the current user if not specified.
- `table_name` (optional): Name of the table to be checked. Check all tables
  visible to the current user if not specified.
- `data_free_threshold_bytes` (optional): Only show tables with at least this
  much free space in bytes. Default 1.
- `limit` (optional): Max rows to return, default 10.

## Example

```yaml
tools:
  list_table_fragmentation:
    kind: mysql-list-table-fragmentation
    source: my-mysql-instance
    description: List table fragmentation in MySQL, by calculating the size of the data and index files and free space allocated to each table. The query calculates fragmentation percentage which represents the proportion of free space relative to the total data and index size. Storage can be reclaimed for tables with high fragmentation using OPTIMIZE TABLE.
```
The response is a json array with the following fields:
```json
{
  "table_schema": "The schema/database this table belongs to",
  "table_name": "Name of this table",
  "data_size": "Size of the table data in bytes",
  "index_size": "Size of the table's indexes in bytes",
  "data_free": "Free space (bytes) available in the table's data file",
  "fragmentation_percentage": "How much fragementation this table has",
}
```

## Reference

| **field**   | **type** | **required** | **description**                                    |
|-------------|:--------:|:------------:|----------------------------------------------------|
| kind        |  string  |     true     | Must be "mysql-list-table-fragmentation".          |
| source      |  string  |     true     | Name of the source the SQL should execute on.      |
| description |  string  |     true     | Description of the tool that is passed to the LLM. |

```

--------------------------------------------------------------------------------
/internal/tools/neo4j/neo4jschema/neo4jschema_test.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package neo4jschema

import (
	"testing"

	"github.com/goccy/go-yaml"
	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/genai-toolbox/internal/server"
	"github.com/googleapis/genai-toolbox/internal/testutils"
)

func TestParseFromYamlNeo4j(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	exp := 30

	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		want server.ToolConfigs
	}{
		{
			desc: "basic example with default cache expiration",
			in: `
			tools:
				example_tool:
					kind: neo4j-schema
					source: my-neo4j-instance
					description: some tool description
					authRequired:
						- my-google-auth-service
						- other-auth-service
			`,
			want: server.ToolConfigs{
				"example_tool": Config{
					Name:               "example_tool",
					Kind:               "neo4j-schema",
					Source:             "my-neo4j-instance",
					Description:        "some tool description",
					AuthRequired:       []string{"my-google-auth-service", "other-auth-service"},
					CacheExpireMinutes: nil,
				},
			},
		},
		{
			desc: "cache expire minutes set explicitly",
			in: `
			tools:
				example_tool:
					kind: neo4j-schema
					source: my-neo4j-instance
					description: some tool description
					cacheExpireMinutes: 30
			`,
			want: server.ToolConfigs{
				"example_tool": Config{
					Name:               "example_tool",
					Kind:               "neo4j-schema",
					Source:             "my-neo4j-instance",
					Description:        "some tool description",
					AuthRequired:       []string{}, // Expect an empty slice, not nil.
					CacheExpireMinutes: &exp,
				},
			},
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			// Parse contents
			err = yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err != nil {
				t.Fatalf("unable to unmarshal: %s", err)
			}
			if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
				t.Fatalf("incorrect parse: diff %v", diff)
			}
		})
	}
}

```

--------------------------------------------------------------------------------
/docs/en/resources/tools/mongodb/mongodb-delete-many.md:
--------------------------------------------------------------------------------

```markdown
---
title: "mongodb-delete-many"
type: docs
weight: 1
description: > 
  A "mongodb-delete-many" tool deletes all documents from a MongoDB collection that match a filter.
aliases:
- /resources/tools/mongodb-delete-many
---

## About

The `mongodb-delete-many` tool performs a **bulk destructive operation**,
deleting **ALL** documents from a collection that match a specified filter.

The tool returns the total count of documents that were deleted. If the filter
does not match any documents (i.e., the deleted count is 0), the tool will
return an error.

This tool is compatible with the following source kind:

* [`mongodb`](../../sources/mongodb.md)

---

## Example

Here is an example that performs a cleanup task by deleting all products from
the `inventory` collection that belong to a discontinued brand.

```yaml
tools:
  retire_brand_products:
    kind: mongodb-delete-many
    source: my-mongo-source
    description: Deletes all products from a specified discontinued brand.
    database: ecommerce
    collection: inventory
    filterPayload: |
        { "brand_name": {{json .brand_to_delete}} }
    filterParams:
      - name: brand_to_delete
        type: string
        description: The name of the discontinued brand whose products should be deleted.
```

## Reference

| **field**     | **type** | **required** | **description**                                                                                                     |
|:--------------|:---------|:-------------|:--------------------------------------------------------------------------------------------------------------------|
| kind          | string   | true         | Must be `mongodb-delete-many`.                                                                                      |
| source        | string   | true         | The name of the `mongodb` source to use.                                                                            |
| description   | string   | true         | A description of the tool that is passed to the LLM.                                                                |
| database      | string   | true         | The name of the MongoDB database containing the collection.                                                         |
| collection    | string   | true         | The name of the MongoDB collection from which to delete documents.                                                  |
| filterPayload | string   | true         | The MongoDB query filter document to select the documents for deletion. Uses `{{json .param_name}}` for templating. |
| filterParams  | list     | true         | A list of parameter objects that define the variables used in the `filterPayload`.                                  |

```

--------------------------------------------------------------------------------
/docs/en/getting-started/local_quickstart_js.md:
--------------------------------------------------------------------------------

```markdown
---
title: "JS Quickstart (Local)"
type: docs
weight: 3
description: >
  How to get started running Toolbox locally with [JavaScript](https://github.com/googleapis/mcp-toolbox-sdk-js), PostgreSQL, and orchestration frameworks such as [LangChain](https://js.langchain.com/docs/introduction/), [GenkitJS](https://genkit.dev/docs/get-started/),  [LlamaIndex](https://ts.llamaindex.ai/) and [GoogleGenAI](https://github.com/googleapis/js-genai).
---

## Before you begin

This guide assumes you have already done the following:

1. Installed [Node.js (v18 or higher)].
1. Installed [PostgreSQL 16+ and the `psql` client][install-postgres].

[Node.js (v18 or higher)]: https://nodejs.org/
[install-postgres]: https://www.postgresql.org/download/

### Cloud Setup (Optional)

{{< regionInclude "quickstart/shared/cloud_setup.md" "cloud_setup" >}}

## Step 1: Set up your database

{{< regionInclude "quickstart/shared/database_setup.md" "database_setup" >}}

## Step 2: Install and configure Toolbox

{{< regionInclude "quickstart/shared/configure_toolbox.md" "configure_toolbox" >}}

## Step 3: Connect your agent to Toolbox

In this section, we will write and run an agent that will load the Tools
from Toolbox.

1. (Optional) Initialize a Node.js project:

    ```bash
    npm init -y
    ```

1. In a new terminal, install the
   [SDK](https://www.npmjs.com/package/@toolbox-sdk/core).

    ```bash
    npm install @toolbox-sdk/core
    ```

1. Install other required dependencies

   {{< tabpane persist=header >}}
{{< tab header="LangChain" lang="bash" >}}
npm install langchain @langchain/google-genai
{{< /tab >}}
{{< tab header="GenkitJS" lang="bash" >}}
npm install genkit @genkit-ai/googleai
{{< /tab >}}
{{< tab header="LlamaIndex" lang="bash" >}}
npm install llamaindex @llamaindex/google @llamaindex/workflow
{{< /tab >}}
{{< tab header="GoogleGenAI" lang="bash" >}}
npm install @google/genai 
{{< /tab >}}
{{< /tabpane >}}

1. Create a new file named `hotelAgent.js` and copy the following code to create
   an agent:

    {{< tabpane persist=header >}}
{{< tab header="LangChain" lang="js" >}}

{{< include "quickstart/js/langchain/quickstart.js" >}}

{{< /tab >}}

{{< tab header="GenkitJS" lang="js" >}}

{{< include "quickstart/js/genkit/quickstart.js" >}}

{{< /tab >}}

{{< tab header="LlamaIndex" lang="js" >}}

{{< include "quickstart/js/llamaindex/quickstart.js" >}}

{{< /tab >}}

{{< tab header="GoogleGenAI" lang="js" >}}

{{< include "quickstart/js/genAI/quickstart.js" >}}

{{< /tab >}}

{{< /tabpane >}}

1. Run your agent, and observe the results:

    ```sh
    node hotelAgent.js
    ```

{{< notice info >}}
For more information, visit the [JS SDK
repo](https://github.com/googleapis/mcp-toolbox-sdk-js).
{{</ notice >}}

```

--------------------------------------------------------------------------------
/docs/en/resources/tools/neo4j/neo4j-execute-cypher.md:
--------------------------------------------------------------------------------

```markdown
---
title: "neo4j-execute-cypher"
type: docs
weight: 1
description: >
  A "neo4j-execute-cypher" tool executes any arbitrary Cypher statement against a Neo4j
  database.
aliases:
- /resources/tools/neo4j-execute-cypher
---

## About

A `neo4j-execute-cypher` tool executes an arbitrary Cypher query provided as a
string parameter against a Neo4j database. It's designed to be a flexible tool
for interacting with the database when a pre-defined query is not sufficient.
This tool is compatible with any of the following sources:

- [neo4j](../../sources/neo4j.md)

For security, the tool can be configured to be read-only. If the `readOnly` flag
is set to `true`, the tool will analyze the incoming Cypher query and reject any
write operations (like `CREATE`, `MERGE`, `DELETE`, etc.) before execution.

The Cypher query uses standard [Neo4j
Cypher](https://neo4j.com/docs/cypher-manual/current/queries/) syntax and
supports all Cypher features, including pattern matching, filtering, and
aggregation.

`neo4j-execute-cypher` takes one input parameter `cypher` and run the cypher
query against the `source`.

> **Note:** This tool is intended for developer assistant workflows with
> human-in-the-loop and shouldn't be used for production agents.

## Example

```yaml
tools:
  query_neo4j:
    kind: neo4j-execute-cypher
    source: my-neo4j-prod-db
    readOnly: true
    description: |
      Use this tool to execute a Cypher query against the production database.
      Only read-only queries are allowed.
      Takes a single 'cypher' parameter containing the full query string.
      Example:
      {{
          "cypher": "MATCH (m:Movie {title: 'The Matrix'}) RETURN m.released"
      }}
```

## Reference

| **field**   |                  **type**                  | **required** | **description**                                                                                 |
|-------------|:------------------------------------------:|:------------:|-------------------------------------------------------------------------------------------------|
| kind        |                   string                   |     true     | Must be "neo4j-cypher".                                                                         |
| source      |                   string                   |     true     | Name of the source the Cypher query should execute on.                                          |
| description |                   string                   |     true     | Description of the tool that is passed to the LLM.                                              |
| readOnly    |                   boolean                  |     false    | If set to `true`, the tool will reject any write operations in the Cypher query. Default is `false`. |

```

--------------------------------------------------------------------------------
/docs/en/samples/looker/looker_mcp_inspector/_index.md:
--------------------------------------------------------------------------------

```markdown
---
title: "Quickstart (MCP with Looker)"
type: docs
weight: 2
description: >
  How to get started running Toolbox with MCP Inspector and Looker as the source.
---

## Overview

[Model Context Protocol](https://modelcontextprotocol.io) is an open protocol
that standardizes how applications provide context to LLMs. Check out this page
on how to [connect to Toolbox via MCP](../../how-to/connect_via_mcp.md).

## Step 1: Get a Looker Client ID and Client Secret

The Looker Client ID and Client Secret can be obtained from the Users page of
your Looker instance. Refer to the documentation
[here](https://cloud.google.com/looker/docs/api-auth#authentication_with_an_sdk).
You may need to ask an administrator to get the Client ID and Client Secret
for you.

## Step 2: Install and configure Toolbox

In this section, we will download Toolbox and run the Toolbox server.

1. Download the latest version of Toolbox as a binary:

    {{< notice tip >}}
   Select the
   [correct binary](https://github.com/googleapis/genai-toolbox/releases)
   corresponding to your OS and CPU architecture.
    {{< /notice >}}
    <!-- {x-release-please-start-version} -->
    ```bash
    export OS="linux/amd64" # one of linux/amd64, darwin/arm64, darwin/amd64, or windows/amd64
    curl -O https://storage.googleapis.com/genai-toolbox/v0.17.0/$OS/toolbox
    ```
    <!-- {x-release-please-end} -->

1. Make the binary executable:

    ```bash
    chmod +x toolbox
    ```

1. Create a file `looker_env` with the settings for your
   Looker instance. Use the Client ID and Client Secret
   you obtained earlier.

   ```bash
    export LOOKER_BASE_URL=https://looker.example.com
    export LOOKER_VERIFY_SSL=true
    export LOOKER_CLIENT_ID=Q7ynZkRkvj9S9FHPm4Wj
    export LOOKER_CLIENT_SECRET=P5JvZstFnhpkhCYy2yNSfJ6x
   ```

   In some instances you may need to append `:19999` to
   the LOOKER_BASE_URL.

1. Load the looker_env file into your environment.

   ```bash
   source looker_env
   ```

1. Run the Toolbox server using the prebuilt Looker tools.

    ```bash
    ./toolbox --prebuilt looker
    ```

## Step 3: Connect to MCP Inspector

1. Run the MCP Inspector:

    ```bash
    npx @modelcontextprotocol/inspector
    ```

1. Type `y` when it asks to install the inspector package.

1. It should show the following when the MCP Inspector is up and running:

    ```bash
    🔍 MCP Inspector is up and running at http://127.0.0.1:5173 🚀
    ```

1. Open the above link in your browser.

1. For `Transport Type`, select `SSE`.

1. For `URL`, type in `http://127.0.0.1:5000/mcp/sse`.

1. Click Connect.

    ![inspector](./inspector.png)

1. Select `List Tools`, you will see a list of tools.

    ![inspector_tools](./inspector_tools.png)

1. Test out your tools here!

```

--------------------------------------------------------------------------------
/docs/en/resources/tools/mysql/mysql-list-active-queries.md:
--------------------------------------------------------------------------------

```markdown
---
title: "mysql-list-active-queries"
type: docs
weight: 1
description: >
  A "mysql-list-active-queries" tool lists active queries in a MySQL database.
aliases:
- /resources/tools/mysql-list-active-queries
---

## About

A `mysql-list-active-queries` tool retrieves information about active queries in
a MySQL database. It's compatible with:

- [cloud-sql-mysql](../../sources/cloud-sql-mysql.md)
- [mysql](../../sources/mysql.md)

`mysql-list-active-queries` outputs detailed information as JSON for current
active queries, ordered by execution time in descending order.
This tool takes 2 optional input parameters:

- `min_duration_secs` (optional): Only show queries running for at least this
  long in seconds, default `0`.
- `limit` (optional):  max number of queries to return, default `10`.

## Example

```yaml
tools:
  list_active_queries:
    kind: mysql-list-active-queries
    source: my-mysql-instance
    description: Lists top N (default 10) ongoing queries from processlist and innodb_trx, ordered by execution time in descending order. Returns detailed information of those queries in json format, including process id, query, transaction duration, transaction wait duration, process time, transaction state, process state, username with host, transaction rows locked, transaction rows modified, and db schema.
```

The response is a json array with the following fields:

```json
{
  "proccess_id": "id of the MySQL process/connection this query belongs to",
  "query": "query text",
  "trx_started": "the time when the transaction (this query belongs to) started",
  "trx_duration_seconds": "the total elapsed time (in seconds) of the owning transaction so far",
  "trx_wait_duration_seconds": "the total wait time (in seconds) of the owning transaction so far",
  "query_time": "the time (in seconds) that the owning connection has been in its current state",
  "trx_state": "the transaction execution state",
  "proces_state": "the current state of the owning connection",
  "user": "the user who issued this query",
  "trx_rows_locked": "the approximate number of rows locked by the owning transaction",
  "trx_rows_modified": "the approximate number of rows modified by the owning transaction",
  "db": "the default database for the owning connection"
}
```

## Reference

| **field**   | **type** | **required** | **description**                                    |
|-------------|:--------:|:------------:|----------------------------------------------------|
| kind        |  string  |     true     | Must be "mysql-list-active-queries".               |
| source      |  string  |     true     | Name of the source the SQL should execute on.      |
| description |  string  |     true     | Description of the tool that is passed to the LLM. |

```

--------------------------------------------------------------------------------
/docs/en/resources/tools/looker/looker-health-pulse.md:
--------------------------------------------------------------------------------

```markdown
---
title: "looker-health-pulse"
type: docs
weight: 1
description: >
  "looker-health-pulse" performs health checks on a Looker instance, with multiple actions available (e.g., checking database connections, dashboard performance, etc).
aliases:
- /resources/tools/looker-health-pulse
---

## About

The `looker-health-pulse` tool performs health checks on a Looker instance. The `action` parameter selects the type of check to perform:

- `check_db_connections`: Checks all database connections, runs supported tests, and reports query counts.
- `check_dashboard_performance`: Finds dashboards with slow running queries in the last 7 days.
- `check_dashboard_errors`: Lists dashboards with erroring queries in the last 7 days.
- `check_explore_performance`: Lists the slowest explores in the last 7 days and reports average query runtime.
- `check_schedule_failures`: Lists schedules that have failed in the last 7 days.
- `check_legacy_features`: Lists enabled legacy features. (*To note, this function is not available in Looker Core. You will get an error running this command with a Core instance configured.*)

## Parameters

| **field**     | **type** | **required** | **description**                             |
|---------------|:--------:|:------------:|---------------------------------------------|
| kind          | string   | true         | Must be "looker-health-pulse"                      |
| source        | string   | true         | Looker source name                          |
| action        | string   | true         | The health check to perform                 |

## Example

```yaml
tools:
  pulse:
    kind: looker-health-pulse
    source: looker-source
    description: |
      Pulse Tool

      Performs health checks on Looker instance.
      Specify the `action` parameter to select the check.
    parameters:
      action: check_dashboard_performance
```

## Reference

| **action**                | **description**                                                                |
|---------------------------|--------------------------------------------------------------------------------|
| check_db_connections      | Checks all database connections and reports query counts and errors            |
| check_dashboard_performance | Finds dashboards with slow queries (>30s) in the last 7 days                 |
| check_dashboard_errors    | Lists dashboards with erroring queries in the last 7 days                      |
| check_explore_performance | Lists slowest explores and average query runtime                               |
| check_schedule_failures   | Lists failed schedules in the last 7 days                                      |
| check_legacy_features     | Lists enabled legacy features                                                  |
```

--------------------------------------------------------------------------------
/internal/sources/sqlite/sqlite.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package sqlite

import (
	"context"
	"database/sql"
	"fmt"

	"github.com/goccy/go-yaml"
	"github.com/googleapis/genai-toolbox/internal/sources"
	"go.opentelemetry.io/otel/trace"
	_ "modernc.org/sqlite" // Pure Go SQLite driver
)

const SourceKind string = "sqlite"

// validate interface
var _ sources.SourceConfig = Config{}

func init() {
	if !sources.Register(SourceKind, newConfig) {
		panic(fmt.Sprintf("source kind %q already registered", SourceKind))
	}
}

func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources.SourceConfig, error) {
	actual := Config{Name: name}
	if err := decoder.DecodeContext(ctx, &actual); err != nil {
		return nil, err
	}
	return actual, nil
}

type Config struct {
	Name     string `yaml:"name" validate:"required"`
	Kind     string `yaml:"kind" validate:"required"`
	Database string `yaml:"database" validate:"required"` // Path to SQLite database file
}

func (r Config) SourceConfigKind() string {
	return SourceKind
}

func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) {
	db, err := initSQLiteConnection(ctx, tracer, r.Name, r.Database)
	if err != nil {
		return nil, fmt.Errorf("unable to create db connection: %w", err)
	}

	err = db.PingContext(context.Background())
	if err != nil {
		return nil, fmt.Errorf("unable to connect successfully: %w", err)
	}

	s := &Source{
		Name: r.Name,
		Kind: SourceKind,
		Db:   db,
	}
	return s, nil
}

var _ sources.Source = &Source{}

type Source struct {
	Name string `yaml:"name"`
	Kind string `yaml:"kind"`
	Db   *sql.DB
}

func (s *Source) SourceKind() string {
	return SourceKind
}

func (s *Source) SQLiteDB() *sql.DB {
	return s.Db
}

func initSQLiteConnection(ctx context.Context, tracer trace.Tracer, name, dbPath string) (*sql.DB, error) {
	//nolint:all // Reassigned ctx
	ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name)
	defer span.End()

	// Open database connection
	db, err := sql.Open("sqlite", dbPath)
	if err != nil {
		return nil, fmt.Errorf("sql.Open: %w", err)
	}

	// Set some reasonable defaults for SQLite
	db.SetMaxOpenConns(1) // SQLite only supports one writer at a time
	db.SetMaxIdleConns(1)

	return db, nil
}

```

--------------------------------------------------------------------------------
/docs/en/resources/tools/postgres/postgres-list-active-queries.md:
--------------------------------------------------------------------------------

```markdown
---
title: "postgres-list-active-queries"
type: docs
weight: 1
description: >
  The "postgres-list-active-queries" tool lists currently active queries in a Postgres database.
aliases:
- /resources/tools/postgres-list-active-queries
---

## About

The `postgres-list-active-queries` tool retrieves information about currently
active queries in a Postgres database. It's compatible with any of the following
sources:

- [alloydb-postgres](../../sources/alloydb-pg.md)
- [cloud-sql-postgres](../../sources/cloud-sql-pg.md)
- [postgres](../../sources/postgres.md)

`postgres-list-active-queries` lists detailed information as JSON for currently
active queries. The tool takes the following input parameters:

- `min_duraton` (optional): Only show queries running at least this long (e.g.,
  '1 minute', '1 second', '2 seconds'). Default: '1 minute'.
- `exclude_application_names` (optional): A comma-separated list of application
  names to exclude from the query results. This is useful for filtering out
  queries from specific applications (e.g., 'psql', 'pgAdmin', 'DBeaver'). The
  match is case-sensitive. Whitespace around commas and names is automatically
  handled. If this parameter is omitted, no applications are excluded.
- `limit` (optional): The maximum number of rows to return. Default: `50`.

## Example

```yaml
tools:
  list_active_queries:
    kind: postgres-list-active-queries
    source: postgres-source
    description: List the top N (default 50) currently running queries (state='active') from pg_stat_activity, ordered by longest-running first. Returns pid, user, database, application_name, client_addr, state, wait_event_type/wait_event, backend/xact/query start times, computed query_duration, and the SQL text.
```

The response is a json array with the following elements:

```json
{
  "pid": "process id",
  "user": "database user name",
  "datname": "database name",
  "application_name": "connecting application name",
  "client_addr": "connecting client ip address",
  "state": "connection state",
  "wait_event_type": "connection wait event type",
  "wait_event": "connection wait event",
  "backend_start": "connection start time",
  "xact_start": "transaction start time",
  "query_start": "query start time",
  "query_duration": "query duration",
  "query": "query text"
}
```

## Reference

| **field**   | **type** | **required** | **description**                                    |
|-------------|:--------:|:------------:|----------------------------------------------------|
| kind        |  string  |     true     | Must be "postgres-list-active-queries".            |
| source      |  string  |     true     | Name of the source the SQL should execute on.      |
| description |  string  |     true     | Description of the tool that is passed to the LLM. |

```

--------------------------------------------------------------------------------
/internal/sources/dataplex/dataplex_test.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dataplex_test

import (
	"testing"

	yaml "github.com/goccy/go-yaml"
	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/genai-toolbox/internal/server"
	"github.com/googleapis/genai-toolbox/internal/sources/dataplex"
	"github.com/googleapis/genai-toolbox/internal/testutils"
)

func TestParseFromYamlDataplex(t *testing.T) {
	tcs := []struct {
		desc string
		in   string
		want server.SourceConfigs
	}{
		{
			desc: "basic example",
			in: `
			sources:
				my-instance:
					kind: dataplex
					project: my-project
			`,
			want: server.SourceConfigs{
				"my-instance": dataplex.Config{
					Name:    "my-instance",
					Kind:    dataplex.SourceKind,
					Project: "my-project",
				},
			},
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Sources server.SourceConfigs `yaml:"sources"`
			}{}
			// Parse contents
			err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
			if err != nil {
				t.Fatalf("unable to unmarshal: %s", err)
			}
			if !cmp.Equal(tc.want, got.Sources) {
				t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
			}
		})
	}

}

func TestFailParseFromYaml(t *testing.T) {
	tcs := []struct {
		desc string
		in   string
		err  string
	}{
		{
			desc: "extra field",
			in: `
			sources:
				my-instance:
					kind: dataplex
					project: my-project
					foo: bar
			`,
			err: "unable to parse source \"my-instance\" as \"dataplex\": [1:1] unknown field \"foo\"\n>  1 | foo: bar\n       ^\n   2 | kind: dataplex\n   3 | project: my-project",
		},
		{
			desc: "missing required field",
			in: `
			sources:
				my-instance:
					kind: dataplex
			`,
			err: "unable to parse source \"my-instance\" as \"dataplex\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag",
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Sources server.SourceConfigs `yaml:"sources"`
			}{}
			// Parse contents
			err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
			if err == nil {
				t.Fatalf("expect parsing to fail")
			}
			errStr := err.Error()
			if errStr != tc.err {
				t.Fatalf("unexpected error: got %q, want %q", errStr, tc.err)
			}
		})
	}
}

```

--------------------------------------------------------------------------------
/docs/en/resources/tools/clickhouse/clickhouse-sql.md:
--------------------------------------------------------------------------------

```markdown
---
title: "clickhouse-sql"
type: docs
weight: 2
description: >
  A "clickhouse-sql" tool executes SQL queries as prepared statements in ClickHouse.
aliases:
- /resources/tools/clickhouse-sql
---

## About

A `clickhouse-sql` tool executes SQL queries as prepared statements against a
ClickHouse database. It's compatible with the
[clickhouse](../../sources/clickhouse.md) source.

This tool supports both template parameters (for SQL statement customization) 
and regular parameters (for prepared statement values), providing flexible 
query execution capabilities.

## Example

```yaml
tools:
  my_analytics_query:
    kind: clickhouse-sql
    source: my-clickhouse-instance
    description: Get user analytics for a specific date range
    statement: |
      SELECT 
        user_id,
        count(*) as event_count,
        max(timestamp) as last_event
      FROM events 
      WHERE date >= ? AND date <= ?
      GROUP BY user_id
      ORDER BY event_count DESC
      LIMIT ?
    parameters:
      - name: start_date
        description: Start date for the query (YYYY-MM-DD format)
      - name: end_date  
        description: End date for the query (YYYY-MM-DD format)
      - name: limit
        description: Maximum number of results to return
```

## Template Parameters Example

```yaml
tools:
  flexible_table_query:
    kind: clickhouse-sql
    source: my-clickhouse-instance
    description: Query any table with flexible columns
    statement: |
      SELECT {{columns}}
      FROM {{table_name}}
      WHERE created_date >= ?
      LIMIT ?
    templateParameters:
      - name: columns
        description: Comma-separated list of columns to select
      - name: table_name
        description: Name of the table to query
    parameters:
      - name: start_date
        description: Start date filter
      - name: limit
        description: Maximum number of results
```

## Reference

| **field**          |      **type**      | **required** | **description**                                       |
|--------------------|:------------------:|:------------:|-------------------------------------------------------|
| kind               |       string       |     true     | Must be "clickhouse-sql".                             |
| source             |       string       |     true     | Name of the ClickHouse source to execute SQL against. |
| description        |       string       |     true     | Description of the tool that is passed to the LLM.    |
| statement          |       string       |     true     | The SQL statement template to execute.                |
| parameters         | array of Parameter |    false     | Parameters for prepared statement values.             |
| templateParameters | array of Parameter |    false     | Parameters for SQL statement template customization.  |

```

--------------------------------------------------------------------------------
/internal/tools/alloydb/alloydbcreateuser/alloydbcreateuser_test.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package alloydbcreateuser_test

import (
	"testing"

	yaml "github.com/goccy/go-yaml"
	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/genai-toolbox/internal/server"
	"github.com/googleapis/genai-toolbox/internal/testutils"
	alloydbcreateuser "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydbcreateuser"
)

func TestParseFromYaml(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		want server.ToolConfigs
	}{
		{
			desc: "basic example",
			in: `
            tools:
                create-my-user:
                    kind: alloydb-create-user
                    source: my-alloydb-admin-source
                    description: some description
            `,
			want: server.ToolConfigs{
				"create-my-user": alloydbcreateuser.Config{
					Name:         "create-my-user",
					Kind:         "alloydb-create-user",
					Source:       "my-alloydb-admin-source",
					Description:  "some description",
					AuthRequired: []string{},
				},
			},
		},
		{
			desc: "with auth required",
			in: `
            tools:
                create-my-user-auth:
                    kind: alloydb-create-user
                    source: my-alloydb-admin-source
                    description: some description
                    authRequired: 
                        - my-google-auth-service
                        - other-auth-service
            `,
			want: server.ToolConfigs{
				"create-my-user-auth": alloydbcreateuser.Config{
					Name:         "create-my-user-auth",
					Kind:         "alloydb-create-user",
					Source:       "my-alloydb-admin-source",
					Description:  "some description",
					AuthRequired: []string{"my-google-auth-service", "other-auth-service"},
				},
			},
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			// Parse contents
			err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err != nil {
				t.Fatalf("unable to unmarshal: %s", err)
			}
			if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
				t.Fatalf("incorrect parse: diff %v", diff)
			}
		})
	}
}

```

--------------------------------------------------------------------------------
/internal/tools/dgraph/dgraph_test.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dgraph_test

import (
	"testing"

	yaml "github.com/goccy/go-yaml"
	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/genai-toolbox/internal/server"
	"github.com/googleapis/genai-toolbox/internal/testutils"
	"github.com/googleapis/genai-toolbox/internal/tools/dgraph"
)

func TestParseFromYamlDgraph(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		want server.ToolConfigs
	}{
		{
			desc: "basic query example",
			in: `
			tools:
				example_tool:
					kind: dgraph-dql
					source: my-dgraph-instance
					description: some tool description
					isQuery: true
					timeout: 20s
					statement: |
						    query {q(func: eq(email, "[email protected]")) {email}}
			`,
			want: server.ToolConfigs{
				"example_tool": dgraph.Config{
					Name:         "example_tool",
					Kind:         "dgraph-dql",
					Source:       "my-dgraph-instance",
					AuthRequired: []string{},
					Description:  "some tool description",
					IsQuery:      true,
					Timeout:      "20s",
					Statement:    "query {q(func: eq(email, \"[email protected]\")) {email}}\n",
				},
			},
		},
		{
			desc: "basic mutation example",
			in: `
			tools:
				example_tool:
					kind: dgraph-dql
					source: my-dgraph-instance
					description: some tool description
					statement: |
					  mutation {set { _:a <name> "[email protected]" . _:b <email> "[email protected]" .}}
			`,
			want: server.ToolConfigs{
				"example_tool": dgraph.Config{
					Name:         "example_tool",
					Kind:         "dgraph-dql",
					Source:       "my-dgraph-instance",
					Description:  "some tool description",
					AuthRequired: []string{},
					Statement:    "mutation {set { _:a <name> \"[email protected]\" . _:b <email> \"[email protected]\" .}}\n",
				},
			},
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			// Parse contents
			err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err != nil {
				t.Fatalf("unable to unmarshal: %s", err)
			}
			if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
				t.Fatalf("incorrect parse: diff %v", diff)
			}
		})
	}

}

```

--------------------------------------------------------------------------------
/docs/en/resources/sources/trino.md:
--------------------------------------------------------------------------------

```markdown
---
title: "Trino"
type: docs
weight: 1
description: >
  Trino is a distributed SQL query engine for big data analytics.
---

## About

[Trino][trino-docs] is a distributed SQL query engine designed for fast analytic
queries against data of any size. It allows you to query data where it lives,
including Hive, Cassandra, relational databases or even proprietary data stores.

[trino-docs]: https://trino.io/docs/

## Available Tools

- [`trino-sql`](../tools/trino/trino-sql.md)  
  Execute parameterized SQL queries against Trino.

- [`trino-execute-sql`](../tools/trino/trino-execute-sql.md)  
  Execute arbitrary SQL queries against Trino.

## Requirements

### Trino Cluster

You need access to a running Trino cluster with appropriate user permissions for
the catalogs and schemas you want to query.

## Example

```yaml
sources:
    my-trino-source:
    kind: trino
    host: trino.example.com
    port: "8080"
    user: ${TRINO_USER}  # Optional for anonymous access
    password: ${TRINO_PASSWORD}  # Optional
    catalog: hive
    schema: default
```

{{< notice tip >}}
Use environment variable replacement with the format ${ENV_NAME}
instead of hardcoding your secrets into the configuration file.
{{< /notice >}}

## Reference

| **field**       | **type** | **required** | **description**                                                              |
|-----------------|:--------:|:------------:|------------------------------------------------------------------------------|
| kind            |  string  |     true     | Must be "trino".                                                             |
| host            |  string  |     true     | Trino coordinator hostname (e.g. "trino.example.com")                        |
| port            |  string  |     true     | Trino coordinator port (e.g. "8080", "8443")                                 |
| user            |  string  |    false     | Username for authentication (e.g. "analyst"). Optional for anonymous access. |
| password        |  string  |    false     | Password for basic authentication                                            |
| catalog         |  string  |     true     | Default catalog to use for queries (e.g. "hive")                             |
| schema          |  string  |     true     | Default schema to use for queries (e.g. "default")                           |
| queryTimeout    |  string  |    false     | Query timeout duration (e.g. "30m", "1h")                                    |
| accessToken     |  string  |    false     | JWT access token for authentication                                          |
| kerberosEnabled | boolean  |    false     | Enable Kerberos authentication (default: false)                              |
| sslEnabled      | boolean  |    false     | Enable SSL/TLS (default: false)                                              |

```

--------------------------------------------------------------------------------
/internal/tools/alloydb/alloydbcreatecluster/alloydbcreatecluster_test.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package alloydbcreatecluster_test

import (
	"testing"

	yaml "github.com/goccy/go-yaml"
	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/genai-toolbox/internal/server"
	"github.com/googleapis/genai-toolbox/internal/testutils"
	alloydbcreatecluster "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydbcreatecluster"
)

func TestParseFromYaml(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		want server.ToolConfigs
	}{
		{
			desc: "basic example",
			in: `
            tools:
                create-my-cluster:
                    kind: alloydb-create-cluster
                    source: my-alloydb-admin-source
                    description: some description
            `,
			want: server.ToolConfigs{
				"create-my-cluster": alloydbcreatecluster.Config{
					Name:         "create-my-cluster",
					Kind:         "alloydb-create-cluster",
					Source:       "my-alloydb-admin-source",
					Description:  "some description",
					AuthRequired: []string{},
				},
			},
		},
		{
			desc: "with auth required",
			in: `
            tools:
                create-my-cluster-auth:
                    kind: alloydb-create-cluster
                    source: my-alloydb-admin-source
                    description: some description
                    authRequired: 
                        - my-google-auth-service
                        - other-auth-service
            `,
			want: server.ToolConfigs{
				"create-my-cluster-auth": alloydbcreatecluster.Config{
					Name:         "create-my-cluster-auth",
					Kind:         "alloydb-create-cluster",
					Source:       "my-alloydb-admin-source",
					Description:  "some description",
					AuthRequired: []string{"my-google-auth-service", "other-auth-service"},
				},
			},
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			// Parse contents
			err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err != nil {
				t.Fatalf("unable to unmarshal: %s", err)
			}
			if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
				t.Fatalf("incorrect parse: diff %v", diff)
			}
		})
	}
}

```

--------------------------------------------------------------------------------
/docs/en/how-to/deploy_docker.md:
--------------------------------------------------------------------------------

```markdown
---
title: "Deploy using Docker Compose"
type: docs
weight: 4
description: >
  How to deploy Toolbox using Docker Compose.
---

<!-- Contributor: Sujith R Pillai <[email protected]> -->

## Before you begin

1. [Install Docker Compose.](https://docs.docker.com/compose/install/)

## Configure `tools.yaml` file

Create a `tools.yaml` file that contains your configuration for Toolbox. For
details, see the
[configuration](https://github.com/googleapis/genai-toolbox/blob/main/README.md#configuration)
section.

## Deploy using Docker Compose

1. Create a `docker-compose.yml` file, customizing as needed:

```yaml
services:
  toolbox:
    # TODO: It is recommended to pin to a specific image version instead of latest.
    image:  us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:latest
    hostname: toolbox
    platform: linux/amd64
    ports:
      - "5000:5000"
    volumes:
      - ./config:/config
    command: [ "toolbox", "--tools-file", "/config/tools.yaml", "--address", "0.0.0.0"]
    depends_on:
      db:
        condition: service_healthy
    networks:
      - tool-network
  db:
    # TODO: It is recommended to pin to a specific image version instead of latest.
    image: postgres
    hostname: db
    environment:
      POSTGRES_USER: toolbox_user
      POSTGRES_PASSWORD: my-password
      POSTGRES_DB: toolbox_db
    ports:
      - "5432:5432"
    volumes:
      - ./db:/var/lib/postgresql/data
      # This file can be used to bootstrap your schema if needed.
      # See "initialization scripts" on https://hub.docker.com/_/postgres/ for more info
      - ./config/init.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U toolbox_user -d toolbox_db"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - tool-network
networks:
  tool-network:

```

1. Run the following command to bring up the Toolbox and Postgres instance

    ```bash
    docker-compose up -d
    ```

{{< notice tip >}}

You can use this setup to quickly set up Toolbox + Postgres to follow along in our
[Quickstart](../getting-started/local_quickstart.md)

{{< /notice >}}

## Connecting with Toolbox Client SDK

Next, we will use Toolbox with the Client SDKs:

1. The url for the Toolbox server running using docker-compose will be:

    ```
    http://localhost:5000
    ```

1. Import and initialize the client with the URL:

   {{< tabpane persist=header >}}
{{< tab header="LangChain" lang="Python" >}}
from toolbox_langchain import ToolboxClient

# Replace with the cloud run service URL generated above

async with ToolboxClient("http://$YOUR_URL") as toolbox:
{{< /tab >}}
{{< tab header="Llamaindex" lang="Python" >}}
from toolbox_llamaindex import ToolboxClient

# Replace with the cloud run service URL generated above

async with ToolboxClient("http://$YOUR_URL") as toolbox:
{{< /tab >}}
{{< /tabpane >}}

```

--------------------------------------------------------------------------------
/internal/sources/mongodb/mongodb_test.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package mongodb_test

import (
	"testing"

	yaml "github.com/goccy/go-yaml"
	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/genai-toolbox/internal/server"
	"github.com/googleapis/genai-toolbox/internal/sources/mongodb"
	"github.com/googleapis/genai-toolbox/internal/testutils"
)

func TestParseFromYamlMongoDB(t *testing.T) {
	tcs := []struct {
		desc string
		in   string
		want server.SourceConfigs
	}{
		{
			desc: "basic example",
			in: `
			sources:
				mongo-db:
					kind: "mongodb"
					uri: "mongodb+srv://username:password@host/dbname"
			`,
			want: server.SourceConfigs{
				"mongo-db": mongodb.Config{
					Name: "mongo-db",
					Kind: mongodb.SourceKind,
					Uri:  "mongodb+srv://username:password@host/dbname",
				},
			},
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Sources server.SourceConfigs `yaml:"sources"`
			}{}
			// Parse contents
			err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
			if err != nil {
				t.Fatalf("unable to unmarshal: %s", err)
			}
			if !cmp.Equal(tc.want, got.Sources) {
				t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
			}
		})
	}

}

func TestFailParseFromYaml(t *testing.T) {
	tcs := []struct {
		desc string
		in   string
		err  string
	}{
		{
			desc: "extra field",
			in: `
			sources:
				mongo-db:
					kind: mongodb
					uri: "mongodb+srv://username:password@host/dbname"
					foo: bar
			`,
			err: "unable to parse source \"mongo-db\" as \"mongodb\": [1:1] unknown field \"foo\"\n>  1 | foo: bar\n       ^\n   2 | kind: mongodb\n   3 | uri: mongodb+srv://username:password@host/dbname",
		},
		{
			desc: "missing required field",
			in: `
			sources:
				mongo-db:
					kind: mongodb
			`,
			err: "unable to parse source \"mongo-db\" as \"mongodb\": Key: 'Config.Uri' Error:Field validation for 'Uri' failed on the 'required' tag",
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Sources server.SourceConfigs `yaml:"sources"`
			}{}
			// Parse contents
			err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
			if err == nil {
				t.Fatalf("expect parsing to fail")
			}
			errStr := err.Error()
			if errStr != tc.err {
				t.Fatalf("unexpected error: got \n%q, want \n%q", errStr, tc.err)
			}
		})
	}
}

```

--------------------------------------------------------------------------------
/internal/tools/alloydb/alloydbcreateinstance/alloydbcreateinstance_test.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package alloydbcreateinstance_test

import (
	"testing"

	yaml "github.com/goccy/go-yaml"
	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/genai-toolbox/internal/server"
	"github.com/googleapis/genai-toolbox/internal/testutils"
	alloydbcreateinstance "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydbcreateinstance"
)

func TestParseFromYaml(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		want server.ToolConfigs
	}{
		{
			desc: "basic example",
			in: `
            tools:
                create-my-instance:
                    kind: alloydb-create-instance
                    source: my-alloydb-admin-source
                    description: some description
            `,
			want: server.ToolConfigs{
				"create-my-instance": alloydbcreateinstance.Config{
					Name:         "create-my-instance",
					Kind:         "alloydb-create-instance",
					Source:       "my-alloydb-admin-source",
					Description:  "some description",
					AuthRequired: []string{},
				},
			},
		},
		{
			desc: "with auth required",
			in: `
            tools:
                create-my-instance-auth:
                    kind: alloydb-create-instance
                    source: my-alloydb-admin-source
                    description: some description
                    authRequired: 
                        - my-google-auth-service
                        - other-auth-service
            `,
			want: server.ToolConfigs{
				"create-my-instance-auth": alloydbcreateinstance.Config{
					Name:         "create-my-instance-auth",
					Kind:         "alloydb-create-instance",
					Source:       "my-alloydb-admin-source",
					Description:  "some description",
					AuthRequired: []string{"my-google-auth-service", "other-auth-service"},
				},
			},
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			// Parse contents
			err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err != nil {
				t.Fatalf("unable to unmarshal: %s", err)
			}
			if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
				t.Fatalf("incorrect parse: diff %v", diff)
			}
		})
	}
}

```

--------------------------------------------------------------------------------
/internal/tools/clickhouse/clickhouselistdatabases/clickhouselistdatabases_test.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package clickhouse

import (
	"testing"

	yaml "github.com/goccy/go-yaml"
	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/genai-toolbox/internal/server"
	"github.com/googleapis/genai-toolbox/internal/sources"
	"github.com/googleapis/genai-toolbox/internal/testutils"
	"github.com/googleapis/genai-toolbox/internal/tools"
)

func TestListDatabasesConfigToolConfigKind(t *testing.T) {
	cfg := Config{}
	if cfg.ToolConfigKind() != listDatabasesKind {
		t.Errorf("expected %q, got %q", listDatabasesKind, cfg.ToolConfigKind())
	}
}

func TestListDatabasesConfigInitializeMissingSource(t *testing.T) {
	cfg := Config{
		Name:        "test-list-databases",
		Kind:        listDatabasesKind,
		Source:      "missing-source",
		Description: "Test list databases tool",
	}

	srcs := map[string]sources.Source{}
	_, err := cfg.Initialize(srcs)
	if err == nil {
		t.Error("expected error for missing source")
	}
}

func TestParseFromYamlClickHouseListDatabases(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		want server.ToolConfigs
	}{
		{
			desc: "basic example",
			in: `
			tools:
				example_tool:
					kind: clickhouse-list-databases
					source: my-instance
					description: some description
			`,
			want: server.ToolConfigs{
				"example_tool": Config{
					Name:         "example_tool",
					Kind:         "clickhouse-list-databases",
					Source:       "my-instance",
					Description:  "some description",
					AuthRequired: []string{},
				},
			},
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err != nil {
				t.Fatalf("unable to unmarshal: %s", err)
			}
			if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
				t.Fatalf("incorrect parse: diff %v", diff)
			}
		})
	}
}

func TestListDatabasesToolParseParams(t *testing.T) {
	tool := Tool{
		Parameters: tools.Parameters{},
	}

	params, err := tool.ParseParams(map[string]any{}, map[string]map[string]any{})
	if err != nil {
		t.Errorf("unexpected error: %v", err)
	}

	if len(params) != 0 {
		t.Errorf("expected 0 parameters, got %d", len(params))
	}
}

```

--------------------------------------------------------------------------------
/docs/en/resources/tools/cloudsql/cloudsqlmysqlcreateinstance.md:
--------------------------------------------------------------------------------

```markdown
---
title: cloud-sql-mysql-create-instance
type: docs
weight: 2
description: "Create a Cloud SQL for MySQL instance."
---

The `cloud-sql-mysql-create-instance` tool creates a new Cloud SQL for MySQL
instance in a specified Google Cloud project.

{{< notice info >}}
This tool uses the `cloud-sql-admin` source.
{{< /notice >}}

## Configuration

Here is an example of how to configure the `cloud-sql-mysql-create-instance`
tool in your `tools.yaml` file:

```yaml
sources:
  my-cloud-sql-admin-source:
    kind: cloud-sql-admin

tools:
  create_my_mysql_instance:
    kind: cloud-sql-mysql-create-instance
    source: my-cloud-sql-admin-source
    description: "Creates a MySQL instance using `Production` and `Development` presets. For the `Development` template, it chooses a 2 vCPU, 16 GiB RAM, 100 GiB SSD configuration with Non-HA/zonal availability. For the `Production` template, it chooses an 8 vCPU, 64 GiB RAM, 250 GiB SSD configuration with HA/regional availability. The Enterprise Plus edition is used in both cases. The default database version is `MYSQL_8_4`. The agent should ask the user if they want to use a different version."
```

## Parameters

The `cloud-sql-mysql-create-instance` tool has the following parameters:

| **field**       | **type** | **required** | **description**                                                                                                 |
| --------------- | :------: | :----------: | --------------------------------------------------------------------------------------------------------------- |
| project         |  string  |     true     | The Google Cloud project ID.                                                                                    |
| name            |  string  |     true     | The name of the instance to create.                                                                             |
| databaseVersion |  string  |     false    | The database version for MySQL. If not specified, defaults to the latest available version (e.g., `MYSQL_8_4`). |
| rootPassword    |  string  |     true     | The root password for the instance.                                                                             |
| editionPreset   |  string  |     false    | The edition of the instance. Can be `Production` or `Development`. Defaults to `Development`.                   |

## Reference

| **field**   | **type** | **required** | **description**                                                |
| ----------- | :------: | :----------: | -------------------------------------------------------------- |
| kind        |  string  |     true     | Must be `cloud-sql-mysql-create-instance`.                     |
| source      |  string  |     true     | The name of the `cloud-sql-admin` source to use for this tool. |
| description |  string  |     false    | A description of the tool that is passed to the agent.         |

```

--------------------------------------------------------------------------------
/docs/en/resources/tools/cloudsql/cloudsqlpgcreateinstances.md:
--------------------------------------------------------------------------------

```markdown
---
title: cloud-sql-postgres-create-instance
type: docs
weight: 10
description: Create a Cloud SQL for PostgreSQL instance.
---

The `cloud-sql-postgres-create-instance` tool creates a Cloud SQL for PostgreSQL
instance using the Cloud SQL Admin API.

{{< notice info >}}
This tool uses a `source` of kind `cloud-sql-admin`.
{{< /notice >}}

## Example

```yaml
tools:
  create-sql-instance:
    kind: cloud-sql-postgres-create-instance
    source: cloud-sql-admin-source
    description: "Creates a Postgres instance using `Production` and `Development` presets. For the `Development` template, it chooses a 2 vCPU, 16 GiB RAM, 100 GiB SSD configuration with Non-HA/zonal availability. For the `Production` template, it chooses an 8 vCPU, 64 GiB RAM, 250 GiB SSD configuration with HA/regional availability. The Enterprise Plus edition is used in both cases. The default database version is `POSTGRES_17`. The agent should ask the user if they want to use a different version."
```

## Reference

### Tool Configuration

| **field**   | **type** | **required** | **description**                                  |
| ----------- | :------: | :----------: | ------------------------------------------------ |
| kind        |  string  |     true     | Must be "cloud-sql-postgres-create-instance".    |
| source      |  string  |     true     | The name of the `cloud-sql-admin` source to use. |
| description |  string  |     false    | A description of the tool.                       |

### Tool Inputs

| **parameter**   | **type** | **required** | **description**                                                                                                                                          |
|-----------------|:--------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| project         |  string  |     true     | The project ID.                                                                                                                                          |
| name            |  string  |     true     | The name of the instance.                                                                                                                                |
| databaseVersion |  string  |    false     | The database version for Postgres. If not specified, defaults to the latest available version (e.g., POSTGRES_17).                                       |
| rootPassword    |  string  |     true     | The root password for the instance.                                                                                                                      |
| editionPreset   |  string  |    false     | The edition of the instance. Can be `Production` or `Development`. This determines the default machine type and availability. Defaults to `Development`. |

```

--------------------------------------------------------------------------------
/docs/en/resources/tools/mongodb/mongodb-delete-one.md:
--------------------------------------------------------------------------------

```markdown
---
title: "mongodb-delete-one"
type: docs
weight: 1
description: > 
  A "mongodb-delete-one" tool deletes a single document from a MongoDB collection.
aliases:
- /resources/tools/mongodb-delete-one
---

## About

The `mongodb-delete-one` tool performs a destructive operation, deleting the
**first single document** that matches a specified filter from a MongoDB
collection.

If the filter matches multiple documents, only the first one found by the
database will be deleted. This tool is useful for removing specific entries,
such as a user account or a single item from an inventory based on a unique ID.

The tool returns the number of documents deleted, which will be either `1` if a
document was found and deleted, or `0` if no matching document was found.

This tool is compatible with the following source kind:

* [`mongodb`](../../sources/mongodb.md)

---

## Example

Here is an example that deletes a specific user account from the `users`
collection by matching their unique email address. This is a permanent action.

```yaml
tools:
  delete_user_account:
    kind: mongodb-delete-one
    source: my-mongo-source
    description: Permanently deletes a user account by their email address.
    database: user_data
    collection: users
    filterPayload: |
        { "email": {{json .email_address}} }
    filterParams:
      - name: email_address
        type: string
        description: The email of the user account to delete.
```

## Reference

| **field**     | **type** | **required** | **description**                                                                                                    |
|:--------------|:---------|:-------------|:-------------------------------------------------------------------------------------------------------------------|
| kind          | string   | true         | Must be `mongodb-delete-one`.                                                                                      |
| source        | string   | true         | The name of the `mongodb` source to use.                                                                           |
| description   | string   | true         | A description of the tool that is passed to the LLM.                                                               |
| database      | string   | true         | The name of the MongoDB database containing the collection.                                                        |
| collection    | string   | true         | The name of the MongoDB collection from which to delete a document.                                                |
| filterPayload | string   | true         | The MongoDB query filter document to select the document for deletion. Uses `{{json .param_name}}` for templating. |
| filterParams  | list     | true         | A list of parameter objects that define the variables used in the `filterPayload`.                                 |

```

--------------------------------------------------------------------------------
/internal/sources/bigtable/bigtable.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package bigtable

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigtable"
	"github.com/goccy/go-yaml"
	"github.com/googleapis/genai-toolbox/internal/sources"
	"github.com/googleapis/genai-toolbox/internal/util"
	"go.opentelemetry.io/otel/trace"
	"google.golang.org/api/option"
)

const SourceKind string = "bigtable"

// validate interface
var _ sources.SourceConfig = Config{}

func init() {
	if !sources.Register(SourceKind, newConfig) {
		panic(fmt.Sprintf("source kind %q already registered", SourceKind))
	}
}

func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources.SourceConfig, error) {
	actual := Config{Name: name}
	if err := decoder.DecodeContext(ctx, &actual); err != nil {
		return nil, err
	}
	return actual, nil
}

type Config struct {
	Name     string `yaml:"name" validate:"required"`
	Kind     string `yaml:"kind" validate:"required"`
	Project  string `yaml:"project" validate:"required"`
	Instance string `yaml:"instance" validate:"required"`
}

func (r Config) SourceConfigKind() string {
	return SourceKind
}

func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) {
	client, err := initBigtableClient(ctx, tracer, r.Name, r.Project, r.Instance)
	if err != nil {
		return nil, fmt.Errorf("unable to create client: %w", err)
	}

	s := &Source{
		Name:   r.Name,
		Kind:   SourceKind,
		Client: client,
	}
	return s, nil
}

var _ sources.Source = &Source{}

type Source struct {
	Name   string `yaml:"name"`
	Kind   string `yaml:"kind"`
	Client *bigtable.Client
}

func (s *Source) SourceKind() string {
	return SourceKind
}

func (s *Source) BigtableClient() *bigtable.Client {
	return s.Client
}

func initBigtableClient(ctx context.Context, tracer trace.Tracer, name, project, instance string) (*bigtable.Client, error) {
	//nolint:all // Reassigned ctx
	ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name)
	defer span.End()

	// Set up Bigtable data operations client.
	poolSize := 10
	userAgent, err := util.UserAgentFromContext(ctx)
	if err != nil {
		return nil, err
	}

	client, err := bigtable.NewClient(ctx, project, instance, option.WithUserAgent(userAgent), option.WithGRPCConnectionPool(poolSize))

	if err != nil {
		return nil, fmt.Errorf("unable to create bigtable.NewClient: %w", err)
	}

	return client, nil
}

```

--------------------------------------------------------------------------------
/docs/en/resources/tools/cloudsql/cloudsqlmssqlcreateinstance.md:
--------------------------------------------------------------------------------

```markdown
---
title: cloud-sql-mssql-create-instance
type: docs
weight: 10
description: "Create a Cloud SQL for SQL Server instance."
---

The `cloud-sql-mssql-create-instance` tool creates a Cloud SQL for SQL Server
instance using the Cloud SQL Admin API.

{{< notice info dd>}}
This tool uses a `source` of kind `cloud-sql-admin`.
{{< /notice >}}

## Example

```yaml
tools:
  create-sql-instance:
    kind: cloud-sql-mssql-create-instance
    source: cloud-sql-admin-source
    description: "Creates a SQL Server instance using `Production` and `Development` presets. For the `Development` template, it chooses a 2 vCPU, 8 GiB RAM (`db-custom-2-8192`) configuration with Non-HA/zonal availability. For the `Production` template, it chooses a 4 vCPU, 26 GiB RAM (`db-custom-4-26624`) configuration with HA/regional availability. The Enterprise edition is used in both cases. The default database version is `SQLSERVER_2022_STANDARD`. The agent should ask the user if they want to use a different version."
```

## Reference

### Tool Configuration

| **field**   | **type** | **required** | **description**                                  |
| ----------- | :------: | :----------: | ------------------------------------------------ |
| kind        |  string  |     true     | Must be "cloud-sql-mssql-create-instance".       |
| source      |  string  |     true     | The name of the `cloud-sql-admin` source to use. |
| description |  string  |    false     | A description of the tool.                       |

### Tool Inputs

| **parameter**   | **type** | **required** | **description**                                                                                                                                          |
|-----------------|:--------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| project         |  string  |     true     | The project ID.                                                                                                                                          |
| name            |  string  |     true     | The name of the instance.                                                                                                                                |
| databaseVersion |  string  |    false     | The database version for SQL Server. If not specified, defaults to the latest available version (e.g., SQLSERVER_2022_STANDARD).                         |
| rootPassword    |  string  |     true     | The root password for the instance.                                                                                                                      |
| editionPreset   |  string  |    false     | The edition of the instance. Can be `Production` or `Development`. This determines the default machine type and availability. Defaults to `Development`. |

```

--------------------------------------------------------------------------------
/.ci/quickstart_test/run_py_tests.sh:
--------------------------------------------------------------------------------

```bash
# Copyright 2025 Google LLC
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
#      http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#!/bin/bash

set -e

TABLE_NAME="hotels_python"
QUICKSTART_PYTHON_DIR="docs/en/getting-started/quickstart/python"
SQL_FILE=".ci/quickstart_test/setup_hotels_sample.sql"

PROXY_PID=""
TOOLBOX_PID=""

install_system_packages() {
  apt-get update && apt-get install -y \
    postgresql-client \
    python3-venv \
    wget \
    gettext-base  \
    netcat-openbsd
}

start_cloud_sql_proxy() {
  wget "https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.10.0/cloud-sql-proxy.linux.amd64" -O /usr/local/bin/cloud-sql-proxy
  chmod +x /usr/local/bin/cloud-sql-proxy
  cloud-sql-proxy "${CLOUD_SQL_INSTANCE}" &
  PROXY_PID=$!

  for i in {1..30}; do
    if nc -z 127.0.0.1 5432; then
      echo "Cloud SQL Proxy is up and running."
      return
    fi
    sleep 1
  done

  echo "Cloud SQL Proxy failed to start within the timeout period."
  exit 1
}

setup_toolbox() {
  TOOLBOX_YAML="/tools.yaml"
  echo "${TOOLS_YAML_CONTENT}" > "$TOOLBOX_YAML"
  if [ ! -f "$TOOLBOX_YAML" ]; then echo "Failed to create tools.yaml"; exit 1; fi
  wget "https://storage.googleapis.com/genai-toolbox/v${VERSION}/linux/amd64/toolbox" -O "/toolbox"
  chmod +x "/toolbox"
  /toolbox --tools-file "$TOOLBOX_YAML" &
  TOOLBOX_PID=$!
  sleep 2
}

setup_orch_table() {
  export TABLE_NAME
  envsubst < "$SQL_FILE" | psql -h "$PGHOST" -p "$PGPORT" -U "$DB_USER" -d "$DATABASE_NAME"
}

run_orch_test() {
  local orch_dir="$1"
  local orch_name
  orch_name=$(basename "$orch_dir")
  (
    set -e
    setup_orch_table
    cd "$orch_dir"
    local VENV_DIR=".venv"
    python3 -m venv "$VENV_DIR"
    source "$VENV_DIR/bin/activate"
    pip install -r requirements.txt
    echo "--- Running tests for $orch_name ---"
    cd ..
    ORCH_NAME="$orch_name" pytest
    rm -rf "$VENV_DIR"
  )
}

cleanup_all() {
  echo "--- Final cleanup: Shutting down processes and dropping table ---"
  if [ -n "$TOOLBOX_PID" ]; then
    kill $TOOLBOX_PID || true
  fi
  if [ -n "$PROXY_PID" ]; then
    kill $PROXY_PID || true
  fi
}
trap cleanup_all EXIT

# Main script execution
install_system_packages
start_cloud_sql_proxy

export PGHOST=127.0.0.1
export PGPORT=5432
export PGPASSWORD="$DB_PASSWORD"
export GOOGLE_API_KEY="$GOOGLE_API_KEY"

setup_toolbox

for ORCH_DIR in "$QUICKSTART_PYTHON_DIR"/*/; do
  if [ ! -d "$ORCH_DIR" ]; then
    continue
  fi
  run_orch_test "$ORCH_DIR"
done

```

--------------------------------------------------------------------------------
/docs/en/resources/tools/bigquery/bigquery-conversational-analytics.md:
--------------------------------------------------------------------------------

```markdown
---
title: "bigquery-conversational-analytics"
type: docs
weight: 1
description: > 
  A "bigquery-conversational-analytics" tool allows conversational interaction with a BigQuery source.
aliases:
- /resources/tools/bigquery-conversational-analytics
---

## About

A `bigquery-conversational-analytics` tool allows you to ask questions about
your data in natural language.

This function takes a user's question (which can include conversational history
for context) and references to specific BigQuery tables, and sends them to a
stateless conversational API.

The API uses a GenAI agent to understand the question, generate and execute SQL
queries and Python code, and formulate an answer. This function returns a
detailed, sequential log of this entire process, which includes any generated
SQL or Python code, the data retrieved, and the final text answer.

**Note**: This tool requires additional setup in your project. Please refer to
the official [Conversational Analytics API
documentation](https://cloud.google.com/gemini/docs/conversational-analytics-api/overview)
for instructions.

It's compatible with the following sources:

- [bigquery](../../sources/bigquery.md)

`bigquery-conversational-analytics` accepts the following parameters:

- **`user_query_with_context`:** The user's question, potentially including
  conversation history and system instructions for context.
- **`table_references`:** A JSON string of a list of BigQuery tables to use as
  context. Each object in the list must contain `projectId`, `datasetId`, and
  `tableId`. Example: `'[{"projectId": "my-gcp-project", "datasetId": "my_dataset", "tableId": "my_table"}]'`

The tool's behavior regarding these parameters is influenced by the `allowedDatasets` 
restriction on the `bigquery` source:
- **Without `allowedDatasets` restriction:** The tool can use tables from any 
dataset specified in the `table_references` parameter.
- **With `allowedDatasets` restriction:** Before processing the request, the tool 
verifies that every table in `table_references` belongs to a dataset in the allowed 
list. If any table is from a dataset that is not in the list, the request is denied.

## Example

```yaml
tools:
  ask_data_insights:
    kind: bigquery-conversational-analytics
    source: my-bigquery-source
    description: |
      Use this tool to perform data analysis, get insights, or answer complex 
      questions about the contents of specific BigQuery tables.
```

## Reference

| **field**   | **type** | **required** | **description**                                    |
|-------------|:--------:|:------------:|----------------------------------------------------|
| kind        |  string  |     true     | Must be "bigquery-conversational-analytics".       |
| source      |  string  |     true     | Name of the source for chat.                       |
| description |  string  |     true     | Description of the tool that is passed to the LLM. |

```

--------------------------------------------------------------------------------
/internal/testutils/testutils.go:
--------------------------------------------------------------------------------

```go
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package testutils

import (
	"bufio"
	"context"
	"fmt"
	"io"
	"os"
	"regexp"
	"strings"

	"github.com/googleapis/genai-toolbox/internal/log"
	"github.com/googleapis/genai-toolbox/internal/util"
)

// formatYaml is a utility function for stripping out tabs in multiline strings
func FormatYaml(in string) []byte {
	// removes any leading indentation(tabs)
	in = strings.ReplaceAll(in, "\n\t", "\n ")
	// converts remaining indentation
	in = strings.ReplaceAll(in, "\t", "  ")
	return []byte(in)
}

// ContextWithNewLogger create a new context with new logger
func ContextWithNewLogger() (context.Context, error) {
	ctx := context.Background()
	logger, err := log.NewStdLogger(os.Stdout, os.Stderr, "info")
	if err != nil {
		return nil, fmt.Errorf("unable to create logger: %s", err)
	}
	return util.WithLogger(ctx, logger), nil
}

// WaitForString waits until the server logs a single line that matches the provided regex.
// returns the output of whatever the server sent so far.
func WaitForString(ctx context.Context, re *regexp.Regexp, pr io.ReadCloser) (string, error) {
	in := bufio.NewReader(pr)
	ctx, cancel := context.WithCancel(ctx)
	defer cancel()

	// read lines in background, sending result of each read over a channel
	// this allows us to use in.ReadString without blocking
	type result struct {
		s   string
		err error
	}
	output := make(chan result)
	go func() {
		defer close(output)
		for {
			select {
			case <-ctx.Done():
				// if the context is canceled, the orig thread will send back the error
				// so we can just exit the goroutine here
				return
			default:
				// otherwise read a line from the output
				s, err := in.ReadString('\n')
				if err != nil {
					output <- result{err: err}
					return
				}
				output <- result{s: s}
				// if that last string matched, exit the goroutine
				if re.MatchString(s) {
					return
				}
			}
		}
	}()

	// collect the output until the ctx is canceled, an error was hit,
	// or match was found (which is indicated the channel is closed)
	var sb strings.Builder
	for {
		select {
		case <-ctx.Done():
			// if ctx is done, return that error
			return sb.String(), ctx.Err()
		case o, ok := <-output:
			if !ok {
				// match was found!
				return sb.String(), nil
			}
			if o.err != nil {
				// error was found!
				return sb.String(), o.err
			}
			sb.WriteString(o.s)
		}
	}
}

```

--------------------------------------------------------------------------------
/internal/sources/mongodb/mongodb.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package mongodb

import (
	"context"
	"fmt"

	"github.com/goccy/go-yaml"
	"github.com/googleapis/genai-toolbox/internal/sources"
	"github.com/googleapis/genai-toolbox/internal/util"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go.opentelemetry.io/otel/trace"
)

const SourceKind string = "mongodb"

// validate interface
var _ sources.SourceConfig = Config{}

func init() {
	if !sources.Register(SourceKind, newConfig) {
		panic(fmt.Sprintf("source kind %q already registered", SourceKind))
	}
}

func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources.SourceConfig, error) {
	actual := Config{Name: name}
	if err := decoder.DecodeContext(ctx, &actual); err != nil {
		return nil, err
	}
	return actual, nil
}

type Config struct {
	Name string `yaml:"name" validate:"required"`
	Kind string `yaml:"kind" validate:"required"`
	Uri  string `yaml:"uri" validate:"required"` // MongoDB Atlas connection URI
}

func (r Config) SourceConfigKind() string {
	return SourceKind
}

func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) {
	client, err := initMongoDBClient(ctx, tracer, r.Name, r.Uri)
	if err != nil {
		return nil, fmt.Errorf("unable to create MongoDB client: %w", err)
	}

	// Verify the connection
	err = client.Ping(ctx, nil)
	if err != nil {
		return nil, fmt.Errorf("unable to connect successfully: %w", err)
	}

	s := &Source{
		Name:   r.Name,
		Kind:   SourceKind,
		Client: client,
	}
	return s, nil
}

var _ sources.Source = &Source{}

type Source struct {
	Name   string `yaml:"name"`
	Kind   string `yaml:"kind"`
	Client *mongo.Client
}

func (s *Source) SourceKind() string {
	return SourceKind
}

func (s *Source) MongoClient() *mongo.Client {
	return s.Client
}

func initMongoDBClient(ctx context.Context, tracer trace.Tracer, name, uri string) (*mongo.Client, error) {
	// Start a tracing span
	ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name)
	defer span.End()

	userAgent, err := util.UserAgentFromContext(ctx)
	if err != nil {
		return nil, err
	}

	// Create a new MongoDB client
	clientOpts := options.Client().ApplyURI(uri).SetAppName(userAgent)
	client, err := mongo.Connect(ctx, clientOpts)
	if err != nil {
		return nil, fmt.Errorf("unable to create MongoDB client: %w", err)
	}

	return client, nil
}

```

--------------------------------------------------------------------------------
/internal/tools/tools_test.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package tools_test

import (
	"testing"

	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/genai-toolbox/internal/tools"
)

func TestGetMcpManifestMetadata(t *testing.T) {
	authServices := []tools.ParamAuthService{
		{
			Name:  "my-google-auth-service",
			Field: "auth_field",
		},
		{
			Name:  "other-auth-service",
			Field: "other_auth_field",
		}}
	tcs := []struct {
		desc         string
		name         string
		description  string
		authInvoke   []string
		params       tools.Parameters
		wantMetadata map[string]any
	}{
		{
			desc:         "basic manifest without metadata",
			name:         "basic",
			description:  "foo bar",
			authInvoke:   []string{},
			params:       tools.Parameters{tools.NewStringParameter("string-param", "string parameter")},
			wantMetadata: nil,
		},
		{
			desc:         "with auth invoke metadata",
			name:         "basic",
			description:  "foo bar",
			authInvoke:   []string{"auth1", "auth2"},
			params:       tools.Parameters{tools.NewStringParameter("string-param", "string parameter")},
			wantMetadata: map[string]any{"toolbox/authInvoke": []string{"auth1", "auth2"}},
		},
		{
			desc:        "with auth param metadata",
			name:        "basic",
			description: "foo bar",
			authInvoke:  []string{},
			params:      tools.Parameters{tools.NewStringParameterWithAuth("string-param", "string parameter", authServices)},
			wantMetadata: map[string]any{
				"toolbox/authParam": map[string][]string{
					"string-param": []string{"my-google-auth-service", "other-auth-service"},
				},
			},
		},
		{
			desc:        "with auth invoke and auth param metadata",
			name:        "basic",
			description: "foo bar",
			authInvoke:  []string{"auth1", "auth2"},
			params:      tools.Parameters{tools.NewStringParameterWithAuth("string-param", "string parameter", authServices)},
			wantMetadata: map[string]any{
				"toolbox/authInvoke": []string{"auth1", "auth2"},
				"toolbox/authParam": map[string][]string{
					"string-param": []string{"my-google-auth-service", "other-auth-service"},
				},
			},
		},
	}
	for _, tc := range tcs {
		t.Run(tc.name, func(t *testing.T) {
			got := tools.GetMcpManifest(tc.name, tc.description, tc.authInvoke, tc.params)
			gotM := got.Metadata
			if diff := cmp.Diff(tc.wantMetadata, gotM); diff != "" {
				t.Fatalf("unexpected metadata (-want +got):\n%s", diff)
			}
		})
	}
}

```

--------------------------------------------------------------------------------
/internal/tools/looker/lookerhealthpulse/lookerhealthpulse_test.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package lookerhealthpulse_test

import (
	"strings"
	"testing"

	yaml "github.com/goccy/go-yaml"
	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/genai-toolbox/internal/server"
	"github.com/googleapis/genai-toolbox/internal/testutils"
	lhp "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerhealthpulse"
)

func TestParseFromYamlLookerHealthPulse(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		want server.ToolConfigs
	}{
		{
			desc: "basic example",
			in: `
			tools:
				example_tool:
					kind: looker-health-pulse
					source: my-instance
					description: some description
			`,
			want: server.ToolConfigs{
				"example_tool": lhp.Config{
					Name:         "example_tool",
					Kind:         "looker-health-pulse",
					Source:       "my-instance",
					Description:  "some description",
					AuthRequired: []string{},
				},
			},
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			// Parse contents
			err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err != nil {
				t.Fatalf("unable to unmarshal: %s", err)
			}
			if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
				t.Fatalf("incorrect parse: diff %v", diff)
			}
		})
	}
}

func TestFailParseFromYamlLookerHealthPulse(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		err  string
	}{
		{
			desc: "Invalid field",
			in: `
			tools:
				example_tool:
					kind: looker-health-pulse
					source: my-instance
					invalid_field: true
			`,
			err: "unable to parse tool \"example_tool\" as kind \"looker-health-pulse\": [2:1] unknown field \"invalid_field\"",
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			// Parse contents
			err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err == nil {
				t.Fatalf("expect parsing to fail")
			}
			errStr := err.Error()
			if !strings.Contains(errStr, tc.err) {
				t.Fatalf("unexpected error string: got %q, want substring %q", errStr, tc.err)
			}
		})
	}
}

```

--------------------------------------------------------------------------------
/internal/tools/looker/lookerhealthvacuum/lookerhealthvacuum_test.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package lookerhealthvacuum_test

import (
	"strings"
	"testing"

	yaml "github.com/goccy/go-yaml"
	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/genai-toolbox/internal/server"
	"github.com/googleapis/genai-toolbox/internal/testutils"
	lhv "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerhealthvacuum"
)

func TestParseFromYamlLookerHealthVacuum(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		want server.ToolConfigs
	}{
		{
			desc: "basic example",
			in: `
			tools:
				example_tool:
					kind: looker-health-vacuum
					source: my-instance
					description: some description
			`,
			want: server.ToolConfigs{
				"example_tool": lhv.Config{
					Name:         "example_tool",
					Kind:         "looker-health-vacuum",
					Source:       "my-instance",
					Description:  "some description",
					AuthRequired: []string{},
				},
			},
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			// Parse contents
			err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err != nil {
				t.Fatalf("unable to unmarshal: %s", err)
			}
			if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
				t.Fatalf("incorrect parse: diff %v", diff)
			}
		})
	}
}

func TestFailParseFromYamlLookerHealthVacuum(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		err  string
	}{
		{
			desc: "Invalid field",
			in: `
			tools:
				example_tool:
					kind: looker-health-vacuum
					source: my-instance
					invalid_field: true
			`,
			err: "unable to parse tool \"example_tool\" as kind \"looker-health-vacuum\": [2:1] unknown field \"invalid_field\"",
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			// Parse contents
			err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err == nil {
				t.Fatalf("expect parsing to fail")
			}
			errStr := err.Error()
			if !strings.Contains(errStr, tc.err) {
				t.Fatalf("unexpected error string: got %q, want substring %q", errStr, tc.err)
			}
		})
	}
}

```

--------------------------------------------------------------------------------
/internal/tools/spanner/spannerlisttables/spannerlisttables_test.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package spannerlisttables_test

import (
	"testing"

	yaml "github.com/goccy/go-yaml"
	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/genai-toolbox/internal/server"
	"github.com/googleapis/genai-toolbox/internal/testutils"
	"github.com/googleapis/genai-toolbox/internal/tools/spanner/spannerlisttables"
)

func TestParseFromYamlListTables(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		want server.ToolConfigs
	}{
		{
			desc: "basic example",
			in: `
			tools:
				example_tool:
					kind: spanner-list-tables
					source: my-spanner-instance
					description: Lists tables in the database
			`,
			want: server.ToolConfigs{
				"example_tool": spannerlisttables.Config{
					Name:         "example_tool",
					Kind:         "spanner-list-tables",
					Source:       "my-spanner-instance",
					Description:  "Lists tables in the database",
					AuthRequired: []string{},
				},
			},
		},
		{
			desc: "with auth required",
			in: `
			tools:
				example_tool:
					kind: spanner-list-tables
					source: my-spanner-instance
					description: Lists tables in the database
					authRequired:
						- auth1
						- auth2
			`,
			want: server.ToolConfigs{
				"example_tool": spannerlisttables.Config{
					Name:         "example_tool",
					Kind:         "spanner-list-tables",
					Source:       "my-spanner-instance",
					Description:  "Lists tables in the database",
					AuthRequired: []string{"auth1", "auth2"},
				},
			},
		},
		{
			desc: "minimal config",
			in: `
			tools:
				example_tool:
					kind: spanner-list-tables
					source: my-spanner-instance
			`,
			want: server.ToolConfigs{
				"example_tool": spannerlisttables.Config{
					Name:         "example_tool",
					Kind:         "spanner-list-tables",
					Source:       "my-spanner-instance",
					Description:  "",
					AuthRequired: []string{},
				},
			},
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			// Parse contents
			err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err != nil {
				t.Fatalf("unable to unmarshal: %s", err)
			}
			if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
				t.Fatalf("incorrect parse: diff %v", diff)
			}
		})
	}
}

```

--------------------------------------------------------------------------------
/internal/tools/looker/lookerhealthanalyze/lookerhealthanalyze_test.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package lookerhealthanalyze_test

import (
	"strings"
	"testing"

	yaml "github.com/goccy/go-yaml"
	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/genai-toolbox/internal/server"
	"github.com/googleapis/genai-toolbox/internal/testutils"
	lha "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerhealthanalyze"
)

func TestParseFromYamlLookerHealthAnalyze(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		want server.ToolConfigs
	}{
		{
			desc: "basic example",
			in: `
			tools:
				example_tool:
					kind: looker-health-analyze
					source: my-instance
					description: some description
			`,
			want: server.ToolConfigs{
				"example_tool": lha.Config{
					Name:         "example_tool",
					Kind:         "looker-health-analyze",
					Source:       "my-instance",
					Description:  "some description",
					AuthRequired: []string{},
				},
			},
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			// Parse contents
			err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err != nil {
				t.Fatalf("unable to unmarshal: %s", err)
			}
			if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
				t.Fatalf("incorrect parse: diff %v", diff)
			}
		})
	}
}

func TestFailParseFromYamlLookerHealthAnalyze(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		err  string
	}{
		{
			desc: "Invalid field",
			in: `
			tools:
				example_tool:
					kind: looker-health-analyze
					source: my-instance
					invalid_field: true
			`,
			err: "unable to parse tool \"example_tool\" as kind \"looker-health-analyze\": [2:1] unknown field \"invalid_field\"",
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			// Parse contents
			err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err == nil {
				t.Fatalf("expect parsing to fail")
			}
			errStr := err.Error()
			if !strings.Contains(errStr, tc.err) {
				t.Fatalf("unexpected error string: got %q, want substring %q", errStr, tc.err)
			}
		})
	}
}

```

--------------------------------------------------------------------------------
/.github/workflows/deploy_versioned_docs.yaml:
--------------------------------------------------------------------------------

```yaml
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: "Deploy Versioned Docs"

permissions:
  contents: write

on:
  release:
    types: [published]

jobs:
  deploy:
    runs-on: ubuntu-24.04
    # This shared concurrency group ensures only one docs deployment runs at a time.
    concurrency:
      group: docs-deployment
      cancel-in-progress: false
    steps:
      - name: Checkout Code at Tag
        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
        with:
          ref: ${{ github.event.release.tag_name }}

      - name: Get Version from Release Tag
        run: echo "VERSION=${{ github.event.release.tag_name }}" >> $GITHUB_ENV

      - name: Setup Hugo
        uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3
        with:
          hugo-version: "0.145.0"
          extended: true

      - name: Setup Node
        uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
        with:
          node-version: "22"

      - name: Install Dependencies
        run: npm ci
        working-directory: .hugo

      - name: Build Hugo Site
        run: hugo --minify
        working-directory: .hugo
        env:
          HUGO_BASEURL: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/${{ env.VERSION }}/
          HUGO_RELATIVEURLS: false

      - name: Deploy
        uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: .hugo/public
          publish_branch: versioned-gh-pages
          destination_dir: ./${{ env.VERSION }}
          keep_files: true
          commit_message: "deploy: docs for ${{ env.VERSION }}"

      - name: Clean Build Directory
        run: rm -rf .hugo/public

      - name: Build Hugo Site
        run: hugo --minify
        working-directory: .hugo
        env:
          HUGO_BASEURL: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/
          HUGO_RELATIVEURLS: false

      - name: Deploy to root
        uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: .hugo/public
          publish_branch: versioned-gh-pages
          keep_files: true
          allow_empty_commit: true
          commit_message: "deploy: docs to root for ${{ env.VERSION }}"

```

--------------------------------------------------------------------------------
/docs/en/resources/tools/alloydb/alloydb-wait-for-operation.md:
--------------------------------------------------------------------------------

```markdown
---
title: alloydb-wait-for-operation
type: docs
weight: 10
description: "Wait for a long-running AlloyDB operation to complete.\n"
---

The `alloydb-wait-for-operation` tool is a utility tool that waits for a
long-running AlloyDB operation to complete. It does this by polling the AlloyDB
Admin API operation status endpoint until the operation is finished, using
exponential backoff. It is compatible with
[alloydb-admin](../../sources/alloydb-admin.md) source.

| Parameter   | Type   | Description                                          | Required |
| :---------- | :----- | :--------------------------------------------------- | :------- |
| `project`   | string | The GCP project ID.                                  | Yes      |
| `location`  | string | The location of the operation (e.g., 'us-central1'). | Yes      |
| `operation` | string | The ID of the operation to wait for.                 | Yes      |

{{< notice info >}}
This tool is intended for developer assistant workflows with human-in-the-loop
and shouldn't be used for production agents.
{{< /notice >}}

## Example

```yaml
tools:
  wait_for_operation:
    kind: alloydb-wait-for-operation
    source: my-alloydb-admin-source
    description: "This will poll on operations API until the operation is done. For checking operation status we need projectId, locationID and operationId. Once instance is created give follow up steps on how to use the variables to bring data plane MCP server up in local and remote setup."
    delay: 1s
    maxDelay: 4m
    multiplier: 2
    maxRetries: 10
```

## Reference

| **field**   | **type** | **required** | **description**                                                                                                  |
| ----------- | :------: | :----------: | ---------------------------------------------------------------------------------------------------------------- |
| kind        |  string  |     true     | Must be "alloydb-wait-for-operation".                                                                            |
| source      |  string  |     true     | The name of a `alloydb-admin` source to use for authentication.                                                  |
| description |  string  |     false    | A description of the tool.                                                                                       |
| delay       | duration |     false    | The initial delay between polling requests (e.g., `3s`). Defaults to 3 seconds.                                  |
| maxDelay    | duration |     false    | The maximum delay between polling requests (e.g., `4m`). Defaults to 4 minutes.                                  |
| multiplier  |   float  |     false    | The multiplier for the polling delay. The delay is multiplied by this value after each request. Defaults to 2.0. |
| maxRetries  |    int   |     false    | The maximum number of polling attempts before giving up. Defaults to 10.                                         |

```

--------------------------------------------------------------------------------
/docs/en/resources/tools/bigquery/bigquery-search-catalog.md:
--------------------------------------------------------------------------------

```markdown
---
title: "bigquery-search-catalog"
type: docs
weight: 1
description: >
  A "bigquery-search-catalog" tool allows to search for entries based on the provided query.
---

## About

A `bigquery-search-catalog` tool returns all entries in Dataplex Catalog (e.g.
tables, views, models) with system=bigquery that matches given user query.
It's compatible with the following sources:

- [bigquery](../../sources/bigquery.md)

`bigquery-search-catalog` takes a required `query` parameter based on which
entries are filtered and returned to the user. It also optionally accepts
following parameters:

- `datasetIds` - The IDs of the bigquery dataset.
- `projectIds` - The IDs of the bigquery project.
- `types` - The type of the data. Accepted values are: CONNECTION, POLICY,
  DATASET, MODEL, ROUTINE, TABLE, VIEW.
- `pageSize` - Number of results in the search page. Defaults to `5`.

## Requirements

### IAM Permissions

Bigquery uses [Identity and Access Management (IAM)][iam-overview] to control
user and group access to Dataplex resources. Toolbox will use your
[Application Default Credentials (ADC)][adc] to authorize and authenticate when
interacting with [Dataplex][dataplex-docs].

In addition to [setting the ADC for your server][set-adc], you need to ensure
the IAM identity has been given the correct IAM permissions for the tasks you
intend to perform. See [Dataplex Universal Catalog IAM permissions][iam-permissions]
and [Dataplex Universal Catalog IAM roles][iam-roles] for more information on
applying IAM permissions and roles to an identity.

[iam-overview]: https://cloud.google.com/dataplex/docs/iam-and-access-control
[adc]: https://cloud.google.com/docs/authentication#adc
[set-adc]: https://cloud.google.com/docs/authentication/provide-credentials-adc
[iam-permissions]: https://cloud.google.com/dataplex/docs/iam-permissions
[iam-roles]: https://cloud.google.com/dataplex/docs/iam-roles

## Example

```yaml
tools:
  search_catalog:
    kind: bigquery-search-catalog
    source: bigquery-source
    description: Use this tool to find tables, views, models, routines or connections.
```

## Reference

| **field**   |                  **type**                  | **required** | **description**                                                                                  |
|-------------|:------------------------------------------:|:------------:|--------------------------------------------------------------------------------------------------|
| kind        |                   string                   |     true     | Must be "bigquery-search-catalog".                                                               |
| source      |                   string                   |     true     | Name of the source the tool should execute on.                                                   |
| description |                   string                   |     true     | Description of the tool that is passed to the LLM.                                               |

```

--------------------------------------------------------------------------------
/.ci/quickstart_test/run_go_tests.sh:
--------------------------------------------------------------------------------

```bash
# Copyright 2025 Google LLC
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
#      http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#!/bin/bash

set -e

TABLE_NAME="hotels_go"
QUICKSTART_GO_DIR="docs/en/getting-started/quickstart/go"
SQL_FILE=".ci/quickstart_test/setup_hotels_sample.sql"

PROXY_PID=""
TOOLBOX_PID=""

install_system_packages() {
  apt-get update && apt-get install -y \
    postgresql-client \
    wget \
    gettext-base  \
    netcat-openbsd
}

start_cloud_sql_proxy() {
  wget "https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.10.0/cloud-sql-proxy.linux.amd64" -O /usr/local/bin/cloud-sql-proxy
  chmod +x /usr/local/bin/cloud-sql-proxy
  cloud-sql-proxy "${CLOUD_SQL_INSTANCE}" &
  PROXY_PID=$!

  for i in {1..30}; do
    if nc -z 127.0.0.1 5432; then
      echo "Cloud SQL Proxy is up and running."
      return
    fi
    sleep 1
  done

  echo "Cloud SQL Proxy failed to start within the timeout period."
  exit 1
}

setup_toolbox() {
  TOOLBOX_YAML="/tools.yaml"
  echo "${TOOLS_YAML_CONTENT}" > "$TOOLBOX_YAML"
  if [ ! -f "$TOOLBOX_YAML" ]; then echo "Failed to create tools.yaml"; exit 1; fi
  wget "https://storage.googleapis.com/genai-toolbox/v${VERSION}/linux/amd64/toolbox" -O "/toolbox"
  chmod +x "/toolbox"
  /toolbox --tools-file "$TOOLBOX_YAML" &
  TOOLBOX_PID=$!
  sleep 2
}

setup_orch_table() {
  export TABLE_NAME
  envsubst < "$SQL_FILE" | psql -h "$PGHOST" -p "$PGPORT" -U "$DB_USER" -d "$DATABASE_NAME"
}

run_orch_test() {
  local orch_dir="$1"
  local orch_name
  orch_name=$(basename "$orch_dir")
  
  if [ "$orch_name" == "openAI" ]; then
      echo -e "\nSkipping framework '${orch_name}': Temporarily excluded."
      return
  fi
  
  (
    set -e
    setup_orch_table

    echo "--- Preparing module for $orch_name ---"
    cd "$orch_dir"

    if [ -f "go.mod" ]; then
      go mod tidy
    fi

    cd ..

    export ORCH_NAME="$orch_name"

    echo "--- Running tests for $orch_name ---"
    go test -v ./...
  )
}

cleanup_all() {
  echo "--- Final cleanup: Shutting down processes and dropping table ---"
  if [ -n "$TOOLBOX_PID" ]; then
    kill $TOOLBOX_PID || true
  fi
  if [ -n "$PROXY_PID" ]; then
    kill $PROXY_PID || true
  fi
}
trap cleanup_all EXIT

# Main script execution
install_system_packages
start_cloud_sql_proxy

export PGHOST=127.0.0.1
export PGPORT=5432
export PGPASSWORD="$DB_PASSWORD"
export GOOGLE_API_KEY="$GOOGLE_API_KEY"

setup_toolbox

for ORCH_DIR in "$QUICKSTART_GO_DIR"/*/; do
  if [ ! -d "$ORCH_DIR" ]; then
    continue
  fi
  run_orch_test "$ORCH_DIR"
done

```

--------------------------------------------------------------------------------
/docs/en/how-to/export_telemetry.md:
--------------------------------------------------------------------------------

```markdown
---
title: "Export Telemetry"
type: docs
weight: 5
description: >
  How to set up and configure Toolbox to use the Otel Collector.
---


## About

The [OpenTelemetry Collector][about-collector] offers a vendor-agnostic
implementation of how to receive, process and export telemetry data. It removes
the need to run, operate, and maintain multiple agents/collectors.

[about-collector]: https://opentelemetry.io/docs/collector/

## Configure the Collector

To configure the collector, you will have to provide a configuration file. The
configuration file consists of four classes of pipeline component that access
telemetry data.

- `Receivers`
- `Processors`
- `Exporters`
- `Connectors`

Example of setting up the classes of pipeline components (in this example, we
don't use connectors):

```yaml
receivers:
  otlp:
    protocols:
      http:
        endpoint: "127.0.0.1:4553"

exporters:
  googlecloud:
    project: <YOUR_GOOGLE_CLOUD_PROJECT>

processors:
  batch:
    send_batch_size: 200
```

After each pipeline component is configured, you will enable it within the
`service` section of the configuration file.

```yaml
service:
  pipelines:
    traces:
      receivers: ["otlp"]
      processors: ["batch"]
      exporters: ["googlecloud"]
```

## Running the Collector

There are a couple of steps to run and use a Collector.

1. [Install the
   Collector](https://opentelemetry.io/docs/collector/installation/) binary.
   Pull a binary or Docker image for the OpenTelemetry contrib collector.

1. Set up credentials for telemetry backend.

1. Set up the Collector config. Below are some examples for setting up the
   Collector config:
    - [Google Cloud Exporter][google-cloud-exporter]
    - [Google Managed Service for Prometheus Exporter][google-prometheus-exporter]

1. Run the Collector with the configuration file.

    ```bash
    ./otelcol-contrib --config=collector-config.yaml
    ```

1. Run toolbox with the `--telemetry-otlp` flag. Configure it to send them to
   `http://127.0.0.1:4553` (for HTTP) or the Collector's URL.

    ```bash
    ./toolbox --telemetry-otlp=http://127.0.0.1:4553
    ```

1. Once telemetry datas are collected, you can view them in your telemetry
   backend. If you are using GCP exporters, telemetry will be visible in GCP
   dashboard at [Metrics Explorer][metrics-explorer] and [Trace
   Explorer][trace-explorer].

  {{< notice note >}}
  If you are exporting to Google Cloud monitoring, we recommend that you use
  the Google Cloud Exporter for traces and the Google Managed Service for
  Prometheus Exporter for metrics.
  {{< /notice >}}

[google-cloud-exporter]:
    https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/googlecloudexporter
[google-prometheus-exporter]:
    https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/googlemanagedprometheusexporter#example-configuration
[metrics-explorer]: https://console.cloud.google.com/monitoring/metrics-explorer
[trace-explorer]: https://console.cloud.google.com/traces

```

--------------------------------------------------------------------------------
/docs/en/getting-started/quickstart/js/genkit/quickstart.js:
--------------------------------------------------------------------------------

```javascript
import { ToolboxClient } from "@toolbox-sdk/core";
import { genkit } from "genkit";
import { googleAI } from '@genkit-ai/googleai';

const GOOGLE_API_KEY = process.env.GOOGLE_API_KEY || 'your-api-key'; // Replace it with your API key

const systemPrompt = `
You're a helpful hotel assistant. You handle hotel searching, booking, and
cancellations. When the user searches for a hotel, mention its name, id,
location and price tier. Always mention hotel ids while performing any
searches. This is very important for any operations. For any bookings or
cancellations, please provide the appropriate confirmation. Be sure to
update checkin or checkout dates if mentioned by the user.
Don't ask for confirmations from the user.
`;

const queries = [
  "Find hotels in Basel with Basel in its name.",
  "Can you book the Hilton Basel for me?",
  "Oh wait, this is too expensive. Please cancel it and book the Hyatt Regency instead.",
  "My check in dates would be from April 10, 2024 to April 19, 2024.",
];

export async function main() {
  const toolboxClient = new ToolboxClient("http://127.0.0.1:5000");

  const ai = genkit({
    plugins: [
      googleAI({
        apiKey: process.env.GEMINI_API_KEY || GOOGLE_API_KEY
      })
    ],
    model: googleAI.model('gemini-2.0-flash'),
  });

  const toolboxTools = await toolboxClient.loadToolset("my-toolset");
  const toolMap = Object.fromEntries(
    toolboxTools.map((tool) => {
      const definedTool = ai.defineTool(
        {
          name: tool.getName(),
          description: tool.getDescription(),
          inputSchema: tool.getParamSchema(),
        },
        tool
      );
      return [tool.getName(), definedTool];
    })
  );
  const tools = Object.values(toolMap);

  let conversationHistory = [{ role: "system", content: [{ text: systemPrompt }] }];

  for (const query of queries) {
    conversationHistory.push({ role: "user", content: [{ text: query }] });
    const response = await ai.generate({
      messages: conversationHistory,
      tools: tools,
    });
    conversationHistory.push(response.message);

    const toolRequests = response.toolRequests;
    if (toolRequests?.length > 0) {
      // Execute tools concurrently and collect their responses.
      const toolResponses = await Promise.all(
        toolRequests.map(async (call) => {
          try {
            const toolOutput = await toolMap[call.name].invoke(call.input);
            return { role: "tool", content: [{ toolResponse: { name: call.name, output: toolOutput } }] };
          } catch (e) {
            console.error(`Error executing tool ${call.name}:`, e);
            return { role: "tool", content: [{ toolResponse: { name: call.name, output: { error: e.message } } }] };
          }
        })
      );

      conversationHistory.push(...toolResponses);

      // Call the AI again with the tool results.
      response = await ai.generate({ messages: conversationHistory, tools });
      conversationHistory.push(response.message);
    }

    console.log(response.text);
  }
}

main();

```

--------------------------------------------------------------------------------
/docs/en/resources/tools/alloydb/alloydb-create-cluster.md:
--------------------------------------------------------------------------------

```markdown
---
title: alloydb-create-cluster
type: docs
weight: 1
description: "The \"alloydb-create-cluster\" tool creates a new AlloyDB for PostgreSQL cluster in a specified project and location.\n"
aliases: [/resources/tools/alloydb-create-cluster]
---

## About

The `alloydb-create-cluster` tool creates a new AlloyDB for PostgreSQL cluster in a specified project and location. It is compatible with [alloydb-admin](../../sources/alloydb-admin.md) source.
This tool provisions a cluster with a **private IP address** within the specified VPC network.

  **Permissions & APIs Required:**
  Before using, ensure the following on your GCP project:

1. The [AlloyDB API](https://console.cloud.google.com/apis/library/alloydb.googleapis.com) is enabled.
2. The user or service account executing the tool has one of the following IAM roles:

    - `roles/alloydb.admin` (the AlloyDB Admin predefined IAM role)
    - `roles/owner` (the Owner basic IAM role)
    - `roles/editor` (the Editor basic IAM role)

The tool takes the following input parameters:

| Parameter  | Type   | Description                                                                                                               | Required |
| :--------- | :----- | :------------------------------------------------------------------------------------------------------------------------ | :------- |
| `project`  | string | The GCP project ID where the cluster will be created.                                                                     | Yes      |
| `cluster`  | string | A unique identifier for the new AlloyDB cluster.                                                                          | Yes      |
| `password` | string | A secure password for the initial user.                                                                                   | Yes      |
| `location` | string | The GCP location where the cluster will be created. Default: `us-central1`. If quota is exhausted then use other regions. | No       |
| `network`  | string | The name of the VPC network to connect the cluster to. Default: `default`.                                                | No       |
| `user`     | string | The name for the initial superuser. Default: `postgres`.                                                                  | No       |

## Example

```yaml
tools:
  create_cluster:
    kind: alloydb-create-cluster
    source: alloydb-admin-source
    description: Use this tool to create a new AlloyDB cluster in a given project and location.
```

## Reference

| **field**   | **type** | **required** | **description**                                      |   |
| ----------- | :------: | :----------: | ---------------------------------------------------- | - |
| kind        |  string  |     true     | Must be alloydb-create-cluster.                      |   |
| source      |  string  |     true     | The name of an `alloydb-admin` source.               |   |
| description |  string  |     false    | Description of the tool that is passed to the agent. |   |

```

--------------------------------------------------------------------------------
/docs/en/resources/tools/dataplex/dataplex-lookup-entry.md:
--------------------------------------------------------------------------------

```markdown
---
title: "dataplex-lookup-entry"
type: docs
weight: 1
description: > 
  A "dataplex-lookup-entry" tool returns details of a particular entry in Dataplex Catalog.
aliases:
- /resources/tools/dataplex-lookup-entry
---

## About

A `dataplex-lookup-entry` tool returns details of a particular entry in Dataplex
Catalog. It's compatible with the following sources:

- [dataplex](../sources/dataplex.md)

`dataplex-lookup-entry` takes a required `name` parameter which contains the
project and location to which the request should be attributed in the following
form: projects/{project}/locations/{location} and also a required `entry`
parameter which is the resource name of the entry in the following form:
projects/{project}/locations/{location}/entryGroups/{entryGroup}/entries/{entry}.
It also optionally accepts following parameters:

- `view` - View to control which parts of an entry the service should return.
    It takes integer values from 1-4 corresponding to type of view - BASIC,
    FULL, CUSTOM, ALL
- `aspectTypes` - Limits the aspects returned to the provided aspect types in
    the format
    `projects/{project}/locations/{location}/aspectTypes/{aspectType}`. It only
    works for CUSTOM view.
- `paths` - Limits the aspects returned to those associated with the provided
    paths within the Entry. It only works for CUSTOM view.

## Requirements

### IAM Permissions

Dataplex uses [Identity and Access Management (IAM)][iam-overview] to control
user and group access to Dataplex resources. Toolbox will use your
[Application Default Credentials (ADC)][adc] to authorize and authenticate when
interacting with [Dataplex][dataplex-docs].

In addition to [setting the ADC for your server][set-adc], you need to ensure
the IAM identity has been given the correct IAM permissions for the tasks you
intend to perform. See [Dataplex Universal Catalog IAM permissions][iam-permissions]
and [Dataplex Universal Catalog IAM roles][iam-roles] for more information on
applying IAM permissions and roles to an identity.

[iam-overview]: https://cloud.google.com/dataplex/docs/iam-and-access-control
[adc]: https://cloud.google.com/docs/authentication#adc
[set-adc]: https://cloud.google.com/docs/authentication/provide-credentials-adc
[iam-permissions]: https://cloud.google.com/dataplex/docs/iam-permissions
[iam-roles]: https://cloud.google.com/dataplex/docs/iam-roles

## Example

```yaml
tools:
  lookup_entry:
    kind: dataplex-lookup-entry
    source: my-dataplex-source
    description: Use this tool to retrieve a specific entry in Dataplex Catalog.
```

## Reference

| **field**   | **type** | **required** | **description**                                    |
|-------------|:--------:|:------------:|----------------------------------------------------|
| kind        |  string  |     true     | Must be "dataplex-lookup-entry".                   |
| source      |  string  |     true     | Name of the source the tool should execute on.     |
| description |  string  |     true     | Description of the tool that is passed to the LLM. |

```

--------------------------------------------------------------------------------
/docs/en/resources/tools/alloydb/alloydb-create-user.md:
--------------------------------------------------------------------------------

```markdown
---
title: alloydb-create-user
type: docs
weight: 2
description: "The \"alloydb-create-user\" tool creates a new database user within a specified AlloyDB cluster.\n"
aliases: [/resources/tools/alloydb-create-user]
---

## About

The `alloydb-create-user` tool creates a new database user (`ALLOYDB_BUILT_IN`
or `ALLOYDB_IAM_USER`) within a specified cluster. It is compatible with
[alloydb-admin](../../sources/alloydb-admin.md) source.

**Permissions & APIs Required:**
Before using, ensure the following on your GCP project:

1. The [AlloyDB
    API](https://console.cloud.google.com/apis/library/alloydb.googleapis.com)
    is enabled.
2. The user or service account executing the tool has one of the following IAM
    roles:
    - `roles/alloydb.admin` (the AlloyDB Admin predefined IAM role)
    - `roles/owner` (the Owner basic IAM role)
    - `roles/editor` (the Editor basic IAM role)

The tool takes the following input parameters:

| Parameter       | Type          | Description                                                                                                   | Required |
| :-------------- | :------------ | :------------------------------------------------------------------------------------------------------------ | :------- |
| `project`       | string        | The GCP project ID where the cluster exists.                                                                  | Yes      |
| `cluster`       | string        | The ID of the existing cluster where the user will be created.                                                | Yes      |
| `location`      | string        | The GCP location where the cluster exists (e.g., `us-central1`).                                              | Yes      |
| `user`          | string        | The name for the new user. Must be unique within the cluster.                                                 | Yes      |
| `userType`      | string        | The type of user. Valid values: `ALLOYDB_BUILT_IN` and `ALLOYDB_IAM_USER`. `ALLOYDB_IAM_USER` is recommended. | Yes      |
| `password`      | string        | A secure password for the user. Required only if `userType` is `ALLOYDB_BUILT_IN`.                            | No       |
| `databaseRoles` | array(string) | Optional. A list of database roles to grant to the new user (e.g., `pg_read_all_data`).                       | No       |

## Example

```yaml
tools:
  create_user:
    kind: alloydb-create-user
    source: alloydb-admin-source
    description: Use this tool to create a new database user for an AlloyDB cluster.
```

## Reference

| **field**   | **type** | **required** | **description**                                      |
| ----------- | :------: | :----------: | ---------------------------------------------------- |
| kind        |  string  |     true     | Must be alloydb-create-user.                         |
| source      |  string  |     true     | The name of an `alloydb-admin` source.               |
| description |  string  |     false    | Description of the tool that is passed to the agent. |

```

--------------------------------------------------------------------------------
/internal/tools/looker/lookerquery/lookerquery_test.go:
--------------------------------------------------------------------------------

```go
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package lookerquery_test

import (
	"strings"
	"testing"

	yaml "github.com/goccy/go-yaml"
	"github.com/google/go-cmp/cmp"
	"github.com/googleapis/genai-toolbox/internal/server"
	"github.com/googleapis/genai-toolbox/internal/testutils"
	lkr "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerquery"
)

func TestParseFromYamlLookerQuery(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		want server.ToolConfigs
	}{
		{
			desc: "basic example",
			in: `
			tools:
				example_tool:
					kind: looker-query
					source: my-instance
					description: some description
				`,
			want: server.ToolConfigs{
				"example_tool": lkr.Config{
					Name:         "example_tool",
					Kind:         "looker-query",
					Source:       "my-instance",
					Description:  "some description",
					AuthRequired: []string{},
				},
			},
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			// Parse contents
			err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err != nil {
				t.Fatalf("unable to unmarshal: %s", err)
			}
			if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
				t.Fatalf("incorrect parse: diff %v", diff)
			}
		})
	}

}

func TestFailParseFromYamlLookerQuery(t *testing.T) {
	ctx, err := testutils.ContextWithNewLogger()
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	tcs := []struct {
		desc string
		in   string
		err  string
	}{
		{
			desc: "Invalid method",
			in: `
			tools:
				example_tool:
					kind: looker-query
					source: my-instance
					method: GOT
					description: some description
			`,
			err: "unable to parse tool \"example_tool\" as kind \"looker-query\": [4:1] unknown field \"method\"\n   1 | authRequired: []\n   2 | description: some description\n   3 | kind: looker-query\n>  4 | method: GOT\n       ^\n   5 | source: my-instance",
		},
	}
	for _, tc := range tcs {
		t.Run(tc.desc, func(t *testing.T) {
			got := struct {
				Tools server.ToolConfigs `yaml:"tools"`
			}{}
			// Parse contents
			err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
			if err == nil {
				t.Fatalf("expect parsing to fail")
			}
			errStr := err.Error()
			if !strings.Contains(errStr, tc.err) {
				t.Fatalf("unexpected error string: got %q, want substring %q", errStr, tc.err)
			}
		})
	}

}

```
Page 4/33FirstPrevNextLast