diff --git a/docs/docs/integrations/providers/toolbox-langchain.mdx b/docs/docs/integrations/providers/toolbox-langchain.mdx new file mode 100644 index 00000000000..c48c5687b2e --- /dev/null +++ b/docs/docs/integrations/providers/toolbox-langchain.mdx @@ -0,0 +1,23 @@ +# MCP Toolbox + +The [MCP Toolbox](https://googleapis.github.io/genai-toolbox/getting-started/introduction/) in LangChain allows you to equip an agent with a set of tools. When the agent receives a query, it can intelligently select and use the most appropriate tool provided by MCP Toolbox to fulfill the request. + +## What is it? + +MCP Toolbox is essentially a container for your tools. Think of it as a multi-tool device for your agent; it can hold any tools you create. The agent then decides which specific tool to use based on the user's input. + +This is particularly useful when you have an agent that needs to perform a variety of tasks that require different capabilities. + +## Installation + +To get started, you'll need to install the necessary package: + +```bash +pip install toolbox-langchain +``` + +## Tutorial + +For a complete, step-by-step guide on how to create, configure, and use MCP Toolbox with your agents, please refer to our detailed Jupyter notebook tutorial. + +**[➡️ View the full tutorial here](/docs/integrations/tools/toolbox)**. diff --git a/docs/docs/integrations/tools/toolbox.ipynb b/docs/docs/integrations/tools/toolbox.ipynb new file mode 100644 index 00000000000..7ab6b1663c3 --- /dev/null +++ b/docs/docs/integrations/tools/toolbox.ipynb @@ -0,0 +1,378 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "554b9f85", + "metadata": {}, + "source": [ + "# MCP Toolbox for Databases\n", + "\n", + "Integrate your databases with LangChain agents using MCP Toolbox.\n", + "\n", + "## Overview\n", + "\n", + "[MCP Toolbox for Databases](https://github.com/googleapis/genai-toolbox) is an open source MCP server for databases. It was designed with enterprise-grade and production-quality in mind. It enables you to develop tools easier, faster, and more securely by handling the complexities such as connection pooling, authentication, and more.\n", + "\n", + "Toolbox Tools can be seemlessly integrated with Langchain applications. For more\n", + "information on [getting\n", + "started](https://googleapis.github.io/genai-toolbox/getting-started/local_quickstart/) or\n", + "[configuring](https://googleapis.github.io/genai-toolbox/getting-started/configure/)\n", + "MCP Toolbox, see the\n", + "[documentation](https://googleapis.github.io/genai-toolbox/getting-started/introduction/).\n", + "\n", + "![architecture](https://raw.githubusercontent.com/googleapis/genai-toolbox/refs/heads/main/docs/en/getting-started/introduction/architecture.png)" + ] + }, + { + "cell_type": "markdown", + "id": "788ff64c", + "metadata": {}, + "source": [ + "## Setup\n", + "\n", + "This guide assumes you have already done the following:\n", + "\n", + "1. Installed [Python 3.9+](https://wiki.python.org/moin/BeginnersGuide/Download) and [pip](https://pip.pypa.io/en/stable/installation/).\n", + "2. Installed [PostgreSQL 16+ and the `psql` command-line client](https://www.postgresql.org/download/)." + ] + }, + { + "cell_type": "markdown", + "id": "4847d196", + "metadata": {}, + "source": [ + "### 1. Setup your Database\n", + "\n", + "First, let's set up a PostgreSQL database. We'll create a new database, a dedicated user for MCP Toolbox, and a `hotels` table with some sample data.\n", + "\n", + "Connect to PostgreSQL using the `psql` command. You may need to adjust the command based on your PostgreSQL setup (e.g., if you need to specify a host or a different superuser).\n", + "\n", + "```bash\n", + "psql -U postgres\n", + "```\n", + "\n", + "Now, run the following SQL commands to create the user, database, and grant the necessary permissions:\n", + "\n", + "```sql\n", + "CREATE USER toolbox_user WITH PASSWORD 'my-password';\n", + "CREATE DATABASE toolbox_db;\n", + "GRANT ALL PRIVILEGES ON DATABASE toolbox_db TO toolbox_user;\n", + "ALTER DATABASE toolbox_db OWNER TO toolbox_user;\n", + "```\n", + "\n", + "Connect to your newly created database with the new user:\n", + "\n", + "```sql\n", + "\\c toolbox_db toolbox_user\n", + "```\n", + "\n", + "Finally, create the `hotels` table and insert some data:\n", + "\n", + "```sql\n", + "CREATE TABLE hotels(\n", + " id INTEGER NOT NULL PRIMARY KEY,\n", + " name VARCHAR NOT NULL,\n", + " location VARCHAR NOT NULL,\n", + " price_tier VARCHAR NOT NULL,\n", + " booked BIT NOT NULL\n", + ");\n", + "\n", + "INSERT INTO hotels(id, name, location, price_tier, booked)\n", + "VALUES \n", + " (1, 'Hilton Basel', 'Basel', 'Luxury', B'0'),\n", + " (2, 'Marriott Zurich', 'Zurich', 'Upscale', B'0'),\n", + " (3, 'Hyatt Regency Basel', 'Basel', 'Upper Upscale', B'0');\n", + "```\n", + "You can now exit `psql` by typing `\\q`." + ] + }, + { + "cell_type": "markdown", + "id": "855133f8", + "metadata": {}, + "source": [ + "### 2. Install MCP Toolbox\n", + "\n", + "Next, we will install MCP Toolbox, define our tools in a `tools.yaml` configuration file, and run the MCP Toolbox server.\n", + "\n", + "For **macOS** users, the easiest way to install is with [Homebrew](https://formulae.brew.sh/formula/mcp-toolbox):\n", + "\n", + "```bash\n", + "brew install mcp-toolbox\n", + "```\n", + "\n", + "For other platforms, [download the latest MCP Toolbox binary for your operating system and architecture.](https://github.com/googleapis/genai-toolbox/releases)\n", + "\n", + "Create a `tools.yaml` file. This file defines the data sources MCP Toolbox can connect to and the tools it can expose to your agent. For production use, always use environment variables for secrets.\n", + "\n", + "```yaml\n", + "sources:\n", + " my-pg-source:\n", + " kind: postgres\n", + " host: 127.0.0.1\n", + " port: 5432\n", + " database: toolbox_db\n", + " user: toolbox_user\n", + " password: my-password\n", + "\n", + "tools:\n", + " search-hotels-by-location:\n", + " kind: postgres-sql\n", + " source: my-pg-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 id, name, location, price_tier FROM hotels WHERE location ILIKE '%' || $1 || '%';\n", + " book-hotel:\n", + " kind: postgres-sql\n", + " source: my-pg-source\n", + " description: >-\n", + " Book a hotel by its ID. If the hotel is successfully booked, returns a confirmation message.\n", + " parameters:\n", + " - name: hotel_id\n", + " type: integer\n", + " description: The ID of the hotel to book.\n", + " statement: UPDATE hotels SET booked = B'1' WHERE id = $1;\n", + "\n", + "toolsets:\n", + " hotel_toolset:\n", + " - search-hotels-by-location\n", + " - book-hotel\n", + "```\n", + "\n", + "Now, in a separate terminal window, start the MCP Toolbox server. If you installed via Homebrew, you can just run `toolbox`. If you downloaded the binary manually, you'll need to run `./toolbox` from the directory where you saved it:\n", + "\n", + "```bash\n", + "toolbox --tools-file \"tools.yaml\"\n", + "```\n", + "\n", + "MCP Toolbox will start on `http://127.0.0.1:5000` by default and will hot-reload if you make changes to your `tools.yaml` file." + ] + }, + { + "cell_type": "markdown", + "id": "b9b2f041", + "metadata": {}, + "source": [ + "## Instantiation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d4c31f3b", + "metadata": {}, + "outputs": [], + "source": [ + "!pip install toolbox-langchain" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14a68a49", + "metadata": {}, + "outputs": [], + "source": [ + "from toolbox_langchain import ToolboxClient\n", + "\n", + "with ToolboxClient(\"http://127.0.0.1:5000\") as client:\n", + " search_tool = await client.aload_tool(\"search-hotels-by-location\")" + ] + }, + { + "cell_type": "markdown", + "id": "95eec50c", + "metadata": {}, + "source": [ + "## Invocation\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8e99351b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[{\"id\":1,\"location\":\"Basel\",\"name\":\"Hilton Basel\",\"price_tier\":\"Luxury\"},{\"id\":3,\"location\":\"Basel\",\"name\":\"Hyatt Regency Basel\",\"price_tier\":\"Upper Upscale\"}]\n" + ] + } + ], + "source": [ + "from toolbox_langchain import ToolboxClient\n", + "\n", + "with ToolboxClient(\"http://127.0.0.1:5000\") as client:\n", + " search_tool = await client.aload_tool(\"search-hotels-by-location\")\n", + " results = search_tool.invoke({\"location\": \"Basel\"})\n", + " print(results)" + ] + }, + { + "cell_type": "markdown", + "id": "9e8dbd39", + "metadata": {}, + "source": [ + "## Use within an agent\n", + "\n", + "Now for the fun part! We'll install the required LangChain packages and create an agent that can use the tools we defined in MCP Toolbox." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9b716a84", + "metadata": { + "id": "install-packages" + }, + "outputs": [], + "source": [ + "%pip install -U --quiet toolbox-langchain langgraph langchain-google-vertexai" + ] + }, + { + "cell_type": "markdown", + "id": "affda34b", + "metadata": {}, + "source": [ + "With the packages installed, we can define our agent. We will use `ChatVertexAI` for the model and `ToolboxClient` to load our tools. The `create_react_agent` from `langgraph.prebuilt` creates a robust agent that can reason about which tools to call.\n", + "\n", + "**Note:** Ensure your MCP Toolbox server is running in a separate terminal before executing the code below." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ddd82892", + "metadata": {}, + "outputs": [], + "source": [ + "from langgraph.prebuilt import create_react_agent\n", + "from langchain_google_vertexai import ChatVertexAI\n", + "from langgraph.checkpoint.memory import MemorySaver\n", + "from toolbox_langchain import ToolboxClient\n", + "\n", + "prompt = \"\"\"\n", + "You're a helpful hotel assistant. You handle hotel searching and booking.\n", + "When the user searches for a hotel, list the full details for each hotel found: id, name, location, and price tier.\n", + "Always use the hotel ID for booking operations.\n", + "For any bookings, provide a clear confirmation message.\n", + "Don't ask for clarification or confirmation from the user; perform the requested action directly.\n", + "\"\"\"\n", + "\n", + "\n", + "async def run_queries(agent_executor):\n", + " config = {\"configurable\": {\"thread_id\": \"hotel-thread-1\"}}\n", + "\n", + " # --- Query 1: Search for hotels ---\n", + " query1 = \"I need to find a hotel in Basel.\"\n", + " print(f'\\n--- USER: \"{query1}\" ---')\n", + " inputs1 = {\"messages\": [(\"user\", prompt + query1)]}\n", + " async for event in agent_executor.astream_events(\n", + " inputs1, config=config, version=\"v2\"\n", + " ):\n", + " if event[\"event\"] == \"on_chat_model_end\" and event[\"data\"][\"output\"].content:\n", + " print(f\"--- AGENT: ---\\n{event['data']['output'].content}\")\n", + "\n", + " # --- Query 2: Book a hotel ---\n", + " query2 = \"Great, please book the Hyatt Regency Basel for me.\"\n", + " print(f'\\n--- USER: \"{query2}\" ---')\n", + " inputs2 = {\"messages\": [(\"user\", query2)]}\n", + " async for event in agent_executor.astream_events(\n", + " inputs2, config=config, version=\"v2\"\n", + " ):\n", + " if event[\"event\"] == \"on_chat_model_end\" and event[\"data\"][\"output\"].content:\n", + " print(f\"--- AGENT: ---\\n{event['data']['output'].content}\")" + ] + }, + { + "cell_type": "markdown", + "id": "54552733", + "metadata": {}, + "source": [ + "## Run the agent" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9f7c199b", + "metadata": {}, + "outputs": [], + "source": [ + "async def main():\n", + " await run_hotel_agent()\n", + "\n", + "\n", + "async def run_hotel_agent():\n", + " model = ChatVertexAI(model_name=\"gemini-2.5-flash\")\n", + "\n", + " # Load the tools from the running MCP Toolbox server\n", + " async with ToolboxClient(\"http://127.0.0.1:5000\") as client:\n", + " tools = await client.aload_toolset(\"hotel_toolset\")\n", + "\n", + " agent = create_react_agent(model, tools, checkpointer=MemorySaver())\n", + "\n", + " await run_queries(agent)\n", + "\n", + "\n", + "await main()" + ] + }, + { + "cell_type": "markdown", + "id": "79bce43d", + "metadata": {}, + "source": [ + "You've successfully connected a LangChain agent to a local database using MCP Toolbox! 🥳\n", + "\n", + "## API reference\n", + "\n", + "The primary class for this integration is `ToolboxClient`.\n", + "\n", + "For more information, see the following resources:\n", + "- [Toolbox Official Documentation](https://googleapis.github.io/genai-toolbox/)\n", + "- [Toolbox GitHub Repository](https://github.com/googleapis/genai-toolbox)\n", + "- [Toolbox LangChain SDK](https://github.com/googleapis/mcp-toolbox-python-sdk/tree/main/packages/toolbox-langchain)\n", + "\n", + "MCP Toolbox has a variety of features to make developing Gen AI tools for databases seamless:\n", + "- [Authenticated Parameters](https://googleapis.github.io/genai-toolbox/resources/tools/#authenticated-parameters): Bind tool inputs to values from OIDC tokens automatically, making it easy to run sensitive queries without potentially leaking data\n", + "- [Authorized Invocations](https://googleapis.github.io/genai-toolbox/resources/tools/#authorized-invocations): Restrict access to use a tool based on the users Auth token\n", + "- [OpenTelemetry](https://googleapis.github.io/genai-toolbox/how-to/export_telemetry/): Get metrics and tracing from MCP Toolbox with [OpenTelemetry](https://opentelemetry.io/docs/)\n", + "\n", + "# Community and Support\n", + "\n", + "We encourage you to get involved with the community:\n", + "- ⭐️ Head over to the [GitHub repository](https://github.com/googleapis/genai-toolbox) to get started and follow along with updates.\n", + "- 📚 Dive into the [official documentation](https://googleapis.github.io/genai-toolbox/getting-started/introduction/) for more advanced features and configurations.\n", + "- 💬 Join our [Discord server](https://discord.com/invite/a4XjGqtmnG) to connect with the community and ask questions." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/scripts/tool_feat_table.py b/docs/scripts/tool_feat_table.py index fda6cc42767..11ec2b74f0e 100644 --- a/docs/scripts/tool_feat_table.py +++ b/docs/scripts/tool_feat_table.py @@ -182,6 +182,10 @@ DATABASE_TOOL_FEAT_TABLE = { "link": "/docs/integrations/tools/cassandra_database", "operations": "SELECT and schema introspection", }, + "MCP Toolbox": { + "link": "/docs/integrations/tools/toolbox", + "operations": "Any SQL operation", + }, } FINANCE_TOOL_FEAT_TABLE = { diff --git a/libs/packages.yml b/libs/packages.yml index f394b52725b..0b229e2f066 100644 --- a/libs/packages.yml +++ b/libs/packages.yml @@ -709,3 +709,7 @@ packages: repo: digitalocean/langchain-gradient downloads: 576 downloads_updated_at: '2025-08-10T21:38:36.795416+00:00' +- name: toolbox-langchain + repo: googleapis/mcp-toolbox-sdk-python + path: packages/toolbox-langchain +