chore: import upstream snapshot with attribution
CF: Deploy Dev Docs / deploy (push) Has been cancelled
Sync Labels / build (push) Has been cancelled
tests / unit tests (macos-latest) (push) Has been cancelled
tests / unit tests (windows-latest) (push) Has been cancelled
tests / unit tests (ubuntu-latest) (push) Has been cancelled
CF: Deploy Dev Docs / deploy (push) Has been cancelled
Sync Labels / build (push) Has been cancelled
tests / unit tests (macos-latest) (push) Has been cancelled
tests / unit tests (windows-latest) (push) Has been cancelled
tests / unit tests (ubuntu-latest) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: "Samples"
|
||||
weight: 3
|
||||
---
|
||||
|
||||
@@ -0,0 +1,847 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "qDHHyJsZdFFp"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Copyright 2025 Google LLC\n",
|
||||
"#\n",
|
||||
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
|
||||
"# you may not use this file except in compliance with the License.\n",
|
||||
"# You may obtain a copy of the License at\n",
|
||||
"#\n",
|
||||
"# https://www.apache.org/licenses/LICENSE-2.0\n",
|
||||
"#\n",
|
||||
"# Unless required by applicable law or agreed to in writing, software\n",
|
||||
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
|
||||
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
|
||||
"# See the License for the specific language governing permissions and\n",
|
||||
"# limitations under the License."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "THTB3L8TxZ1Q"
|
||||
},
|
||||
"source": [
|
||||
"# Getting Started With MCP Toolbox\n",
|
||||
"\n",
|
||||
"This guide demonstrates how to quickly run\n",
|
||||
"[Toolbox](https://github.com/googleapis/mcp-toolbox) end-to-end in Google\n",
|
||||
"Colab using Python, BigQuery, and either [Google\n",
|
||||
"GenAI](https://pypi.org/project/google-genai/), [ADK](https://google.github.io/adk-docs/),\n",
|
||||
"[Langgraph](https://www.langchain.com/langgraph)\n",
|
||||
"or [LlamaIndex](https://www.llamaindex.ai/).\n",
|
||||
"\n",
|
||||
"Within this Colab environment, you'll\n",
|
||||
"- Set up a `BigQuery Dataset`.\n",
|
||||
"- Launch a Toolbox server.\n",
|
||||
"- Connect to Toolbox and develop a sample `Hotel Booking` application."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "KLQzss0WxeI1"
|
||||
},
|
||||
"source": [
|
||||
"## Step 1: Set up your dataset\n",
|
||||
"\n",
|
||||
"In this section, we will\n",
|
||||
"1. Create a dataset in your bigquery project.\n",
|
||||
"1. Insert example data into the dataset."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "zTtKdvbwAag3"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# @markdown Please fill in the value below and then run the cell.\n",
|
||||
"BIGQUERY_PROJECT = \"\" # @param {type:\"string\"}\n",
|
||||
"DATASET = \"toolbox_ds\" # @param {type:\"string\"}\n",
|
||||
"TABLE_ID = \"hotels\" # @param {type:\"string\"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "bDaRyfx3PhXM"
|
||||
},
|
||||
"source": [
|
||||
"> You need to authenticate as an IAM user so this notebook can access your Google Cloud Project. This access is necessary to use Google's LLM models."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "c1_GR5NwPhXM"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from google.colab import auth\n",
|
||||
"\n",
|
||||
"# Authenticate the user for Google Cloud access\n",
|
||||
"auth.authenticate_user()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "2eNdr9LYyhuV",
|
||||
"outputId": "4ded8803-5b9c-4a26-af03-28a6f23a415e"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Create the dataset if it does not exist\n",
|
||||
"from google.cloud import bigquery\n",
|
||||
"from google.cloud import exceptions\n",
|
||||
"\n",
|
||||
"bqclient = bigquery.Client(project=BIGQUERY_PROJECT)\n",
|
||||
"dataset_ref = bqclient.dataset(DATASET)\n",
|
||||
"\n",
|
||||
"# Check if the dataset already exists\n",
|
||||
"try:\n",
|
||||
" bqclient.get_dataset(dataset_ref)\n",
|
||||
" print(f\"Dataset {DATASET} already exists. Skipping creation.\")\n",
|
||||
"except exceptions.NotFound:\n",
|
||||
" # If a google.cloud.exceptions.NotFound error is raised, the dataset does not exist.\n",
|
||||
" print(f\"Dataset {DATASET} not found. Creating dataset...\")\n",
|
||||
" dataset = bigquery.Dataset(dataset_ref)\n",
|
||||
" dataset = bqclient.create_dataset(dataset)\n",
|
||||
" print(f\"Dataset {DATASET} created successfully.\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 432
|
||||
},
|
||||
"id": "6t_nLJIHCRgy",
|
||||
"outputId": "11a5c025-288d-43e2-a823-454b0d88b1ce"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"table_ref = dataset_ref.table(TABLE_ID)\n",
|
||||
"\n",
|
||||
"schema = [\n",
|
||||
" bigquery.SchemaField(\"id\", \"INTEGER\", mode=\"REQUIRED\"),\n",
|
||||
" bigquery.SchemaField(\"name\", \"STRING\", mode=\"REQUIRED\"),\n",
|
||||
" bigquery.SchemaField(\"location\", \"STRING\", mode=\"REQUIRED\"),\n",
|
||||
" bigquery.SchemaField(\"price_tier\", \"STRING\", mode=\"REQUIRED\"),\n",
|
||||
" bigquery.SchemaField(\"checkin_date\", \"DATE\", mode=\"REQUIRED\"),\n",
|
||||
" bigquery.SchemaField(\"checkout_date\", \"DATE\", mode=\"REQUIRED\"),\n",
|
||||
" bigquery.SchemaField(\"booked\", \"BOOLEAN\", mode=\"REQUIRED\"),\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"# Check if the table already exists; if not, create it and insert data\n",
|
||||
"try:\n",
|
||||
" bqclient.get_table(table_ref)\n",
|
||||
" raise ValueError(f\"Table '{TABLE_ID}' already exists in dataset '{DATASET}'. Please delete it or use a different table name.\")\n",
|
||||
"except exceptions.NotFound:\n",
|
||||
" table = bigquery.Table(table_ref, schema=schema)\n",
|
||||
" table = bqclient.create_table(table)\n",
|
||||
" print(f\"Created table '{TABLE_ID}'.\")\n",
|
||||
"\n",
|
||||
" sql = f\"\"\"\n",
|
||||
" INSERT INTO `{BIGQUERY_PROJECT}.{DATASET}.{TABLE_ID}`(id, name, location, price_tier, checkin_date, checkout_date, booked)\n",
|
||||
" VALUES\n",
|
||||
" (1, 'Hilton Basel', 'Basel', 'Luxury', '2024-04-20', '2024-04-22', FALSE),\n",
|
||||
" (2, 'Marriott Zurich', 'Zurich', 'Upscale', '2024-04-14', '2024-04-21', FALSE),\n",
|
||||
" (3, 'Hyatt Regency Basel', 'Basel', 'Upper Upscale', '2024-04-02', '2024-04-20', FALSE),\n",
|
||||
" (4, 'Radisson Blu Lucerne', 'Lucerne', 'Midscale', '2024-04-05', '2024-04-24', FALSE),\n",
|
||||
" (5, 'Best Western Bern', 'Bern', 'Upper Midscale', '2024-04-01', '2024-04-23', FALSE),\n",
|
||||
" (6, 'InterContinental Geneva', 'Geneva', 'Luxury', '2024-04-23', '2024-04-28', FALSE),\n",
|
||||
" (7, 'Sheraton Zurich', 'Zurich', 'Upper Upscale', '2024-04-02', '2024-04-27', FALSE),\n",
|
||||
" (8, 'Holiday Inn Basel', 'Basel', 'Upper Midscale', '2024-04-09', '2024-04-24', FALSE),\n",
|
||||
" (9, 'Courtyard Zurich', 'Zurich', 'Upscale', '2024-04-03', '2024-04-13', FALSE),\n",
|
||||
" (10, 'Comfort Inn Bern', 'Bern', 'Midscale', '2024-04-04', '2024-04-16', FALSE);\n",
|
||||
" \"\"\"\n",
|
||||
" job = bqclient.query(sql)\n",
|
||||
" job.result()\n",
|
||||
" print(\"Data inserted into 'hotels' table.\")\n",
|
||||
"\n",
|
||||
"sql_select = f\"SELECT * FROM `{BIGQUERY_PROJECT}.{DATASET}.{TABLE_ID}`\"\n",
|
||||
"query_job = bqclient.query(sql_select)\n",
|
||||
"\n",
|
||||
"print(\"\\nTable Content:\")\n",
|
||||
"query_job.to_dataframe()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "EPuheP8DIt3p"
|
||||
},
|
||||
"source": [
|
||||
"## Step 2: Install and configure Toolbox\n",
|
||||
"\n",
|
||||
"In this section, we will\n",
|
||||
"1. Download the latest version of the toolbox binary.\n",
|
||||
"2. Create a toolbox config file.\n",
|
||||
"3. Start a toolbox server using the config file.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "Bl1IeaqZbMYh"
|
||||
},
|
||||
"source": [
|
||||
"Download the [latest](https://github.com/googleapis/mcp-toolbox/releases) version of Toolbox as a binary."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "lbsQ1Aa-IszB",
|
||||
"outputId": "07c57730-b285-4069-e6e1-97d128cdcda4"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"version = \"0.30.0\" # x-release-please-version\n",
|
||||
"! curl -O https://storage.googleapis.com/mcp-toolbox-for-databases/v{version}/linux/amd64/toolbox\n",
|
||||
"\n",
|
||||
"# Make the binary executable\n",
|
||||
"! chmod +x toolbox"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "Ovlzi2RVJGM5"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"TOOLBOX_BINARY_PATH = \"/content/toolbox\"\n",
|
||||
"SERVER_PORT = 5000"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "KNg7v_FeTYJu"
|
||||
},
|
||||
"source": [
|
||||
"Create a config with the following functions:\n",
|
||||
"\n",
|
||||
"- `Database Connection (sources)`: `Includes details for connecting to our hotels database.`\n",
|
||||
"- `Tool Definitions (tools)`: `Defines five tools for database interaction:`\n",
|
||||
" - `search-hotels-by-name`\n",
|
||||
" - `search-hotels-by-location`\n",
|
||||
" - `book-hotel`\n",
|
||||
" - `update-hotel`\n",
|
||||
" - `cancel-hotel`\n",
|
||||
"\n",
|
||||
"Our application will leverage these tools to interact with the hotels table.\n",
|
||||
"\n",
|
||||
"For detailed configuration options, please refer to the [Toolbox documentation](https://mcp-toolbox.dev/documentation/configuration/).\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "Jje8N5fScchw"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Create a config at runtime.\n",
|
||||
"# You can also upload a config and use that to run toolbox.\n",
|
||||
"tools_file_name = \"tools.yml\"\n",
|
||||
"file_content = f\"\"\"\n",
|
||||
"kind: source\n",
|
||||
"name: my-bigquery-source\n",
|
||||
"type: bigquery\n",
|
||||
"project: {BIGQUERY_PROJECT}\n",
|
||||
"---\n",
|
||||
"kind: tool\n",
|
||||
"name: search-hotels-by-name\n",
|
||||
"type: bigquery-sql\n",
|
||||
"source: my-bigquery-source\n",
|
||||
"description: Search for hotels based on name.\n",
|
||||
"parameters:\n",
|
||||
" - name: name\n",
|
||||
" type: string\n",
|
||||
" description: The name of the hotel.\n",
|
||||
"statement: SELECT * FROM `{DATASET}.{TABLE_ID}` WHERE LOWER(name) LIKE LOWER(CONCAT('%', @name, '%'));\n",
|
||||
"---\n",
|
||||
"kind: tool\n",
|
||||
"name: search-hotels-by-location\n",
|
||||
"type: bigquery-sql\n",
|
||||
"source: my-bigquery-source\n",
|
||||
"description: Search for hotels based on location.\n",
|
||||
"parameters:\n",
|
||||
" - name: location\n",
|
||||
" type: string\n",
|
||||
" description: The location of the hotel.\n",
|
||||
"statement: SELECT * FROM `{DATASET}.{TABLE_ID}` WHERE LOWER(location) LIKE LOWER(CONCAT('%', @location, '%'));\n",
|
||||
"---\n",
|
||||
"kind: tool\n",
|
||||
"name: book-hotel\n",
|
||||
"type: bigquery-sql\n",
|
||||
"source: my-bigquery-source\n",
|
||||
"description: >-\n",
|
||||
" Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not.\n",
|
||||
"parameters:\n",
|
||||
" - name: hotel_id\n",
|
||||
" type: integer\n",
|
||||
" description: The ID of the hotel to book.\n",
|
||||
"statement: UPDATE `{DATASET}.{TABLE_ID}` SET booked = TRUE WHERE id = @hotel_id;\n",
|
||||
"---\n",
|
||||
"kind: tool\n",
|
||||
"name: update-hotel\n",
|
||||
"type: bigquery-sql\n",
|
||||
"source: my-bigquery-source\n",
|
||||
"description: >-\n",
|
||||
" Update a hotel's check-in and check-out dates by its ID. Returns a message indicating whether the hotel was successfully updated or not.\n",
|
||||
"parameters:\n",
|
||||
" - name: checkin_date\n",
|
||||
" type: string\n",
|
||||
" description: The new check-in date of the hotel.\n",
|
||||
" - name: checkout_date\n",
|
||||
" type: string\n",
|
||||
" description: The new check-out date of the hotel.\n",
|
||||
" - name: hotel_id\n",
|
||||
" type: integer\n",
|
||||
" description: The ID of the hotel to update.\n",
|
||||
"statement: >-\n",
|
||||
" UPDATE `{DATASET}.{TABLE_ID}` SET checkin_date = PARSE_DATE('%Y-%m-%d', @checkin_date), checkout_date = PARSE_DATE('%Y-%m-%d', @checkout_date) WHERE id = @hotel_id;\n",
|
||||
"---\n",
|
||||
"kind: tool\n",
|
||||
"name: cancel-hotel\n",
|
||||
"type: bigquery-sql\n",
|
||||
"source: my-bigquery-source\n",
|
||||
"description: Cancel a hotel by its ID.\n",
|
||||
"parameters:\n",
|
||||
" - name: hotel_id\n",
|
||||
" type: integer\n",
|
||||
" description: The ID of the hotel to cancel.\n",
|
||||
"statement: UPDATE `{DATASET}.{TABLE_ID}` SET booked = FALSE WHERE id = @hotel_id;\n",
|
||||
"---\n",
|
||||
"kind: toolset\n",
|
||||
"name: my-toolset\n",
|
||||
"tools:\n",
|
||||
" - search-hotels-by-name\n",
|
||||
" - search-hotels-by-location\n",
|
||||
" - book-hotel\n",
|
||||
" - update-hotel\n",
|
||||
" - cancel-hotel\n",
|
||||
"\"\"\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "JPNXr4y58tMH"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"with open(tools_file_name, 'w', encoding='utf-8') as f:\n",
|
||||
" f.write(file_content)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "5ZH5VuYzdP_W"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"TOOLS_FILE_PATH = f\"/content/{tools_file_name}\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "iZGQzYUF-pho"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Start a toolbox server\n",
|
||||
"! nohup {TOOLBOX_BINARY_PATH} --config {TOOLS_FILE_PATH} -p {SERVER_PORT} > toolbox.log 2>&1 &"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "1PJpKOBieKOV",
|
||||
"outputId": "3bc866bd-86b1-4b5c-f77a-f0acf65ebd4e"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Check if toolbox is running\n",
|
||||
"!sudo lsof -i :{SERVER_PORT}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "4yFH4JK7JEAv"
|
||||
},
|
||||
"source": [
|
||||
"## Step 3: Connect your agent to Toolbox\n",
|
||||
"\n",
|
||||
"In this section, you will\n",
|
||||
"1. Establish a connection to the tools by creating a Toolbox client.\n",
|
||||
"2. Build an agent that leverages the tools and an LLM for Hotel Booking functionality.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "u0Jc-0YNdhQd",
|
||||
"outputId": "8c0167ca-bcca-492a-e7b6-aab808ecc156"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Configure gcloud.\n",
|
||||
"!gcloud config set project {BIGQUERY_PROJECT}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "J46eLkFbNhWq"
|
||||
},
|
||||
"source": [
|
||||
"> You can use ADK, LangGraph, or LlamaIndex to develop a Toolbox based application. Run one of the [Connect Using LangGraph](#scrollTo=pbapNMhhL33S), [Connect using LlamaIndex](#scrollTo=04iysrm_L_7v&line=1&uniqifier=1) or [Connect using ADK](#scrollTo=yA3rAiELIds5) sections below.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "pbapNMhhL33S"
|
||||
},
|
||||
"source": [
|
||||
"### Connect Using LangGraph"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "uraBx8mbMXnV",
|
||||
"outputId": "d4fc8823-e8e5-4f55-95e8-06eafbb5e0b1"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Install the Toolbox Langchain package\n",
|
||||
"!pip install toolbox-langchain --quiet\n",
|
||||
"!pip install langgraph --quiet\n",
|
||||
"\n",
|
||||
"# Install the Langchain llm package\n",
|
||||
"# TODO(developer): replace this with another model if needed\n",
|
||||
"! pip install langchain-google-vertexai --quiet\n",
|
||||
"# ! pip install langchain-google-genai\n",
|
||||
"# ! pip install langchain-anthropic"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "0oHNnZnBM8FU"
|
||||
},
|
||||
"source": [
|
||||
"Create a LangGraph Hotel Agent which can Search, Book and Cancel hotels."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "Br3ucM46M9uc",
|
||||
"outputId": "7118993f-d5f7-4e15-ba28-0dc71cc6c403"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langgraph.prebuilt import create_react_agent\n",
|
||||
"# TODO(developer): replace this with another import if needed\n",
|
||||
"from langchain_google_vertexai import ChatVertexAI\n",
|
||||
"# from langchain_google_genai import ChatGoogleGenerativeAI\n",
|
||||
"# from langchain_anthropic import ChatAnthropic\n",
|
||||
"from langgraph.checkpoint.memory import MemorySaver\n",
|
||||
"\n",
|
||||
"from toolbox_langchain import ToolboxClient\n",
|
||||
"\n",
|
||||
"prompt = \"\"\"\n",
|
||||
" You're a helpful hotel assistant. You handle hotel searching, booking and\n",
|
||||
" cancellations. When the user searches for a hotel, mention it's name, id,\n",
|
||||
" location and price tier. Always mention hotel id while performing any\n",
|
||||
" searches. This is very important for any operations. For any bookings or\n",
|
||||
" cancellations, please provide the appropriate confirmation. Be sure to\n",
|
||||
" update checkin or checkout dates if mentioned by the user.\n",
|
||||
" Don't ask for confirmations from the user.\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"queries = [\n",
|
||||
" \"Find hotels in Basel with Basel in it's name.\",\n",
|
||||
" \"Can you book the Hilton Basel for me?\",\n",
|
||||
" \"Oh wait, this is too expensive. Please cancel it and book the Hyatt Regency instead.\",\n",
|
||||
" \"My check in dates would be from April 10, 2024 to April 19, 2024.\",\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"# Create an LLM to bind with the agent.\n",
|
||||
"# TODO(developer): replace this with another model if needed\n",
|
||||
"model = ChatVertexAI(model_name=\"gemini-2.0-flash-001\", project=BIGQUERY_PROJECT)\n",
|
||||
"# model = ChatGoogleGenerativeAI(model=\"gemini-2.0-flash-001\")\n",
|
||||
"# model = ChatAnthropic(model=\"claude-3-5-sonnet-20240620\")\n",
|
||||
"\n",
|
||||
"# Load the tools from the Toolbox server\n",
|
||||
"client = ToolboxClient(\"http://127.0.0.1:5000\")\n",
|
||||
"tools = client.load_toolset()\n",
|
||||
"\n",
|
||||
"# Create a Langraph agent\n",
|
||||
"agent = create_react_agent(model, tools, checkpointer=MemorySaver())\n",
|
||||
"config = {\"configurable\": {\"thread_id\": \"thread-1\"}}\n",
|
||||
"for query in queries:\n",
|
||||
" inputs = {\"messages\": [(\"user\", prompt + query)]}\n",
|
||||
" response = agent.invoke(inputs, stream_mode=\"values\", config=config)\n",
|
||||
" print(response[\"messages\"][-1].content)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "04iysrm_L_7v"
|
||||
},
|
||||
"source": [
|
||||
"### Connect using LlamaIndex"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "6b6Loh8SJ_iA",
|
||||
"outputId": "a834e07b-6f28-48f2-ef26-1204af5e053d"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Install the Toolbox LlamaIndex package\n",
|
||||
"!pip install toolbox-llamaindex --quiet\n",
|
||||
"\n",
|
||||
"# Install the llamaindex llm package\n",
|
||||
"# TODO(developer): replace this with another model if needed\n",
|
||||
"! pip install llama-index-llms-google-genai --quiet\n",
|
||||
"# ! pip install llama-index-llms-anthropic"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "zjsq_xXice11"
|
||||
},
|
||||
"source": [
|
||||
"Create a LlamaIndex Hotel Agent which can Search, Book and Cancel hotels."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "EaBX4Dh6cU31",
|
||||
"outputId": "3d07e690-6102-4ed4-9751-fcf7fc869cdd"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import asyncio\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"from llama_index.core.agent.workflow import AgentWorkflow\n",
|
||||
"\n",
|
||||
"from llama_index.core.workflow import Context\n",
|
||||
"\n",
|
||||
"# TODO(developer): replace this with another import if needed\n",
|
||||
"from llama_index.llms.google_genai import GoogleGenAI\n",
|
||||
"# from llama_index.llms.anthropic import Anthropic\n",
|
||||
"\n",
|
||||
"from toolbox_llamaindex import ToolboxClient\n",
|
||||
"\n",
|
||||
"prompt = \"\"\"\n",
|
||||
" You're a helpful hotel assistant. You handle hotel searching, booking and\n",
|
||||
" cancellations. When the user searches for a hotel, mention it's name, id,\n",
|
||||
" location and price tier. Always mention hotel ids while performing any\n",
|
||||
" searches. This is very important for any operations. For any bookings or\n",
|
||||
" cancellations, please provide the appropriate confirmation. Be sure to\n",
|
||||
" update checkin or checkout dates if mentioned by the user.\n",
|
||||
" Don't ask for confirmations from the user.\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"queries = [\n",
|
||||
" \"Find hotels in Basel with Basel in it's name.\",\n",
|
||||
" \"Can you book the Hilton Basel for me?\",\n",
|
||||
" \"Oh wait, this is too expensive. Please cancel it and book the Hyatt Regency instead.\",\n",
|
||||
" \"My check in dates would be from April 10, 2024 to April 19, 2024.\",\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"async def run_agent():\n",
|
||||
" # Create an LLM to bind with the agent.\n",
|
||||
" # TODO(developer): replace this with another model if needed\n",
|
||||
" llm = GoogleGenAI(\n",
|
||||
" model=\"gemini-2.0-flash-001\",\n",
|
||||
" vertexai_config={\"project\": BIGQUERY_PROJECT, \"location\": \"us-central1\"},\n",
|
||||
" )\n",
|
||||
" # llm = GoogleGenAI(\n",
|
||||
" # api_key=os.getenv(\"GOOGLE_API_KEY\"),\n",
|
||||
" # model=\"gemini-2.0-flash-001\",\n",
|
||||
" # )\n",
|
||||
" # llm = Anthropic(\n",
|
||||
" # model=\"claude-3-7-sonnet-latest\",\n",
|
||||
" # api_key=os.getenv(\"ANTHROPIC_API_KEY\")\n",
|
||||
" # )\n",
|
||||
"\n",
|
||||
" # Load the tools from the Toolbox server\n",
|
||||
" client = ToolboxClient(\"http://127.0.0.1:5000\")\n",
|
||||
" tools = client.load_toolset()\n",
|
||||
"\n",
|
||||
" # Create a LlamaIndex agent\n",
|
||||
" agent = AgentWorkflow.from_tools_or_functions(\n",
|
||||
" tools,\n",
|
||||
" llm=llm,\n",
|
||||
" system_prompt=prompt,\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" # Run the agent\n",
|
||||
" ctx = Context(agent)\n",
|
||||
" for query in queries:\n",
|
||||
" response = await agent.run(user_msg=query, ctx=ctx)\n",
|
||||
" print(f\"---- {query} ----\")\n",
|
||||
" print(str(response))\n",
|
||||
"\n",
|
||||
"await run_agent()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "yA3rAiELIds5"
|
||||
},
|
||||
"source": [
|
||||
"### Connect Using ADK"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "rphyouv2JtwX",
|
||||
"outputId": "63b26ec0-1880-4112-a90e-26b297ddd565"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install -q google-adk\n",
|
||||
"!pip install -q toolbox-core"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "wsc-bozAIXvo",
|
||||
"outputId": "6ecb10cd-2493-4bf4-e9ed-add9fed5c600"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Create an ADK Hotel Agent which can Search, Book and Cancel hotels.\n",
|
||||
"from google.adk.agents import Agent\n",
|
||||
"from google.adk.runners import Runner\n",
|
||||
"from google.adk.sessions import InMemorySessionService\n",
|
||||
"from google.adk.artifacts.in_memory_artifact_service import InMemoryArtifactService\n",
|
||||
"from google.genai import types\n",
|
||||
"from toolbox_core import ToolboxSyncClient\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.environ['GOOGLE_GENAI_USE_VERTEXAI'] = 'True'\n",
|
||||
"os.environ['GOOGLE_CLOUD_PROJECT'] = BIGQUERY_PROJECT\n",
|
||||
"os.environ['GOOGLE_CLOUD_LOCATION'] = 'us-central1'\n",
|
||||
"\n",
|
||||
"toolbox_client = ToolboxSyncClient(\"http://127.0.0.1:5000\")\n",
|
||||
"\n",
|
||||
"prompt = \"\"\"\n",
|
||||
" You're a helpful hotel assistant. You handle hotel searching, booking and\n",
|
||||
" cancellations. When the user searches for a hotel, mention it's name, id,\n",
|
||||
" location and price tier. Always mention hotel ids while performing any\n",
|
||||
" searches. This is very important for any operations. For any bookings or\n",
|
||||
" cancellations, please provide the appropriate confirmation. Be sure to\n",
|
||||
" update checkin or checkout dates if mentioned by the user.\n",
|
||||
" Don't ask for confirmations from the user.\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"root_agent = Agent(\n",
|
||||
" model='gemini-2.0-flash-001',\n",
|
||||
" name='hotel_agent',\n",
|
||||
" description='A helpful AI assistant.',\n",
|
||||
" instruction=prompt,\n",
|
||||
" tools=toolbox_client.load_toolset(\"my-toolset\"),\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"session_service = InMemorySessionService()\n",
|
||||
"artifacts_service = InMemoryArtifactService()\n",
|
||||
"session = session_service.create_session(\n",
|
||||
" state={}, app_name='hotel_agent', user_id='123'\n",
|
||||
")\n",
|
||||
"runner = Runner(\n",
|
||||
" app_name='hotel_agent',\n",
|
||||
" agent=root_agent,\n",
|
||||
" artifact_service=artifacts_service,\n",
|
||||
" session_service=session_service,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"queries = [\n",
|
||||
" \"Find hotels in Basel with Basel in it's name.\",\n",
|
||||
" \"Can you book the Hilton Basel for me?\",\n",
|
||||
" \"Oh wait, this is too expensive. Please cancel it and book the Hyatt Regency instead.\",\n",
|
||||
" \"My check in dates would be from April 10, 2024 to April 19, 2024.\",\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"for query in queries:\n",
|
||||
" content = types.Content(role='user', parts=[types.Part(text=query)])\n",
|
||||
" events = runner.run(session_id=session.id,\n",
|
||||
" user_id='123', new_message=content)\n",
|
||||
"\n",
|
||||
" responses = (\n",
|
||||
" part.text\n",
|
||||
" for event in events\n",
|
||||
" for part in event.content.parts\n",
|
||||
" if part.text is not None\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" for text in responses:\n",
|
||||
" print(text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "Kd-wF_Z9vVe3"
|
||||
},
|
||||
"source": [
|
||||
"### Observe the output\n",
|
||||
"\n",
|
||||
"You can see that the `Hyatt Regency Basel` has been booked for the correct dates."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 398
|
||||
},
|
||||
"id": "ZTW9bTUoqHis",
|
||||
"outputId": "0bd858b3-366e-4821-d570-3058e6bea673"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"sql_select = f\"SELECT * FROM `{BIGQUERY_PROJECT}.{DATASET}.{TABLE_ID}`\"\n",
|
||||
"query_job = bqclient.query(sql_select)\n",
|
||||
"\n",
|
||||
"print(\"\\nQuery results:\")\n",
|
||||
"query_job.to_dataframe()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "wCRH0542KC51"
|
||||
},
|
||||
"source": [
|
||||
"### Clean-Up\n",
|
||||
"Conditionally delete BigQuery table and dataset in final session."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "w8W1N0rpz5Iq",
|
||||
"outputId": "0b6763d6-08c6-4c4d-e697-f6ae47fce3f2"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"bqclient.delete_table(table_ref, not_found_ok=True)\n",
|
||||
"\n",
|
||||
"bqclient.get_dataset(dataset_ref)\n",
|
||||
"tables_in_dataset = list(bqclient.list_tables(dataset_ref))\n",
|
||||
"if not tables_in_dataset:\n",
|
||||
" bqclient.delete_dataset(dataset_ref, delete_contents=False, not_found_ok=True)\n",
|
||||
" print(f\"Dataset '{DATASET}' deleted.\")\n",
|
||||
"else:\n",
|
||||
" print(f\"Dataset '{DATASET}' is not empty. Skipping dataset deletion.\")"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
@@ -0,0 +1,723 @@
|
||||
---
|
||||
title: "Quickstart (Local with BigQuery)"
|
||||
type: docs
|
||||
weight: 1
|
||||
description: >
|
||||
How to get started running Toolbox locally with Python, BigQuery, and
|
||||
LangGraph, LlamaIndex, or ADK.
|
||||
sample_filters: ["BigQuery", "Local", "ADK", "LangChain", "LlamaIndex", "Python"]
|
||||
is_sample: true
|
||||
---
|
||||
|
||||
[](https://colab.research.google.com/github/googleapis/mcp-toolbox/blob/main/docs/en/samples/bigquery/colab_quickstart_bigquery.ipynb)
|
||||
|
||||
## Before you begin
|
||||
|
||||
This guide assumes you have already done the following:
|
||||
|
||||
1. Installed [Python 3.10+][install-python] (including [pip][install-pip] and
|
||||
your preferred virtual environment tool for managing dependencies e.g.
|
||||
[venv][install-venv]).
|
||||
1. Installed and configured the [Google Cloud SDK (gcloud CLI)][install-gcloud].
|
||||
1. Authenticated with Google Cloud for Application Default Credentials (ADC):
|
||||
|
||||
```bash
|
||||
gcloud auth login --update-adc
|
||||
```
|
||||
|
||||
1. Set your default Google Cloud project (replace `YOUR_PROJECT_ID` with your
|
||||
actual project ID):
|
||||
|
||||
```bash
|
||||
gcloud config set project YOUR_PROJECT_ID
|
||||
export GOOGLE_CLOUD_PROJECT=YOUR_PROJECT_ID
|
||||
```
|
||||
|
||||
Toolbox and the client libraries will use this project for BigQuery, unless
|
||||
overridden in configurations.
|
||||
1. [Enabled the BigQuery API][enable-bq-api] in your Google Cloud project.
|
||||
1. Installed the BigQuery client library for Python:
|
||||
|
||||
```bash
|
||||
pip install google-cloud-bigquery
|
||||
```
|
||||
|
||||
1. Completed setup for usage with an LLM model such as
|
||||
{{< tabpane text=true persist=header >}}
|
||||
{{% tab header="Core" lang="en" %}}
|
||||
|
||||
- [langchain-vertexai](https://python.langchain.com/docs/integrations/llms/google_vertex_ai_palm/#setup)
|
||||
package.
|
||||
|
||||
- [langchain-google-genai](https://python.langchain.com/docs/integrations/chat/google_generative_ai/#setup)
|
||||
package.
|
||||
|
||||
- [langchain-anthropic](https://python.langchain.com/docs/integrations/chat/anthropic/#setup)
|
||||
package.
|
||||
{{% /tab %}}
|
||||
{{% tab header="LangChain" lang="en" %}}
|
||||
- [langchain-vertexai](https://python.langchain.com/docs/integrations/llms/google_vertex_ai_palm/#setup)
|
||||
package.
|
||||
|
||||
- [langchain-google-genai](https://python.langchain.com/docs/integrations/chat/google_generative_ai/#setup)
|
||||
package.
|
||||
|
||||
- [langchain-anthropic](https://python.langchain.com/docs/integrations/chat/anthropic/#setup)
|
||||
package.
|
||||
{{% /tab %}}
|
||||
{{% tab header="LlamaIndex" lang="en" %}}
|
||||
- [llama-index-llms-google-genai](https://pypi.org/project/llama-index-llms-google-genai/)
|
||||
package.
|
||||
|
||||
- [llama-index-llms-anthropic](https://docs.llamaindex.ai/en/stable/examples/llm/anthropic)
|
||||
package.
|
||||
{{% /tab %}}
|
||||
{{% tab header="ADK" lang="en" %}}
|
||||
- [google-adk](https://pypi.org/project/google-adk/) package.
|
||||
{{% /tab %}}
|
||||
{{< /tabpane >}}
|
||||
|
||||
[install-python]: https://wiki.python.org/moin/BeginnersGuide/Download
|
||||
[install-pip]: https://pip.pypa.io/en/stable/installation/
|
||||
[install-venv]:
|
||||
https://packaging.python.org/en/latest/tutorials/installing-packages/#creating-virtual-environments
|
||||
[install-gcloud]: https://cloud.google.com/sdk/docs/install
|
||||
[enable-bq-api]:
|
||||
https://cloud.google.com/bigquery/docs/quickstarts/query-public-dataset-console#before-you-begin
|
||||
|
||||
## Step 1: Set up your BigQuery Dataset and Table
|
||||
|
||||
In this section, we will create a BigQuery dataset and a table, then insert some
|
||||
data that needs to be accessed by our agent. BigQuery operations are performed
|
||||
against your configured Google Cloud project.
|
||||
|
||||
1. Create a new BigQuery dataset (replace `YOUR_DATASET_NAME` with your desired
|
||||
dataset name, e.g., `toolbox_ds`, and optionally specify a location like `US`
|
||||
or `EU`):
|
||||
|
||||
```bash
|
||||
export BQ_DATASET_NAME="YOUR_DATASET_NAME" # e.g., toolbox_ds
|
||||
export BQ_LOCATION="US" # e.g., US, EU, asia-northeast1
|
||||
|
||||
bq --location=$BQ_LOCATION mk $BQ_DATASET_NAME
|
||||
```
|
||||
|
||||
You can also do this through the [Google Cloud
|
||||
Console](https://console.cloud.google.com/bigquery).
|
||||
|
||||
{{< notice tip >}}
|
||||
For a real application, ensure that the service account or user running Toolbox
|
||||
has the necessary IAM permissions (e.g., BigQuery Data Editor, BigQuery User)
|
||||
on the dataset or project. For this local quickstart with user credentials,
|
||||
your own permissions will apply.
|
||||
{{< /notice >}}
|
||||
|
||||
1. The hotels table needs to be defined in your new dataset for use with the bq
|
||||
query command. First, create a file named `create_hotels_table.sql` with the
|
||||
following content:
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS `YOUR_PROJECT_ID.YOUR_DATASET_NAME.hotels` (
|
||||
id INT64 NOT NULL,
|
||||
name STRING NOT NULL,
|
||||
location STRING NOT NULL,
|
||||
price_tier STRING NOT NULL,
|
||||
checkin_date DATE NOT NULL,
|
||||
checkout_date DATE NOT NULL,
|
||||
booked BOOLEAN NOT NULL
|
||||
);
|
||||
```
|
||||
|
||||
> **Note:** Replace `YOUR_PROJECT_ID` and `YOUR_DATASET_NAME` in the SQL
|
||||
> with your actual project ID and dataset name.
|
||||
|
||||
Then run the command below to execute the sql query:
|
||||
|
||||
```bash
|
||||
bq query --project_id=$GOOGLE_CLOUD_PROJECT --dataset_id=$BQ_DATASET_NAME --use_legacy_sql=false < create_hotels_table.sql
|
||||
```
|
||||
|
||||
1. Next, populate the hotels table with some initial data. To do this, create a
|
||||
file named `insert_hotels_data.sql` and add the following SQL INSERT
|
||||
statement to it.
|
||||
|
||||
```sql
|
||||
INSERT INTO `YOUR_PROJECT_ID.YOUR_DATASET_NAME.hotels` (id, name, location, price_tier, checkin_date, checkout_date, booked)
|
||||
VALUES
|
||||
(1, 'Hilton Basel', 'Basel', 'Luxury', '2024-04-20', '2024-04-22', FALSE),
|
||||
(2, 'Marriott Zurich', 'Zurich', 'Upscale', '2024-04-14', '2024-04-21', FALSE),
|
||||
(3, 'Hyatt Regency Basel', 'Basel', 'Upper Upscale', '2024-04-02', '2024-04-20', FALSE),
|
||||
(4, 'Radisson Blu Lucerne', 'Lucerne', 'Midscale', '2024-04-05', '2024-04-24', FALSE),
|
||||
(5, 'Best Western Bern', 'Bern', 'Upper Midscale', '2024-04-01', '2024-04-23', FALSE),
|
||||
(6, 'InterContinental Geneva', 'Geneva', 'Luxury', '2024-04-23', '2024-04-28', FALSE),
|
||||
(7, 'Sheraton Zurich', 'Zurich', 'Upper Upscale', '2024-04-02', '2024-04-27', FALSE),
|
||||
(8, 'Holiday Inn Basel', 'Basel', 'Upper Midscale', '2024-04-09', '2024-04-24', FALSE),
|
||||
(9, 'Courtyard Zurich', 'Zurich', 'Upscale', '2024-04-03', '2024-04-13', FALSE),
|
||||
(10, 'Comfort Inn Bern', 'Bern', 'Midscale', '2024-04-04', '2024-04-16', FALSE);
|
||||
```
|
||||
|
||||
> **Note:** Replace `YOUR_PROJECT_ID` and `YOUR_DATASET_NAME` in the SQL
|
||||
> with your actual project ID and dataset name.
|
||||
|
||||
Then run the command below to execute the sql query:
|
||||
|
||||
```bash
|
||||
bq query --project_id=$GOOGLE_CLOUD_PROJECT --dataset_id=$BQ_DATASET_NAME --use_legacy_sql=false < insert_hotels_data.sql
|
||||
```
|
||||
|
||||
## Step 2: Install and configure Toolbox
|
||||
|
||||
In this section, we will download Toolbox, configure our tools in a `tools.yaml`
|
||||
to use BigQuery, and then run the Toolbox server.
|
||||
|
||||
1. Download the latest version of Toolbox as a binary:
|
||||
|
||||
{{< notice tip >}}
|
||||
Select the
|
||||
[correct binary](https://github.com/googleapis/mcp-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, windows/amd64, or windows/arm64
|
||||
curl -O https://storage.googleapis.com/mcp-toolbox-for-databases/v0.30.0/$OS/toolbox
|
||||
```
|
||||
<!-- {x-release-please-end} -->
|
||||
|
||||
1. Make the binary executable:
|
||||
|
||||
```bash
|
||||
chmod +x toolbox
|
||||
```
|
||||
|
||||
1. Write the following into a `tools.yaml` file. You must replace the
|
||||
`YOUR_PROJECT_ID` and `YOUR_DATASET_NAME` placeholder in the config with your
|
||||
actual BigQuery project and dataset name. The `location` field is optional;
|
||||
if not specified, it defaults to 'us'. The table name `hotels` is used
|
||||
directly in the statements.
|
||||
|
||||
{{< notice tip >}}
|
||||
Authentication with BigQuery is handled via Application Default Credentials
|
||||
(ADC). Ensure you have run `gcloud auth application-default login`.
|
||||
{{< /notice >}}
|
||||
|
||||
```yaml
|
||||
kind: source
|
||||
name: my-bigquery-source
|
||||
type: bigquery
|
||||
project: YOUR_PROJECT_ID
|
||||
location: us
|
||||
---
|
||||
kind: tool
|
||||
name: search-hotels-by-name
|
||||
type: bigquery-sql
|
||||
source: my-bigquery-source
|
||||
description: Search for hotels based on name.
|
||||
parameters:
|
||||
- name: name
|
||||
type: string
|
||||
description: The name of the hotel.
|
||||
statement: SELECT * FROM `YOUR_DATASET_NAME.hotels` WHERE LOWER(name) LIKE LOWER(CONCAT('%', @name, '%'));
|
||||
---
|
||||
kind: tool
|
||||
name: search-hotels-by-location
|
||||
type: bigquery-sql
|
||||
source: my-bigquery-source
|
||||
description: Search for hotels based on location.
|
||||
parameters:
|
||||
- name: location
|
||||
type: string
|
||||
description: The location of the hotel.
|
||||
statement: SELECT * FROM `YOUR_DATASET_NAME.hotels` WHERE LOWER(location) LIKE LOWER(CONCAT('%', @location, '%'));
|
||||
---
|
||||
kind: tool
|
||||
name: book-hotel
|
||||
type: bigquery-sql
|
||||
source: my-bigquery-source
|
||||
description: >-
|
||||
Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not.
|
||||
parameters:
|
||||
- name: hotel_id
|
||||
type: integer
|
||||
description: The ID of the hotel to book.
|
||||
statement: UPDATE `YOUR_DATASET_NAME.hotels` SET booked = TRUE WHERE id = @hotel_id;
|
||||
---
|
||||
kind: tool
|
||||
name: update-hotel
|
||||
type: bigquery-sql
|
||||
source: my-bigquery-source
|
||||
description: >-
|
||||
Update a hotel's check-in and check-out dates by its ID. Returns a message indicating whether the hotel was successfully updated or not.
|
||||
parameters:
|
||||
- name: checkin_date
|
||||
type: string
|
||||
description: The new check-in date of the hotel.
|
||||
- name: checkout_date
|
||||
type: string
|
||||
description: The new check-out date of the hotel.
|
||||
- name: hotel_id
|
||||
type: integer
|
||||
description: The ID of the hotel to update.
|
||||
statement: >-
|
||||
UPDATE `YOUR_DATASET_NAME.hotels` SET checkin_date = PARSE_DATE('%Y-%m-%d', @checkin_date), checkout_date = PARSE_DATE('%Y-%m-%d', @checkout_date) WHERE id = @hotel_id;
|
||||
---
|
||||
kind: tool
|
||||
name: cancel-hotel
|
||||
type: bigquery-sql
|
||||
source: my-bigquery-source
|
||||
description: Cancel a hotel by its ID.
|
||||
parameters:
|
||||
- name: hotel_id
|
||||
type: integer
|
||||
description: The ID of the hotel to cancel.
|
||||
statement: UPDATE `YOUR_DATASET_NAME.hotels` SET booked = FALSE WHERE id = @hotel_id;
|
||||
```
|
||||
|
||||
**Important Note on `toolset`**: The `tools.yaml` content above does not
|
||||
include a `toolset` kind. The Python agent examples in Step 3 (e.g.,
|
||||
`await toolbox_client.load_toolset("my-toolset")`) rely on a toolset named
|
||||
`my-toolset`. To make those examples work, you will need to add a `toolset`
|
||||
to your `tools.yaml` file, for example:
|
||||
|
||||
```yaml
|
||||
# Add this to your tools.yaml if using load_toolset("my-toolset")
|
||||
kind: toolset
|
||||
name: my-toolset
|
||||
tools:
|
||||
- search-hotels-by-name
|
||||
- search-hotels-by-location
|
||||
- book-hotel
|
||||
- update-hotel
|
||||
- cancel-hotel
|
||||
```
|
||||
|
||||
Alternatively, you can modify the agent code to load tools individually
|
||||
(e.g., using `await toolbox_client.load_tool("search-hotels-by-name")`).
|
||||
|
||||
For more info on tools, check out the [Configuring Tools](../../../documentation/configuration/tools/_index.md) section
|
||||
of the docs.
|
||||
|
||||
1. Run the Toolbox server, pointing to the `tools.yaml` file created earlier:
|
||||
|
||||
```bash
|
||||
./toolbox --config "tools.yaml"
|
||||
```
|
||||
|
||||
{{< notice note >}}
|
||||
Toolbox enables dynamic reloading by default. To disable, use the
|
||||
`--disable-reload` flag.
|
||||
{{< /notice >}}
|
||||
|
||||
## Step 3: Connect your agent to Toolbox
|
||||
|
||||
In this section, we will write and run an agent that will load the Tools
|
||||
from Toolbox.
|
||||
|
||||
{{< notice tip>}} If you prefer to experiment within a Google Colab environment,
|
||||
you can connect to a
|
||||
[local runtime](https://research.google.com/colaboratory/local-runtimes.html).
|
||||
{{< /notice >}}
|
||||
|
||||
1. In a new terminal, install the SDK package.
|
||||
|
||||
{{< tabpane persist=header >}}
|
||||
{{< tab header="Core" lang="bash" >}}
|
||||
|
||||
pip install toolbox-core
|
||||
{{< /tab >}}
|
||||
{{< tab header="Langchain" lang="bash" >}}
|
||||
|
||||
pip install toolbox-langchain
|
||||
{{< /tab >}}
|
||||
{{< tab header="LlamaIndex" lang="bash" >}}
|
||||
|
||||
pip install toolbox-llamaindex
|
||||
{{< /tab >}}
|
||||
{{< tab header="ADK" lang="bash" >}}
|
||||
|
||||
pip install google-adk[toolbox]
|
||||
{{< /tab >}}
|
||||
|
||||
{{< /tabpane >}}
|
||||
|
||||
1. Install other required dependencies:
|
||||
|
||||
{{< tabpane persist=header >}}
|
||||
{{< tab header="Core" lang="bash" >}}
|
||||
|
||||
# TODO(developer): replace with correct package if needed
|
||||
|
||||
pip install langgraph langchain-google-vertexai
|
||||
|
||||
# pip install langchain-google-genai
|
||||
|
||||
# pip install langchain-anthropic
|
||||
|
||||
{{< /tab >}}
|
||||
{{< tab header="Langchain" lang="bash" >}}
|
||||
|
||||
# TODO(developer): replace with correct package if needed
|
||||
|
||||
pip install langgraph langchain-google-vertexai
|
||||
|
||||
# pip install langchain-google-genai
|
||||
|
||||
# pip install langchain-anthropic
|
||||
|
||||
{{< /tab >}}
|
||||
{{< tab header="LlamaIndex" lang="bash" >}}
|
||||
|
||||
# TODO(developer): replace with correct package if needed
|
||||
|
||||
pip install llama-index-llms-google-genai
|
||||
|
||||
# pip install llama-index-llms-anthropic
|
||||
|
||||
{{< /tab >}}
|
||||
{{< tab header="ADK" lang="bash" >}}
|
||||
# No other dependencies required for ADK
|
||||
{{< /tab >}}
|
||||
{{< /tabpane >}}
|
||||
|
||||
1. Create a new file named `hotel_agent.py` and copy the following
|
||||
code to create an agent:
|
||||
{{< tabpane persist=header >}}
|
||||
{{< tab header="Core" lang="python" >}}
|
||||
|
||||
import asyncio
|
||||
|
||||
from google import genai
|
||||
from google.genai.types import (
|
||||
Content,
|
||||
FunctionDeclaration,
|
||||
GenerateContentConfig,
|
||||
Part,
|
||||
Tool,
|
||||
)
|
||||
|
||||
from toolbox_core import ToolboxClient
|
||||
|
||||
prompt = """
|
||||
You're a helpful hotel assistant. You handle hotel searching, booking and
|
||||
cancellations. When the user searches for a hotel, mention it's name, id,
|
||||
location and price tier. Always mention hotel id 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.
|
||||
"""
|
||||
|
||||
queries = [
|
||||
"Find hotels in Basel with Basel in it's name.",
|
||||
"Please book the hotel Hilton Basel for me.",
|
||||
"This is too expensive. Please cancel it.",
|
||||
"Please book Hyatt Regency for me",
|
||||
"My check in dates for my booking would be from April 10, 2024 to April 19, 2024.",
|
||||
]
|
||||
|
||||
async def run_application():
|
||||
async with ToolboxClient("<http://127.0.0.1:5000>") as toolbox_client:
|
||||
|
||||
# The toolbox_tools list contains Python callables (functions/methods) designed for LLM tool-use
|
||||
# integration. While this example uses Google's genai client, these callables can be adapted for
|
||||
# various function-calling or agent frameworks. For easier integration with supported frameworks
|
||||
# (https://github.com/googleapis/mcp-toolbox-python-sdk/tree/main/packages), use the
|
||||
# provided wrapper packages, which handle framework-specific boilerplate.
|
||||
toolbox_tools = await toolbox_client.load_toolset("my-toolset")
|
||||
tool_map = {tool.__name__: tool for tool in toolbox_tools}
|
||||
genai_client = genai.Client(
|
||||
vertexai=True, project="project-id", location="us-central1"
|
||||
)
|
||||
|
||||
genai_tools = [
|
||||
Tool(
|
||||
function_declarations=[
|
||||
FunctionDeclaration.from_callable_with_api_option(callable=tool)
|
||||
]
|
||||
)
|
||||
for tool in toolbox_tools
|
||||
]
|
||||
history = []
|
||||
for query in queries:
|
||||
user_prompt_content = Content(
|
||||
role="user",
|
||||
parts=[Part.from_text(text=query)],
|
||||
)
|
||||
history.append(user_prompt_content)
|
||||
|
||||
response = genai_client.models.generate_content(
|
||||
model="gemini-2.0-flash-001",
|
||||
contents=history,
|
||||
config=GenerateContentConfig(
|
||||
system_instruction=prompt,
|
||||
tools=genai_tools,
|
||||
),
|
||||
)
|
||||
history.append(response.candidates[0].content)
|
||||
function_response_parts = []
|
||||
for function_call in response.function_calls:
|
||||
fn_name = function_call.name
|
||||
if fn_name in tool_map:
|
||||
function_result = await tool_map[fn_name](**function_call.args)
|
||||
else:
|
||||
raise ValueError(f"Function name {fn_name} not present.")
|
||||
function_response = {"result": function_result}
|
||||
function_response_part = Part.from_function_response(
|
||||
name=function_call.name,
|
||||
response=function_response,
|
||||
)
|
||||
function_response_parts.append(function_response_part)
|
||||
|
||||
if function_response_parts:
|
||||
tool_response_content = Content(role="tool", parts=function_response_parts)
|
||||
history.append(tool_response_content)
|
||||
|
||||
response2 = genai_client.models.generate_content(
|
||||
model="gemini-2.0-flash-001",
|
||||
contents=history,
|
||||
config=GenerateContentConfig(
|
||||
tools=genai_tools,
|
||||
),
|
||||
)
|
||||
final_model_response_content = response2.candidates[0].content
|
||||
history.append(final_model_response_content)
|
||||
print(response2.text)
|
||||
|
||||
asyncio.run(run_application())
|
||||
{{< /tab >}}
|
||||
{{< tab header="LangChain" lang="python" >}}
|
||||
|
||||
import asyncio
|
||||
from langgraph.prebuilt import create_react_agent
|
||||
|
||||
# TODO(developer): replace this with another import if needed
|
||||
|
||||
from langchain_google_vertexai import ChatVertexAI
|
||||
|
||||
# from langchain_google_genai import ChatGoogleGenerativeAI
|
||||
|
||||
# from langchain_anthropic import ChatAnthropic
|
||||
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
|
||||
from toolbox_langchain import ToolboxClient
|
||||
|
||||
prompt = """
|
||||
You're a helpful hotel assistant. You handle hotel searching, booking and
|
||||
cancellations. When the user searches for a hotel, mention it's 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.
|
||||
"""
|
||||
|
||||
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.",
|
||||
]
|
||||
|
||||
async def main():
|
||||
# TODO(developer): replace this with another model if needed
|
||||
model = ChatVertexAI(model_name="gemini-2.0-flash-001")
|
||||
# model = ChatGoogleGenerativeAI(model="gemini-2.0-flash-001")
|
||||
# model = ChatAnthropic(model="claude-3-5-sonnet-20240620")
|
||||
|
||||
# Load the tools from the Toolbox server
|
||||
client = ToolboxClient("http://127.0.0.1:5000")
|
||||
tools = await client.aload_toolset()
|
||||
|
||||
agent = create_react_agent(model, tools, checkpointer=MemorySaver())
|
||||
|
||||
config = {"configurable": {"thread_id": "thread-1"}}
|
||||
for query in queries:
|
||||
inputs = {"messages": [("user", prompt + query)]}
|
||||
response = await agent.ainvoke(inputs, stream_mode="values", config=config)
|
||||
print(response["messages"][-1].content)
|
||||
|
||||
asyncio.run(main())
|
||||
{{< /tab >}}
|
||||
{{< tab header="LlamaIndex" lang="python" >}}
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from llama_index.core.agent.workflow import AgentWorkflow
|
||||
|
||||
from llama_index.core.workflow import Context
|
||||
|
||||
# TODO(developer): replace this with another import if needed
|
||||
|
||||
from llama_index.llms.google_genai import GoogleGenAI
|
||||
|
||||
# from llama_index.llms.anthropic import Anthropic
|
||||
|
||||
from toolbox_llamaindex import ToolboxClient
|
||||
|
||||
prompt = """
|
||||
You're a helpful hotel assistant. You handle hotel searching, booking and
|
||||
cancellations. When the user searches for a hotel, mention it's 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.
|
||||
"""
|
||||
|
||||
queries = [
|
||||
"Find hotels in Basel with Basel in it's 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.",
|
||||
]
|
||||
|
||||
async def main():
|
||||
# TODO(developer): replace this with another model if needed
|
||||
llm = GoogleGenAI(
|
||||
model="gemini-2.0-flash-001",
|
||||
vertexai_config={"location": "us-central1"},
|
||||
)
|
||||
# llm = GoogleGenAI(
|
||||
# api_key=os.getenv("GOOGLE_API_KEY"),
|
||||
# model="gemini-2.0-flash-001",
|
||||
# )
|
||||
# llm = Anthropic(
|
||||
# model="claude-3-7-sonnet-latest",
|
||||
# api_key=os.getenv("ANTHROPIC_API_KEY")
|
||||
# )
|
||||
|
||||
# Load the tools from the Toolbox server
|
||||
client = ToolboxClient("http://127.0.0.1:5000")
|
||||
tools = await client.aload_toolset()
|
||||
|
||||
agent = AgentWorkflow.from_tools_or_functions(
|
||||
tools,
|
||||
llm=llm,
|
||||
system_prompt=prompt,
|
||||
)
|
||||
ctx = Context(agent)
|
||||
for query in queries:
|
||||
response = await agent.arun(user_msg=query, ctx=ctx)
|
||||
print(f"---- {query} ----")
|
||||
print(str(response))
|
||||
|
||||
asyncio.run(main())
|
||||
{{< /tab >}}
|
||||
{{< tab header="ADK" lang="python" >}}
|
||||
from google.adk.agents import Agent
|
||||
from google.adk.runners import Runner
|
||||
from google.adk.sessions import InMemorySessionService
|
||||
from google.adk.artifacts.in_memory_artifact_service import InMemoryArtifactService
|
||||
from google.adk.tools.toolbox_toolset import ToolboxToolset
|
||||
from google.genai import types # For constructing message content
|
||||
|
||||
import os
|
||||
os.environ['GOOGLE_GENAI_USE_VERTEXAI'] = 'True'
|
||||
|
||||
# TODO(developer): Replace 'YOUR_PROJECT_ID' with your Google Cloud Project ID
|
||||
|
||||
os.environ['GOOGLE_CLOUD_PROJECT'] = 'YOUR_PROJECT_ID'
|
||||
|
||||
# TODO(developer): Replace 'us-central1' with your Google Cloud Location (region)
|
||||
|
||||
os.environ['GOOGLE_CLOUD_LOCATION'] = 'us-central1'
|
||||
|
||||
# --- Load Tools from Toolbox ---
|
||||
|
||||
# TODO(developer): Ensure the Toolbox server is running at http://127.0.0.1:5000
|
||||
toolset = ToolboxToolset(server_url="http://127.0.0.1:5000")
|
||||
|
||||
# --- Define the Agent's Prompt ---
|
||||
prompt = """
|
||||
You're a helpful hotel assistant. You handle hotel searching, booking and
|
||||
cancellations. When the user searches for a hotel, mention it's 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.
|
||||
"""
|
||||
|
||||
# --- Configure the Agent ---
|
||||
|
||||
root_agent = Agent(
|
||||
model='gemini-2.0-flash-001',
|
||||
name='hotel_agent',
|
||||
description='A helpful AI assistant that can search and book hotels.',
|
||||
instruction=prompt,
|
||||
tools=[toolset], # Pass the loaded toolset
|
||||
)
|
||||
|
||||
# --- Initialize Services for Running the Agent ---
|
||||
session_service = InMemorySessionService()
|
||||
artifacts_service = InMemoryArtifactService()
|
||||
|
||||
runner = Runner(
|
||||
app_name='hotel_agent',
|
||||
agent=root_agent,
|
||||
artifact_service=artifacts_service,
|
||||
session_service=session_service,
|
||||
)
|
||||
|
||||
async def main():
|
||||
# Create a new session for the interaction.
|
||||
session = await session_service.create_session(
|
||||
state={}, app_name='hotel_agent', user_id='123'
|
||||
)
|
||||
|
||||
# --- Define Queries and Run the Agent ---
|
||||
queries = [
|
||||
"Find hotels in Basel with Basel in it's 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.",
|
||||
]
|
||||
|
||||
for query in queries:
|
||||
content = types.Content(role='user', parts=[types.Part(text=query)])
|
||||
events = runner.run(session_id=session.id,
|
||||
user_id='123', new_message=content)
|
||||
|
||||
responses = (
|
||||
part.text
|
||||
for event in events
|
||||
for part in event.content.parts
|
||||
if part.text is not None
|
||||
)
|
||||
|
||||
for text in responses:
|
||||
print(text)
|
||||
|
||||
import asyncio
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
{{< /tab >}}
|
||||
{{< /tabpane >}}
|
||||
|
||||
{{< tabpane text=true persist=header >}}
|
||||
{{% tab header="Core" lang="en" %}}
|
||||
To learn more about the Core SDK, check out the [Toolbox Core SDK
|
||||
documentation.](https://github.com/googleapis/mcp-toolbox-sdk-python/blob/main/packages/toolbox-core/README.md)
|
||||
{{% /tab %}}
|
||||
{{% tab header="Langchain" lang="en" %}}
|
||||
To learn more about Agents in LangChain, check out the [LangGraph Agent
|
||||
documentation.](https://langchain-ai.github.io/langgraph/reference/prebuilt/#langgraph.prebuilt.chat_agent_executor.create_react_agent)
|
||||
{{% /tab %}}
|
||||
{{% tab header="LlamaIndex" lang="en" %}}
|
||||
To learn more about Agents in LlamaIndex, check out the [LlamaIndex
|
||||
AgentWorkflow
|
||||
documentation.](https://docs.llamaindex.ai/en/stable/examples/agent/agent_workflow_basic/)
|
||||
{{% /tab %}}
|
||||
{{% tab header="ADK" lang="en" %}}
|
||||
To learn more about Agents in ADK, check out the [ADK
|
||||
documentation.](https://google.github.io/adk-docs/)
|
||||
{{% /tab %}}
|
||||
{{< /tabpane >}}
|
||||
|
||||
1. Run your agent, and observe the results:
|
||||
|
||||
```sh
|
||||
python hotel_agent.py
|
||||
```
|
||||
@@ -0,0 +1,254 @@
|
||||
---
|
||||
title: "Quickstart (MCP with BigQuery)"
|
||||
type: docs
|
||||
weight: 2
|
||||
description: >
|
||||
How to get started running Toolbox with MCP Inspector and BigQuery as the source.
|
||||
sample_filters: ["BigQuery", "MCP Inspector"]
|
||||
is_sample: true
|
||||
---
|
||||
|
||||
## 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](../../../../documentation/connect-to/mcp-client/_index.md).
|
||||
|
||||
## Step 1: Set up your BigQuery Dataset and Table
|
||||
|
||||
In this section, we will create a BigQuery dataset and a table, then insert some
|
||||
data that needs to be accessed by our agent.
|
||||
|
||||
1. Create a new BigQuery dataset (replace `YOUR_DATASET_NAME` with your desired
|
||||
dataset name, e.g., `toolbox_mcp_ds`, and optionally specify a location like
|
||||
`US` or `EU`):
|
||||
|
||||
```bash
|
||||
export BQ_DATASET_NAME="YOUR_DATASET_NAME"
|
||||
export BQ_LOCATION="US"
|
||||
|
||||
bq --location=$BQ_LOCATION mk $BQ_DATASET_NAME
|
||||
```
|
||||
|
||||
You can also do this through the [Google Cloud
|
||||
Console](https://console.cloud.google.com/bigquery).
|
||||
|
||||
1. The `hotels` table needs to be defined in your new dataset. First, create a
|
||||
file named `create_hotels_table.sql` with the following content:
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS `YOUR_PROJECT_ID.YOUR_DATASET_NAME.hotels` (
|
||||
id INT64 NOT NULL,
|
||||
name STRING NOT NULL,
|
||||
location STRING NOT NULL,
|
||||
price_tier STRING NOT NULL,
|
||||
checkin_date DATE NOT NULL,
|
||||
checkout_date DATE NOT NULL,
|
||||
booked BOOLEAN NOT NULL
|
||||
);
|
||||
```
|
||||
|
||||
> **Note:** Replace `YOUR_PROJECT_ID` and `YOUR_DATASET_NAME` in the SQL
|
||||
> with your actual project ID and dataset name.
|
||||
|
||||
Then run the command below to execute the sql query:
|
||||
|
||||
```bash
|
||||
bq query --project_id=$GOOGLE_CLOUD_PROJECT --dataset_id=$BQ_DATASET_NAME --use_legacy_sql=false < create_hotels_table.sql
|
||||
```
|
||||
|
||||
1. . Next, populate the hotels table with some initial data. To do this, create
|
||||
a file named `insert_hotels_data.sql` and add the following SQL INSERT
|
||||
statement to it.
|
||||
|
||||
```sql
|
||||
INSERT INTO `YOUR_PROJECT_ID.YOUR_DATASET_NAME.hotels` (id, name, location, price_tier, checkin_date, checkout_date, booked)
|
||||
VALUES
|
||||
(1, 'Hilton Basel', 'Basel', 'Luxury', '2024-04-20', '2024-04-22', FALSE),
|
||||
(2, 'Marriott Zurich', 'Zurich', 'Upscale', '2024-04-14', '2024-04-21', FALSE),
|
||||
(3, 'Hyatt Regency Basel', 'Basel', 'Upper Upscale', '2024-04-02', '2024-04-20', FALSE),
|
||||
(4, 'Radisson Blu Lucerne', 'Lucerne', 'Midscale', '2024-04-05', '2024-04-24', FALSE),
|
||||
(5, 'Best Western Bern', 'Bern', 'Upper Midscale', '2024-04-01', '2024-04-23', FALSE),
|
||||
(6, 'InterContinental Geneva', 'Geneva', 'Luxury', '2024-04-23', '2024-04-28', FALSE),
|
||||
(7, 'Sheraton Zurich', 'Zurich', 'Upper Upscale', '2024-04-02', '2024-04-27', FALSE),
|
||||
(8, 'Holiday Inn Basel', 'Basel', 'Upper Midscale', '2024-04-09', '2024-04-24', FALSE),
|
||||
(9, 'Courtyard Zurich', 'Zurich', 'Upscale', '2024-04-03', '2024-04-13', FALSE),
|
||||
(10, 'Comfort Inn Bern', 'Bern', 'Midscale', '2024-04-04', '2024-04-16', FALSE);
|
||||
```
|
||||
|
||||
> **Note:** Replace `YOUR_PROJECT_ID` and `YOUR_DATASET_NAME` in the SQL
|
||||
> with your actual project ID and dataset name.
|
||||
|
||||
Then run the command below to execute the sql query:
|
||||
|
||||
```bash
|
||||
bq query --project_id=$GOOGLE_CLOUD_PROJECT --dataset_id=$BQ_DATASET_NAME --use_legacy_sql=false < insert_hotels_data.sql
|
||||
```
|
||||
|
||||
## Step 2: Install and configure Toolbox
|
||||
|
||||
In this section, we will download Toolbox, configure our tools in a
|
||||
`tools.yaml`, and then run the Toolbox server.
|
||||
|
||||
1. Download the latest version of Toolbox as a binary:
|
||||
|
||||
{{< notice tip >}}
|
||||
Select the
|
||||
[correct binary](https://github.com/googleapis/mcp-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, windows/amd64, or windows/arm64
|
||||
curl -O https://storage.googleapis.com/mcp-toolbox-for-databases/v0.30.0/$OS/toolbox
|
||||
```
|
||||
<!-- {x-release-please-end} -->
|
||||
|
||||
1. Make the binary executable:
|
||||
|
||||
```bash
|
||||
chmod +x toolbox
|
||||
```
|
||||
|
||||
1. Write the following into a `tools.yaml` file. You must replace the
|
||||
`YOUR_PROJECT_ID` and `YOUR_DATASET_NAME` placeholder in the config with your
|
||||
actual BigQuery project and dataset name. The `location` field is optional;
|
||||
if not specified, it defaults to 'us'. The table name `hotels` is used
|
||||
directly in the statements.
|
||||
|
||||
{{< notice tip >}}
|
||||
Authentication with BigQuery is handled via Application Default Credentials
|
||||
(ADC). Ensure you have run `gcloud auth application-default login`.
|
||||
{{< /notice >}}
|
||||
|
||||
```yaml
|
||||
kind: source
|
||||
name: my-bigquery-source
|
||||
type: bigquery
|
||||
project: YOUR_PROJECT_ID
|
||||
location: us
|
||||
---
|
||||
kind: tool
|
||||
name: search-hotels-by-name
|
||||
type: bigquery-sql
|
||||
source: my-bigquery-source
|
||||
description: Search for hotels based on name.
|
||||
parameters:
|
||||
- name: name
|
||||
type: string
|
||||
description: The name of the hotel.
|
||||
statement: SELECT * FROM `YOUR_DATASET_NAME.hotels` WHERE LOWER(name) LIKE LOWER(CONCAT('%', @name, '%'));
|
||||
---
|
||||
kind: tool
|
||||
name: search-hotels-by-location
|
||||
type: bigquery-sql
|
||||
source: my-bigquery-source
|
||||
description: Search for hotels based on location.
|
||||
parameters:
|
||||
- name: location
|
||||
type: string
|
||||
description: The location of the hotel.
|
||||
statement: SELECT * FROM `YOUR_DATASET_NAME.hotels` WHERE LOWER(location) LIKE LOWER(CONCAT('%', @location, '%'));
|
||||
---
|
||||
kind: tool
|
||||
name: book-hotel
|
||||
type: bigquery-sql
|
||||
source: my-bigquery-source
|
||||
description: >-
|
||||
Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not.
|
||||
parameters:
|
||||
- name: hotel_id
|
||||
type: integer
|
||||
description: The ID of the hotel to book.
|
||||
statement: UPDATE `YOUR_DATASET_NAME.hotels` SET booked = TRUE WHERE id = @hotel_id;
|
||||
---
|
||||
kind: tool
|
||||
name: update-hotel
|
||||
type: bigquery-sql
|
||||
source: my-bigquery-source
|
||||
description: >-
|
||||
Update a hotel's check-in and check-out dates by its ID. Returns a message indicating whether the hotel was successfully updated or not.
|
||||
parameters:
|
||||
- name: checkin_date
|
||||
type: string
|
||||
description: The new check-in date of the hotel.
|
||||
- name: checkout_date
|
||||
type: string
|
||||
description: The new check-out date of the hotel.
|
||||
- name: hotel_id
|
||||
type: integer
|
||||
description: The ID of the hotel to update.
|
||||
statement: >-
|
||||
UPDATE `YOUR_DATASET_NAME.hotels` SET checkin_date = PARSE_DATE('%Y-%m-%d', @checkin_date), checkout_date = PARSE_DATE('%Y-%m-%d', @checkout_date) WHERE id = @hotel_id;
|
||||
---
|
||||
kind: tool
|
||||
name: cancel-hotel
|
||||
type: bigquery-sql
|
||||
source: my-bigquery-source
|
||||
description: Cancel a hotel by its ID.
|
||||
parameters:
|
||||
- name: hotel_id
|
||||
type: integer
|
||||
description: The ID of the hotel to cancel.
|
||||
statement: UPDATE `YOUR_DATASET_NAME.hotels` SET booked = FALSE WHERE id = @hotel_id;
|
||||
---
|
||||
kind: toolset
|
||||
name: my-toolset
|
||||
tools:
|
||||
- search-hotels-by-name
|
||||
- search-hotels-by-location
|
||||
- book-hotel
|
||||
- update-hotel
|
||||
- cancel-hotel
|
||||
```
|
||||
|
||||
For more info on tools, check out the
|
||||
[Tools](../../../../documentation/configuration/tools/_index.md) section.
|
||||
|
||||
1. Run the Toolbox server, pointing to the `tools.yaml` file created earlier:
|
||||
|
||||
```bash
|
||||
./toolbox --config "tools.yaml"
|
||||
```
|
||||
|
||||
## 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 (please
|
||||
take note of `<YOUR_SESSION_TOKEN>`):
|
||||
|
||||
```bash
|
||||
Starting MCP inspector...
|
||||
⚙️ Proxy server listening on localhost:6277
|
||||
🔑 Session token: <YOUR_SESSION_TOKEN>
|
||||
Use this token to authenticate requests or set DANGEROUSLY_OMIT_AUTH=true to disable auth
|
||||
|
||||
🚀 MCP Inspector is up and running at:
|
||||
http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=<YOUR_SESSION_TOKEN>
|
||||
```
|
||||
|
||||
1. Open the above link in your browser.
|
||||
|
||||
1. For `Transport Type`, select `Streamable HTTP`.
|
||||
|
||||
1. For `URL`, type in `http://127.0.0.1:5000/mcp`.
|
||||
|
||||
1. For `Configuration` -> `Proxy Session Token`, make sure
|
||||
`<YOUR_SESSION_TOKEN>` is present.
|
||||
|
||||
1. Click Connect.
|
||||
|
||||

|
||||
|
||||
1. Select `List Tools`, you will see a list of tools configured in `tools.yaml`.
|
||||
|
||||

|
||||
|
||||
1. Test out your tools here!
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
Reference in New Issue
Block a user