mirror of
https://github.com/googleapis/genai-toolbox.git
synced 2026-01-31 10:18:28 -05:00
Compare commits
1 Commits
migrate-go
...
migrate-go
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15a6a32aa2 |
745
docs/en/sdks/go-sdk/tbadk/_index.md
Normal file
745
docs/en/sdks/go-sdk/tbadk/_index.md
Normal file
@@ -0,0 +1,745 @@
|
||||
---
|
||||
title: "tbADK Package"
|
||||
linkTitle: "tbADK"
|
||||
type: docs
|
||||
weight: 1
|
||||
---
|
||||
|
||||

|
||||
|
||||
# MCP Toolbox tbadk SDK
|
||||
|
||||
[](https://opensource.org/licenses/Apache-2.0)
|
||||
|
||||
This SDK allows you to seamlessly integrate the functionalities of
|
||||
[Toolbox](https://github.com/googleapis/genai-toolbox) allowing you to load and
|
||||
use tools defined in the service as standard Go structs within your ADK Go
|
||||
applications.
|
||||
|
||||
This simplifies integrating external functionalities (like APIs, databases, or
|
||||
custom logic) managed by the Toolbox into your workflows, especially those
|
||||
involving Large Language Models (LLMs).
|
||||
|
||||
<!-- TOC ignore:true -->
|
||||
<!-- TOC -->
|
||||
|
||||
- [MCP Toolbox tbadk SDK](#mcp-toolbox-tbadk-sdk)
|
||||
- [Installation](#installation)
|
||||
- [Quickstart](#quickstart)
|
||||
- [Usage](#usage)
|
||||
- [Transport Protocols](#transport-protocols)
|
||||
- [Supported Protocols](#supported-protocols)
|
||||
- [Example](#example)
|
||||
- [Loading Tools](#loading-tools)
|
||||
- [Load a toolset](#load-a-toolset)
|
||||
- [Load a single tool](#load-a-single-tool)
|
||||
- [Invoking Tools](#invoking-tools)
|
||||
- [Client to Server Authentication](#client-to-server-authentication)
|
||||
- [When is Client-to-Server Authentication Needed?](#when-is-client-to-server-authentication-needed)
|
||||
- [How it works](#how-it-works)
|
||||
- [Configuration](#configuration)
|
||||
- [Authenticating with Google Cloud Servers](#authenticating-with-google-cloud-servers)
|
||||
- [Step by Step Guide for Cloud Run](#step-by-step-guide-for-cloud-run)
|
||||
- [Authenticating Tools](#authenticating-tools)
|
||||
- [When is Authentication Needed?](#when-is-authentication-needed)
|
||||
- [Supported Authentication Mechanisms](#supported-authentication-mechanisms)
|
||||
- [Step 1: Configure Tools in Toolbox Service](#step-1-configure-tools-in-toolbox-service)
|
||||
- [Step 2: Configure SDK Client](#step-2-configure-sdk-client)
|
||||
- [Provide an ID Token Retriever Function](#provide-an-id-token-retriever-function)
|
||||
- [Option A: Add Default Authentication to a Client](#option-a-add-default-authentication-to-a-client)
|
||||
- [Option B: Add Authentication to a Loaded Tool](#option-b-add-authentication-to-a-loaded-tool)
|
||||
- [Option C: Add Authentication While Loading Tools](#option-c-add-authentication-while-loading-tools)
|
||||
- [Complete Authentication Example](#complete-authentication-example)
|
||||
- [Binding Parameter Values](#binding-parameter-values)
|
||||
- [Why Bind Parameters?](#why-bind-parameters)
|
||||
- [Option A: Add Default Bound Parameters to a Client](#option-a-add-default-bound-parameters-to-a-client)
|
||||
- [Option B: Binding Parameters to a Loaded Tool](#option-b-binding-parameters-to-a-loaded-tool)
|
||||
- [Option C: Binding Parameters While Loading Tools](#option-c-binding-parameters-while-loading-tools)
|
||||
- [Binding Dynamic Values](#binding-dynamic-values)
|
||||
- [Using with ADK Go](#using-with-adk-go)
|
||||
- [For a single tool](#for-a-single-tool)
|
||||
- [For a toolset](#for-a-toolset)
|
||||
- [Contributing](#contributing)
|
||||
- [License](#license)
|
||||
- [Support](#support)
|
||||
- [Samples for Reference](#samples-for-reference)
|
||||
|
||||
<!-- /TOC -->
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
go get github.com/googleapis/mcp-toolbox-sdk-go
|
||||
```
|
||||
This SDK is supported on Go version 1.24.4 and higher.
|
||||
|
||||
{{< notice note >}}
|
||||
While the SDK itself is synchronous, you can execute its functions within goroutines to achieve asynchronous behavior.
|
||||
{{< /notice >}}
|
||||
|
||||
|
||||
## Quickstart
|
||||
|
||||
Here's a minimal example to get you started. Ensure your Toolbox service is
|
||||
running and accessible.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/googleapis/mcp-toolbox-sdk-go/tbadk"
|
||||
)
|
||||
|
||||
func quickstart() string {
|
||||
inputs := map[string]any{"location": "London"}
|
||||
client, err := tbadk.NewToolboxClient("http://localhost:5000")
|
||||
if err != nil {
|
||||
return fmt.Sprintln("Could not start Toolbox Client", err)
|
||||
}
|
||||
tool, err := client.LoadTool("get_weather", ctx)
|
||||
if err != nil {
|
||||
return fmt.Sprintln("Could not load Toolbox Tool", err)
|
||||
}
|
||||
// pass the tool.Context as ctx into the Run() method
|
||||
result, err := tool.Run(ctx, inputs)
|
||||
if err != nil {
|
||||
return fmt.Sprintln("Could not invoke tool", err)
|
||||
}
|
||||
return fmt.Sprintln(result["output"])
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println(quickstart())
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Import and initialize a Toolbox client, pointing it to the URL of your running
|
||||
Toolbox service.
|
||||
|
||||
```go
|
||||
import "github.com/googleapis/mcp-toolbox-sdk-go/tbadk"
|
||||
|
||||
client, err := tbadk.NewToolboxClient("http://localhost:5000")
|
||||
```
|
||||
|
||||
All interactions for loading and invoking tools happen through this client.
|
||||
|
||||
{{< notice note >}}
|
||||
For advanced use cases, you can provide an external custom `http.Client`
|
||||
during initialization (e.g., `tbadk.NewToolboxClient(URL, core.WithHTTPClient(myClient)`). If you provide your own session, you are responsible for managing its lifecycle;
|
||||
`ToolboxClient` *will not* close it.
|
||||
{{< /notice >}}
|
||||
|
||||
## Transport Protocols
|
||||
|
||||
The SDK supports multiple transport protocols. By default, the client uses the latest supported version of the **Model Context Protocol (MCP)**.
|
||||
|
||||
You can explicitly select a protocol using the `core.WithProtocol` option during client initialization.
|
||||
|
||||
{{< notice note >}}* **Native Toolbox Transport**: This uses the service's native **REST over HTTP** API.
|
||||
* **MCP Transports**: These options use the **Model Context Protocol over HTTP**.
|
||||
{{< /notice >}}
|
||||
|
||||
### Supported Protocols
|
||||
|
||||
| Constant | Description |
|
||||
| :--- | :--- |
|
||||
| `core.MCP` | **(Default)** Alias for the latest supported MCP version (currently `v2025-06-18`). |
|
||||
| `core.Toolbox` | The native Toolbox HTTP protocol. |
|
||||
| `core.MCPv20251125` | MCP Protocol version 2025-11-25. |
|
||||
| `core.MCPv20250618` | MCP Protocol version 2025-06-18. |
|
||||
| `core.MCPv20250326` | MCP Protocol version 2025-03-26. |
|
||||
| `core.MCPv20241105` | MCP Protocol version 2024-11-05. |
|
||||
|
||||
### Example
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/googleapis/mcp-toolbox-sdk-go/core"
|
||||
"github.com/googleapis/mcp-toolbox-sdk-go/tbadk"
|
||||
)
|
||||
|
||||
// Initialize with the native Toolbox protocol
|
||||
client, err := tbadk.NewToolboxClient(
|
||||
"http://localhost:5000",
|
||||
core.WithProtocol(core.Toolbox),
|
||||
)
|
||||
|
||||
// Initialize with the MCP Protocol 2025-03-26
|
||||
client, err := tbadk.NewToolboxClient(
|
||||
"http://localhost:5000",
|
||||
core.WithProtocol(core.MCPv20250326),
|
||||
)
|
||||
|
||||
```
|
||||
|
||||
## Loading Tools
|
||||
|
||||
You can load tools individually or in groups (toolsets) as defined in your
|
||||
Toolbox service configuration. Loading a toolset is convenient when working with
|
||||
multiple related functions, while loading a single tool offers more granular
|
||||
control.
|
||||
|
||||
### Load a toolset
|
||||
|
||||
A toolset is a collection of related tools. You can load all tools in a toolset
|
||||
or a specific one:
|
||||
|
||||
```go
|
||||
// Load default toolset by providing an empty string as the name
|
||||
tools, err := client.LoadToolset("", ctx)
|
||||
|
||||
// Load a specific toolset
|
||||
tools, err := client.LoadToolset("my-toolset", ctx)
|
||||
```
|
||||
|
||||
`LoadToolset` returns a slice of the ToolboxTool structs (`[]ToolboxTool`).
|
||||
|
||||
|
||||
### Load a single tool
|
||||
|
||||
Loads a specific tool by its unique name. This provides fine-grained control.
|
||||
|
||||
```go
|
||||
tool, err = client.LoadTool("my-tool", ctx)
|
||||
```
|
||||
|
||||
## Invoking Tools
|
||||
|
||||
Once loaded, tools behave like Go structs. You invoke them using `Run` method
|
||||
by passing arguments corresponding to the parameters defined in the tool's
|
||||
configuration within the Toolbox service.
|
||||
|
||||
```go
|
||||
tool, err = client.LoadTool("my-tool", ctx)
|
||||
inputs := map[string]any{"location": "London"}
|
||||
// Pass the tool.Context as ctx to the Run() function
|
||||
result, err := tool.Run(ctx, inputs)
|
||||
```
|
||||
|
||||
{{< notice tip >}}For a more comprehensive guide on setting up the Toolbox service itself, which
|
||||
you'll need running to use this SDK, please refer to the [Toolbox Quickstart
|
||||
Guide](https://googleapis.github.io/genai-toolbox/getting-started/local_quickstart).
|
||||
{{< /notice >}}
|
||||
|
||||
## Client to Server Authentication
|
||||
|
||||
This section describes how to authenticate the ToolboxClient itself when
|
||||
connecting to a Toolbox server instance that requires authentication. This is
|
||||
crucial for securing your Toolbox server endpoint, especially when deployed on
|
||||
platforms like Cloud Run, GKE, or any environment where unauthenticated access is restricted.
|
||||
|
||||
This client-to-server authentication ensures that the Toolbox server can verify
|
||||
the identity of the client making the request before any tool is loaded or
|
||||
called. It is different from [Authenticating Tools](#authenticating-tools),
|
||||
which deals with providing credentials for specific tools within an already
|
||||
connected Toolbox session.
|
||||
|
||||
### When is Client-to-Server Authentication Needed?
|
||||
|
||||
You'll need this type of authentication if your Toolbox server is configured to
|
||||
deny unauthenticated requests. For example:
|
||||
|
||||
- Your Toolbox server is deployed on Cloud Run and configured to "Require authentication."
|
||||
- Your server is behind an Identity-Aware Proxy (IAP) or a similar
|
||||
authentication layer.
|
||||
- You have custom authentication middleware on your self-hosted Toolbox server.
|
||||
|
||||
Without proper client authentication in these scenarios, attempts to connect or
|
||||
make calls (like `LoadTool`) will likely fail with `Unauthorized` errors.
|
||||
|
||||
### How it works
|
||||
|
||||
The `ToolboxClient` allows you to specify TokenSources that dynamically generate HTTP headers for
|
||||
every request sent to the Toolbox server. The most common use case is to add an
|
||||
Authorization header with a bearer token (e.g., a Google ID token).
|
||||
|
||||
These header-generating functions are called just before each request, ensuring
|
||||
that fresh credentials or header values can be used.
|
||||
|
||||
### Configuration
|
||||
|
||||
You can configure these dynamic headers as seen below:
|
||||
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/googleapis/mcp-toolbox-sdk-go/core"
|
||||
"github.com/googleapis/mcp-toolbox-sdk-go/tbadk"
|
||||
)
|
||||
|
||||
tokenProvider := func() string {
|
||||
return "header3_value"
|
||||
}
|
||||
|
||||
staticTokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: "header2_value"})
|
||||
dynamicTokenSource := core.NewCustomTokenSource(tokenProvider)
|
||||
|
||||
client, err := tbadk.NewToolboxClient(
|
||||
"toolbox-url",
|
||||
core.WithClientHeaderString("header1", "header1_value"),
|
||||
core.WithClientHeaderTokenSource("header2", staticTokenSource),
|
||||
core.WithClientHeaderTokenSource("header3", dynamicTokenSource),
|
||||
)
|
||||
```
|
||||
|
||||
### Authenticating with Google Cloud Servers
|
||||
|
||||
For Toolbox servers hosted on Google Cloud (e.g., Cloud Run) and requiring
|
||||
`Google ID token` authentication, the helper module
|
||||
[auth_methods](/core/auth.go) provides utility functions.
|
||||
|
||||
### Step by Step Guide for Cloud Run
|
||||
|
||||
1. **Configure Permissions**: [Grant](https://cloud.google.com/run/docs/securing/managing-access#service-add-principals) the `roles/run.Runr` IAM role on the Cloud
|
||||
Run service to the principal. This could be your `user account email` or a
|
||||
`service account`.
|
||||
2. **Configure Credentials**
|
||||
- Local Development: Set up
|
||||
[ADC](https://cloud.google.com/docs/authentication/set-up-adc-local-dev-environment).
|
||||
- Google Cloud Environments: When running within Google Cloud (e.g., Compute
|
||||
Engine, GKE, another Cloud Run service, Cloud Functions), ADC is typically
|
||||
configured automatically, using the environment's default service account.
|
||||
3. **Connect to the Toolbox Server**
|
||||
```go
|
||||
import (
|
||||
"github.com/googleapis/mcp-toolbox-sdk-go/core"
|
||||
"github.com/googleapis/mcp-toolbox-sdk-go/tbadk"
|
||||
"context"
|
||||
)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
token, err := core.GetGoogleIDToken(ctx, URL)
|
||||
|
||||
client, err := tbadk.NewToolboxClient(
|
||||
URL,
|
||||
core.WithClientHeaderString("Authorization", token),
|
||||
)
|
||||
|
||||
// Now, you can use the client as usual.
|
||||
```
|
||||
|
||||
## Authenticating Tools
|
||||
|
||||
{{< notice warning >}} **Always use HTTPS** to connect your application with the Toolbox service,
|
||||
especially in **production environments** or whenever the communication
|
||||
involves **sensitive data** (including scenarios where tools require
|
||||
authentication tokens). Using plain HTTP lacks encryption and exposes your
|
||||
application and data to significant security risks, such as eavesdropping and tampering.
|
||||
{{< /notice >}}
|
||||
|
||||
Tools can be configured within the Toolbox service to require authentication,
|
||||
ensuring only authorized users or applications can invoke them, especially when
|
||||
accessing sensitive data.
|
||||
|
||||
### When is Authentication Needed?
|
||||
|
||||
Authentication is configured per-tool within the Toolbox service itself. If a
|
||||
tool you intend to use is marked as requiring authentication in the service, you
|
||||
must configure the SDK client to provide the necessary credentials (currently
|
||||
Oauth2 tokens) when invoking that specific tool.
|
||||
|
||||
### Supported Authentication Mechanisms
|
||||
|
||||
The Toolbox service enables secure tool usage through **Authenticated Parameters**.
|
||||
For detailed information on how these mechanisms work within the Toolbox service and how to configure them, please refer to [Toolbox Service Documentation - Authenticated Parameters](https://googleapis.github.io/genai-toolbox/resources/tools/#authenticated-parameters).
|
||||
|
||||
### Step 1: Configure Tools in Toolbox Service
|
||||
|
||||
First, ensure the target tool(s) are configured correctly in the Toolbox service
|
||||
to require authentication. Refer to the [Toolbox Service Documentation -
|
||||
Authenticated
|
||||
Parameters](https://googleapis.github.io/genai-toolbox/resources/tools/#authenticated-parameters)
|
||||
for instructions.
|
||||
|
||||
### Step 2: Configure SDK Client
|
||||
|
||||
Your application needs a way to obtain the required Oauth2 token for the
|
||||
authenticated user. The SDK requires you to provide a function capable of
|
||||
retrieving this token *when the tool is invoked*.
|
||||
|
||||
#### Provide an ID Token Retriever Function
|
||||
|
||||
You must provide the SDK with a function that returns the
|
||||
necessary token when called. The implementation depends on your application's
|
||||
authentication flow (e.g., retrieving a stored token, initiating an OAuth flow).
|
||||
|
||||
{{< notice info >}}
|
||||
The name used when registering the getter function with the SDK (e.g.,
|
||||
`"my_api_token"`) must exactly match the `name` of the corresponding
|
||||
`authServices` defined in the tool's configuration within the Toolbox service.
|
||||
{{< /notice >}}
|
||||
|
||||
```go
|
||||
func getAuthToken() string {
|
||||
// ... Logic to retrieve ID token (e.g., from local storage, OAuth flow)
|
||||
// This example just returns a placeholder. Replace with your actual token retrieval.
|
||||
return "YOUR_ID_TOKEN" // Placeholder
|
||||
}
|
||||
```
|
||||
|
||||
{{< notice tip >}} Your token retriever function is invoked every time an authenticated parameter
|
||||
requires a token for a tool call. Consider implementing caching logic within
|
||||
this function to avoid redundant token fetching or generation, especially for
|
||||
tokens with longer validity periods or if the retrieval process is resource-intensive.
|
||||
{{< /notice >}}
|
||||
|
||||
#### Option A: Add Default Authentication to a Client
|
||||
|
||||
You can add default tool level authentication to a client.
|
||||
Every tool / toolset loaded by the client will contain the auth token.
|
||||
|
||||
```go
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
client, err := tbadk.NewToolboxClient("http://127.0.0.1:5000",
|
||||
core.WithDefaultToolOptions(
|
||||
core.WithAuthTokenString("my-auth-1", "auth-value"),
|
||||
),
|
||||
)
|
||||
|
||||
AuthTool, err := client.LoadTool("my-tool", ctx)
|
||||
```
|
||||
|
||||
#### Option B: Add Authentication to a Loaded Tool
|
||||
|
||||
You can add the token retriever function to a tool object *after* it has been
|
||||
loaded. This modifies the specific tool instance.
|
||||
|
||||
```go
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
client, err := tbadk.NewToolboxClient("http://127.0.0.1:5000")
|
||||
|
||||
tool, err := client.LoadTool("my-tool", ctx)
|
||||
|
||||
AuthTool, err := tool.ToolFrom(
|
||||
core.WithAuthTokenSource("my-auth", headerTokenSource),
|
||||
core.WithAuthTokenString("my-auth-1", "value"),
|
||||
)
|
||||
```
|
||||
|
||||
#### Option C: Add Authentication While Loading Tools
|
||||
|
||||
You can provide the token retriever(s) directly during the `LoadTool` or
|
||||
`LoadToolset` calls. This applies the authentication configuration only to the
|
||||
tools loaded in that specific call, without modifying the original tool objects
|
||||
if they were loaded previously.
|
||||
|
||||
```go
|
||||
AuthTool, err := client.LoadTool("my-tool", ctx, core.WithAuthTokenString("my-auth-1", "value"))
|
||||
|
||||
// or
|
||||
|
||||
AuthTools, err := client.LoadToolset(
|
||||
"my-toolset",
|
||||
ctx,
|
||||
core.WithAuthTokenString("my-auth-1", "value"),
|
||||
)
|
||||
```
|
||||
|
||||
{{< notice note >}}
|
||||
Adding auth tokens during loading only affect the tools loaded within that call.
|
||||
{{< /notice >}}
|
||||
|
||||
### Complete Authentication Example
|
||||
|
||||
```go
|
||||
import "github.com/googleapis/mcp-toolbox-sdk-go/core"
|
||||
import "fmt"
|
||||
|
||||
func getAuthToken() string {
|
||||
// ... Logic to retrieve ID token (e.g., from local storage, OAuth flow)
|
||||
// This example just returns a placeholder. Replace with your actual token retrieval.
|
||||
return "YOUR_ID_TOKEN" // Placeholder
|
||||
}
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
inputs := map[string]any{"input": "some input"}
|
||||
|
||||
dynamicTokenSource := core.NewCustomTokenSource(getAuthToken)
|
||||
|
||||
client, err := tbadk.NewToolboxClient("http://127.0.0.1:5000")
|
||||
tool, err := client.LoadTool("my-tool", ctx)
|
||||
AuthTool, err := tool.ToolFrom(core.WithAuthTokenSource("my_auth", dynamicTokenSource))
|
||||
|
||||
result, err := AuthTool.Run(ctx, inputs)
|
||||
|
||||
fmt.Println(result)
|
||||
}
|
||||
```
|
||||
|
||||
{{< notice note >}}An auth token getter for a specific name (e.g., "GOOGLE_ID") will replace any client header with the same name followed by "_token" (e.g.,"GOOGLE_ID_token").
|
||||
{{< /notice >}}
|
||||
|
||||
## Binding Parameter Values
|
||||
|
||||
The SDK allows you to pre-set, or "bind", values for specific tool parameters
|
||||
before the tool is invoked or even passed to an LLM. These bound values are
|
||||
fixed and will not be requested or modified by the LLM during tool use.
|
||||
|
||||
### Why Bind Parameters?
|
||||
|
||||
- **Protecting sensitive information:** API keys, secrets, etc.
|
||||
- **Enforcing consistency:** Ensuring specific values for certain parameters.
|
||||
- **Pre-filling known data:** Providing defaults or context.
|
||||
|
||||
{{< notice info >}}
|
||||
The parameter names used for binding (e.g., `"api_key"`) must exactly match the
|
||||
parameter names defined in the tool's configuration within the Toolbox service.
|
||||
{{< /notice >}}
|
||||
|
||||
{{< notice note >}}
|
||||
You do not need to modify the tool's configuration in the Toolbox service to bind parameter values using the SDK.
|
||||
{{< /notice >}}
|
||||
|
||||
#### Option A: Add Default Bound Parameters to a Client
|
||||
|
||||
You can add default tool level bound parameters to a client. Every tool / toolset
|
||||
loaded by the client will have the bound parameter.
|
||||
|
||||
```go
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
client, err := tbadk.NewToolboxClient("http://127.0.0.1:5000",
|
||||
core.WithDefaultToolOptions(
|
||||
core.WithBindParamString("param1", "value"),
|
||||
),
|
||||
)
|
||||
|
||||
boundTool, err := client.LoadTool("my-tool", ctx)
|
||||
```
|
||||
|
||||
### Option B: Binding Parameters to a Loaded Tool
|
||||
|
||||
Bind values to a tool object *after* it has been loaded. This modifies the
|
||||
specific tool instance.
|
||||
|
||||
```go
|
||||
client, err := tbadk.NewToolboxClient("http://127.0.0.1:5000")
|
||||
|
||||
tool, err := client.LoadTool("my-tool", ctx)
|
||||
|
||||
boundTool, err := tool.ToolFrom(
|
||||
core.WithBindParamString("param1", "value"),
|
||||
core.WithBindParamString("param2", "value")
|
||||
)
|
||||
```
|
||||
|
||||
### Option C: Binding Parameters While Loading Tools
|
||||
|
||||
Specify bound parameters directly when loading tools. This applies the binding
|
||||
only to the tools loaded in that specific call.
|
||||
|
||||
```go
|
||||
boundTool, err := client.LoadTool("my-tool", ctx, core.WithBindParamString("param", "value"))
|
||||
|
||||
// OR
|
||||
|
||||
boundTool, err := client.LoadToolset("", ctx, core.WithBindParamString("param", "value"))
|
||||
```
|
||||
|
||||
{{< notice note >}}
|
||||
Bound values during loading only affect the tools loaded in that call.
|
||||
{{< /notice >}}
|
||||
|
||||
### Binding Dynamic Values
|
||||
|
||||
Instead of a static value, you can bind a parameter to a synchronous or
|
||||
asynchronous function. This function will be called *each time* the tool is
|
||||
invoked to dynamically determine the parameter's value at runtime.
|
||||
Functions with the return type (data_type, error) can be provided.
|
||||
|
||||
```go
|
||||
getDynamicValue := func() (string, error) { return "req-123", nil }
|
||||
|
||||
dynamicBoundTool, err := tool.ToolFrom(core.WithBindParamStringFunc("param", getDynamicValue))
|
||||
```
|
||||
|
||||
{{< notice info >}}
|
||||
You don't need to modify tool configurations to bind parameter values.
|
||||
{{< /notice >}}
|
||||
|
||||
## Using with ADK Go
|
||||
|
||||
After altering the tool to your needs, type-assert the ToolboxTool and pass it to the LLM agent.
|
||||
|
||||
### For a single tool
|
||||
|
||||
```go
|
||||
|
||||
toolboxtool, err = client.LoadTool("my-tool", ctx)
|
||||
|
||||
// <Bind parameters & add authentication here>
|
||||
|
||||
llmagent, err := llmagent.New(llmagent.Config{
|
||||
Name: "assistant",
|
||||
Model: model,
|
||||
Description: "Agent to answer questions.",
|
||||
Tools: []tool.Tool{&toolboxtool},
|
||||
})
|
||||
```
|
||||
|
||||
### For a toolset
|
||||
|
||||
```go
|
||||
toolboxtools, err := client.LoadToolset("", ctx)
|
||||
|
||||
// <Bind parameters & add authentication here>
|
||||
|
||||
toolsList := make([]tool.Tool, len(toolboxtools))
|
||||
for i := range toolboxtools {
|
||||
toolsList[i] = &toolboxtools[i]
|
||||
}
|
||||
|
||||
llmagent, err := llmagent.New(llmagent.Config{
|
||||
Name: "assistant",
|
||||
Model: model,
|
||||
Description: "Agent to answer questions.",
|
||||
Tools: toolsList,
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
The reason we have to type assert it before passing it to ADK Go, is because it requires a generic `tool.Tool` interface. You can always convert it back to `ToolboxTool` format to access the specialized methods.
|
||||
|
||||
To see how the MCP Toolbox Go SDK works with ADK Go, check out the end-to-end example in the [/samples/](https://github.com/googleapis/mcp-toolbox-sdk-go/tree/main/tbadk/samples) folder.
|
||||
|
||||
# Contributing
|
||||
|
||||
Contributions are welcome! Please refer to the [DEVELOPER.md](/DEVELOPER.md)
|
||||
file for guidelines on how to set up a development environment and run tests.
|
||||
|
||||
# License
|
||||
|
||||
This project is licensed under the Apache License 2.0. See the
|
||||
[LICENSE](https://github.com/googleapis/mcp-toolbox-sdk-go/blob/main/LICENSE) file for details.
|
||||
|
||||
# Support
|
||||
|
||||
If you encounter issues or have questions, check the existing [GitHub Issues](https://github.com/googleapis/genai-toolbox/issues) for the main Toolbox project.
|
||||
|
||||
# Samples for Reference
|
||||
|
||||
These samples demonstrate how to integrate the MCP Toolbox Go tbADK SDK with popular orchestration frameworks.
|
||||
|
||||
<details>
|
||||
<summary>ADK Go</summary>
|
||||
|
||||
```go
|
||||
//This sample contains a complete example on how to integrate MCP Toolbox Go SDK with ADK Go using the tbadk package.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/googleapis/mcp-toolbox-sdk-go/tbadk"
|
||||
"google.golang.org/adk/agent"
|
||||
"google.golang.org/adk/agent/llmagent"
|
||||
"google.golang.org/adk/model/gemini"
|
||||
"google.golang.org/adk/runner"
|
||||
"google.golang.org/adk/session"
|
||||
"google.golang.org/adk/tool"
|
||||
"google.golang.org/genai"
|
||||
)
|
||||
|
||||
func main() {
|
||||
genaiKey := os.Getenv("GEMINI_API_KEY")
|
||||
toolboxURL := "http://localhost:5000"
|
||||
ctx := context.Background()
|
||||
|
||||
// Initialize MCP Toolbox client
|
||||
toolboxClient, err := tbadk.NewToolboxClient(toolboxURL)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create MCP Toolbox client: %v", err)
|
||||
}
|
||||
|
||||
toolsetName := "my-toolset"
|
||||
toolset, err := toolboxClient.LoadToolset(toolsetName, ctx)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to load MCP toolset '%s': %v\nMake sure your Toolbox server is running.", toolsetName, err)
|
||||
}
|
||||
|
||||
// Create Gemini model
|
||||
model, err := gemini.NewModel(ctx, "gemini-2.5-flash", &genai.ClientConfig{
|
||||
APIKey: genaiKey,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create model: %v", err)
|
||||
}
|
||||
|
||||
tools := make([]tool.Tool, len(toolset))
|
||||
for i := range toolset {
|
||||
tools[i] = &toolset[i]
|
||||
}
|
||||
|
||||
llmagent, err := llmagent.New(llmagent.Config{
|
||||
Name: "hotel_assistant",
|
||||
Model: model,
|
||||
Description: "Agent to answer questions about hotels.",
|
||||
Tools: tools,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create agent: %v", err)
|
||||
}
|
||||
|
||||
appName := "hotel_assistant"
|
||||
userID := "user-123"
|
||||
|
||||
sessionService := session.InMemoryService()
|
||||
resp, err := sessionService.Create(ctx, &session.CreateRequest{
|
||||
AppName: appName,
|
||||
UserID: userID,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create the session service: %v", err)
|
||||
}
|
||||
session := resp.Session
|
||||
|
||||
r, err := runner.New(runner.Config{
|
||||
AppName: appName,
|
||||
Agent: llmagent,
|
||||
SessionService: sessionService,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create runner: %v", err)
|
||||
}
|
||||
|
||||
query := "Find hotels with Basel in its name."
|
||||
|
||||
fmt.Println(query)
|
||||
userMsg := genai.NewContentFromText(query, genai.RoleUser)
|
||||
|
||||
streamingMode := agent.StreamingModeSSE
|
||||
for event, err := range r.Run(ctx, userID, session.ID(), userMsg, agent.RunConfig{
|
||||
StreamingMode: streamingMode,
|
||||
}) {
|
||||
if err != nil {
|
||||
fmt.Printf("\nAGENT_ERROR: %v\n", err)
|
||||
} else {
|
||||
if event.LLMResponse.Content != nil {
|
||||
for _, p := range event.LLMResponse.Content.Parts {
|
||||
if streamingMode != agent.StreamingModeSSE || event.LLMResponse.Partial {
|
||||
fmt.Print(p.Text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
Reference in New Issue
Block a user