## 1. Project Overview & Quickstart (googleapis/mcp-toolbox)

## File: docs/en/documentation/configuration/authentication/_index.md

---
title: "Authentication"
type: docs
weight: 1
  AuthServices represent services that handle authentication and authorization.
---

AuthServices represent services that handle authentication and authorization. They support two distinct modes of operation:

### 1. Toolbox Native Authorization
Used for specific tools to enforce authorization or resolve parameters:
- [**Authorized Invocation**][auth-invoke]: A tool is validated by the auth service before it can be invoked. Toolbox will reject any calls that fail to validate or have an invalid token.
- [**Authenticated Parameters**][auth-params]: Replaces the value of a parameter with a field from an [OIDC][openid-claims] claim. Toolbox will automatically resolve the ID token provided by the client and replace the parameter in the tool call.

### 2. MCP Authorization
Used to secure the entire MCP server. The Model Context Protocol supports [MCP Authorization](https://modelcontextprotocol.io/docs/tutorials/security/authorization) to secure interactions between clients and servers. When enabled, all MCP endpoints require a valid token, and you can enforce granular tool-level scope authorization. **Note that this mode is currently only supported when using the `generic` auth service type.**

[openid-claims]: https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
[auth-invoke]: ../tools/_index.md#authorized-invocations-toolbox-native-authorization
[auth-params]: ../tools/_index.md#authenticated-parameters

## Example

The following configurations are placed at the top level of a `tools.yaml` file.

{{< notice tip >}}
If you are accessing Toolbox with multiple applications, each
 application should register their own Client ID even if they use the same
 "type" of auth provider.
{{< /notice >}}

```yaml
kind: authService
name: my_auth_app_1
type: google
clientId: ${YOUR_CLIENT_ID_1}
---
kind: authService
name: my_auth_app_2
type: google
clientId: ${YOUR_CLIENT_ID_2}
```

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

After you've configured an `authService`, you can use it:
- For **Toolbox Native Authorization** by referencing it in your tool configuration (using `authRequired` or `authService` in parameters).
- For **MCP Authorization** by setting `mcpEnabled: true` in the auth service configuration to secure the entire server.

## Specifying ID Tokens from Clients

After [configuring](#example) your `authService`, use a Toolbox SDK to
add your ID tokens to the header of a Tool invocation request. When specifying a
token you will provide a function (that returns an id). This function is called
when the tool is invoked. This allows you to cache and refresh the ID token as
needed.

The primary method for providing these getters is via the `auth_token_getters`
parameter when loading tools, or the `add_auth_token_getter`() /
`add_auth_token_getters()` methods on a loaded tool object.

### Specifying tokens during load

#### Python

Use the [Python SDK](https://github.com/googleapis/mcp-toolbox-sdk-python/tree/main).

{{< tabpane persist=header >}}
{{< tab header="Core" lang="Python" >}}
import asyncio
from toolbox_core import ToolboxClient

async def get_auth_token():
    # ... 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

async def main():
    async with ToolboxClient("<http://127.0.0.1:5000>") as toolbox:
        auth_tool = await toolbox.load_tool(
            "get_sensitive_data",
            auth_token_getters={"my_auth_app_1": get_auth_token}
        )
        result = await auth_tool(param="value")
        print(result)

if **name** == "**main**":
    asyncio.run(main())
{{< /tab >}}
{{< tab header="LangChain" lang="Python" >}}
import asyncio
from toolbox_langchain import ToolboxClient

async def get_auth_token():
    # ... 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

async def main():
    toolbox = ToolboxClient("<http://127.0.0.1:5000>")

    auth_tool = await toolbox.aload_tool(
        "get_sensitive_data",
        auth_token_getters={"my_auth_app_1": get_auth_token}
    )
    result = await auth_tool.ainvoke({"param": "value"})
    print(result)

if **name** == "**main**":
    asyncio.run(main())
{{< /tab >}}
{{< tab header="Llamaindex" lang="Python" >}}
import asyncio
from toolbox_llamaindex import ToolboxClient

async def get_auth_token():
    # ... 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

async def main():
    toolbox = ToolboxClient("<http://127.0.0.1:5000>")

    auth_tool = await toolbox.aload_tool(
        "get_sensitive_data",
        auth_token_getters={"my_auth_app_1": get_auth_token}
    )
    # result = await auth_tool.acall(param="value")
    # print(result.content)

if **name** == "**main**":
    asyncio.run(main()){{< /tab >}}
{{< /tabpane >}}

#### Javascript/Typescript

Use the [JS SDK](https://github.com/googleapis/mcp-toolbox-sdk-js/tree/main).

```javascript
import { ToolboxClient } from '@toolbox-sdk/core';

async function getAuthToken() {
    // ... 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
}

const URL = 'http://127.0.0.1:5000';
let client = new ToolboxClient(URL);
const authTool = await client.loadTool("my-tool", {"my_auth_app_1": getAuthToken});
const result = await authTool({param:"value"});
console.log(result);
print(result)
```

#### Go

Use the [Go SDK](https://github.com/googleapis/mcp-toolbox-sdk-go/tree/main).

```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() {
  URL := "http://127.0.0.1:5000"
  client, err := core.NewToolboxClient(URL)
  if err != nil {
    log.Fatalf("Failed to create Toolbox client: %v", err)
    }
  dynamicTokenSource := core.NewCustomTokenSource(getAuthToken)
  authTool, err := client.LoadTool(
    "my-tool",
    ctx,
    core.WithAuthTokenSource("my_auth_app_1", dynamicTokenSource))
  if err != nil {
    log.Fatalf("Failed to load tool: %v", err)
  }
  inputs := map[string]any{"param": "value"}
  result, err := authTool.Invoke(ctx, inputs)
  if err != nil {
    log.Fatalf("Failed to invoke tool: %v", err)
  }
  fmt.Println(result)
}
```

### Specifying tokens for existing tools

#### Python

Use the [Python
SDK](https://github.com/googleapis/mcp-toolbox-sdk-python/tree/main).

{{< tabpane persist=header >}}
{{< tab header="Core" lang="Python" >}}
tools = await toolbox.load_toolset()

# for a single token

authorized_tool = tools[0].add_auth_token_getter("my_auth", get_auth_token)

# OR, if multiple tokens are needed

authorized_tool = tools[0].add_auth_token_getters({
  "my_auth1": get_auth1_token,
  "my_auth2": get_auth2_token,
})
{{< /tab >}}
{{< tab header="LangChain" lang="Python" >}}
tools = toolbox.load_toolset()

# for a single token

authorized_tool = tools[0].add_auth_token_getter("my_auth", get_auth_token)

# OR, if multiple tokens are needed

authorized_tool = tools[0].add_auth_token_getters({
  "my_auth1": get_auth1_token,
  "my_auth2": get_auth2_token,
})
{{< /tab >}}
{{< tab header="Llamaindex" lang="Python" >}}
tools = toolbox.load_toolset()

# for a single token

authorized_tool = tools[0].add_auth_token_getter("my_auth", get_auth_token)

# OR, if multiple tokens are needed

authorized_tool = tools[0].add_auth_token_getters({
  "my_auth1": get_auth1_token,
  "my_auth2": get_auth2_token,
})
{{< /tab >}}
{{< /tabpane >}}

#### Javascript/Typescript

Use the [JS SDK](https://github.com/googleapis/mcp-toolbox-sdk-js/tree/main).

```javascript
const URL = 'http://127.0.0.1:5000';
let client = new ToolboxClient(URL);
let tool = await client.loadTool("my-tool")

// for a single token
const authorizedTool = tool.addAuthTokenGetter("my_auth", get_auth_token)

// OR, if multiple tokens are needed
const multiAuthTool = tool.addAuthTokenGetters({
    "my_auth_1": getAuthToken1,
    "my_auth_2": getAuthToken2,
})

```

#### Go

Use the [Go SDK](https://github.com/googleapis/mcp-toolbox-sdk-go/tree/main).

```go
import "github.com/googleapis/mcp-toolbox-sdk-go/core"

func main() {
  URL := "http://127.0.0.1:5000"
  client, err := core.NewToolboxClient(URL)
  if err != nil {
    log.Fatalf("Failed to create Toolbox client: %v", err)
  }
  tool, err := client.LoadTool("my-tool", ctx)
  if err != nil {
    log.Fatalf("Failed to load tool: %v", err)
  }
  dynamicTokenSource1 := core.NewCustomTokenSource(getAuthToken1)
  dynamicTokenSource2 := core.NewCustomTokenSource(getAuthToken1)

  // For a single token
  authTool, err := tool.ToolFrom(
    core.WithAuthTokenSource("my-auth", dynamicTokenSource1),
  )

  // OR, if multiple tokens are needed
  authTool, err := tool.ToolFrom(
    core.WithAuthTokenSource("my-auth_1", dynamicTokenSource1),
    core.WithAuthTokenSource("my-auth_2", dynamicTokenSource2),
  )
}
```

## Types of Auth Services

---

## File: docs/en/documentation/configuration/authentication/generic.md

---
title: "Generic OIDC Auth"
type: docs
weight: 2
  Use a Generic OpenID Connect (OIDC) provider for OAuth 2.0 flow and token
  lifecycle.
---

## Getting Started

The Generic Auth Service allows you to integrate with any OpenID Connect (OIDC)
compliant identity provider (IDP). It discovers the JWKS (JSON Web Key Set) URL
either through the provider's `/.well-known/openid-configuration` endpoint or
directly via the provided `authorizationServer`.

To configure this auth service, you need to provide the `audience` (the expected `aud` claim in the token), the `authorizationServer` of your identity provider, and optionally a list of `scopesRequired` that must be present in the token's claims.

> [!NOTE]
> The only time the `aud` claim matches the `client_id` is inside an ID Token (a concept from OpenID Connect used to verify a user's identity). Because an ID token is intended to be consumed by the client application itself, the client is the audience.

## Usage Modes

The Generic Auth Service supports two distinct modes of operation:

### 1. Toolbox Auth

This mode is used for Toolbox's native authentication/authorization features. It
is active when you reference the auth service in a tool's configuration and
`mcpEnabled` is set to false.

- **Header**: Expects the token in a custom header matching `<name>_token`
  (e.g., `my-generic-auth_token`).
- **Token Type**: Only supports **JWT** (OIDC) tokens.
- **Usage**: Used for [Authenticated Parameters][auth-params] and [Authorized
  Invocations][auth-invoke].

#### Token Validation

When a request is received in this mode, the service will:

1. Extract the token from the `<name>_token` header.
2. Treat it as a JWT (opaque tokens are not supported in this mode).
3. Validates signature using JWKS fetched from `authorizationServer`.
4. Verifies expiration (`exp`) and audience (`aud`).
5. Verifies required scopes in `scope` claim.

#### Example

```yaml
kind: authService
name: my-generic-auth
type: generic
audience: ${YOUR_OIDC_AUDIENCE}
authorizationServer: https://your-idp.example.com
# mcpEnabled: false
scopesRequired:
  - read
  - write
```

#### Tool Usage Example

To use this auth service for **Authenticated Parameters** or **Authorized
Invocations**, reference it in your tool configuration:

```yaml
kind: tool
name: secure_query
type: postgres-sql
source: my-pg-instance
statement: |
  SELECT * FROM data WHERE user_id = $1
parameters:
  - name: user_id
    type: strings
    description: Auto-populated from token
    authServices:
      - name: my-generic-auth
        field: sub # Extract 'sub' claim from JWT
authRequired:
  - my-generic-auth # Require valid token for invocation
```

### 2. MCP Authorization

This mode enforces global authentication for all MCP endpoints. It is active
when `mcpEnabled` is set to `true` in the auth service configuration.

- **Header**: Expects the token in the standard `Authorization: Bearer <token>`
  header.
- **Token Type**: Supports both **JWT** and **Opaque** tokens.
- **Usage**: Used to secure the entire MCP server.

#### Token Validation

When a request is received in this mode, the service will:

1. Extract the token from the `Authorization` header after `Bearer ` prefix.
2. Determine if the token is a JWT or an opaque token based on format (JWTs
   contain exactly two dots).
3. For **JWTs**:
   - Validates signature using JWKS fetched from `authorizationServer`.
   - Verifies expiration (`exp`) and audience (`aud`).
   - Verifies required scopes in `scope` claim.
4. For **Opaque Tokens**:
   - Calls the introspection endpoint (either configured via `introspectionEndpoint`
     or discovered from the `authorizationServer`'s OIDC configuration).
   - Verifies expiration (`exp`) and audience (`aud` or `"audience"` fallback).
   - Verifies required scopes in `scope` field.

#### Example

```yaml
kind: authService
name: my-generic-auth
type: generic
audience: ${YOUR_TOKEN_AUDIENCE}
authorizationServer: https://your-idp.example.com
mcpEnabled: true
scopesRequired:
  - read
  - write
```

#### Google Authentication Note

> [!WARNING]
> Do not configure Google's tokeninfo endpoint (`https://oauth2.googleapis.com/tokeninfo`) using `type: generic`. Because the generic OIDC service strictly enforces the presence and validity of the `active` claim (RFC 7662), and Google's tokeninfo endpoint does not return this claim, validation will fail.
>
> To authenticate with Google tokens, use the native [Google Sign-In](./google.md) auth service (`type: google`) instead, which natively handles Google's endpoints and token formats.

#### Okta OIDC Configuration Example

To secure your MCP server or tools using Okta as the identity provider:

```yaml
kind: authService
name: okta-auth
type: generic
audience: api://default # Or your custom Okta audience
authorizationServer: https://your-subdomain.okta.com/oauth2/default
mcpEnabled: true
scopesRequired:
  - openid
  - profile
```

> [!NOTE]
> If you are using Okta's Org Authorization Server (instead of a Custom Authorization Server), your `authorizationServer` URL will be `https://your-subdomain.okta.com`.

#### Tool-Level Scopes

When using MCP Authorization (with `mcpEnabled: true` in the auth service), you can enforce granular tool-level scope authorization by specifying the `scopesRequired` field in the tool configuration.

This ensures that a client can only invoke the tool if their authorization token contains all the specified scopes.

```yaml
kind: tool
name: update_flight_status
type: postgres-sql
source: my-pg-instance
statement: |
  UPDATE flights SET status = $1 WHERE flight_number = $2
description: Update flight status
authRequired:
  - my-generic-auth
scopesRequired:
  - execute:sql
  - write:flights
```

If a client attempts to invoke this tool without the required scopes, the server will return an HTTP 403 Forbidden response with a `WWW-Authenticate` header challenge indicating the missing scopes, as per the MCP Auth specification.

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

[auth-invoke]: ../tools/_index.md#authorized-invocations
[auth-params]: ../tools/_index.md#authenticated-parameters
[mcp-auth]: https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization

## Reference

| **field**              | **type** | **required** | **description**                                                                                                                                                                                       |
| ---------------------- | :------: | :----------: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type                   |  string  |     true     | Must be "generic".                                                                                                                                                                                    |
| audience               |  string  |     true     | The expected audience (`aud` claim) in the token. This ensures the token was minted specifically for your application. See [Getting Started](#getting-started) for details on OIDC audience matching. |
| authorizationServer    |  string  |     true     | The base URL of your OIDC provider. The service will append `/.well-known/openid-configuration` to discover the JWKS URI. HTTP is allowed but logs a warning.                                         |
| mcpEnabled             |   bool   |    false     | Indicates if MCP endpoint authentication should be applied. Defaults to false.                                                                                                                        |
| scopesRequired         | []string |    false     | A list of required scopes that must be present in the token's `scope` claim to be considered valid. Disallowed if `mcpEnabled` is false.                                                             |
| introspectionEndpoint  |  string  |    false     | Optional override for the token introspection URL. Useful if the provider does not list it in OIDC discovery (e.g., Google). Disallowed if `mcpEnabled` is false.                                   |
| introspectionMethod    |  string  |    false     | HTTP method to use for introspection. Defaults to "POST". Set to "GET" for providers like Google. Disallowed if `mcpEnabled` is false.                                                               |
| introspectionParamName |  string  |    false     | Parameter name for the token in the introspection request. Defaults to "token". Set to "access_token" for Google. Disallowed if `mcpEnabled` is false.                                               |

---

## File: docs/en/documentation/configuration/authentication/google.md

---
title: "Google Sign-In"
type: docs
weight: 1
  Use Google Sign-In for OAuth 2.0 flow and token lifecycle.
---

## Getting Started

Google Sign-In manages the OAuth 2.0 flow and token lifecycle. To integrate the Google Sign-In workflow to your web app, [follow this guide][gsi-setup].

After setting up Google Sign-In, configure your auth service in the toolbox. The Google auth provider supports two distinct validation modes:

1. **Web App Claims (OIDC)**: Used to authenticate user requests in web applications.
2. **MCP Authorization**: Used to secure the entire MCP server transport (SSE or Stdio).

[gsi-setup]: https://developers.google.com/identity/sign-in/web/sign-in

## Configuration Modes

### 1. Web App OIDC Authentication
If you are developing a web application using the Toolbox and need to retrieve user claims from Google ID tokens sent in custom request headers, configure the `clientId` field.

- **Header**: Expects the token in the `<name>_token` header (e.g. `my-google-auth_token`).
- **Token Type**: Google OIDC ID tokens (JWT).

#### Example
```yaml
kind: authService
name: my-google-auth
type: google
clientId: ${YOUR_GOOGLE_CLIENT_ID}
```

---

### 2. MCP Authorization
To secure all endpoints on your MCP server using Google OAuth tokens, enable `mcpEnabled` and specify the `audience` field.

- **Header**: Expects the token in the standard `Authorization: Bearer <token>` header.
- **Token Type**: Supports both Google **ID tokens (JWT)** and Google **opaque access tokens**.

#### Example
```yaml
kind: authService
name: my-google-auth
type: google
audience: ${YOUR_GOOGLE_CLIENT_ID}
mcpEnabled: true
scopesRequired:
  - https://www.googleapis.com/auth/userinfo.email
```

> [!IMPORTANT]
> - For **ID tokens (JWT)**: Local cryptographic signature verification is performed, which requires `audience` to be configured. If `audience` is not set, the provider will fall back to using `clientId`. If neither is configured, validation will fail.
> - For **Opaque tokens**: The provider automatically queries Google's secure tokeninfo endpoint (`https://oauth2.googleapis.com/tokeninfo`) and validates the resulting audience against the configured `audience` field (falling back to `clientId` if `audience` is not set).

---

## Behavior

### Authorized Invocations
When using [Authorized Invocations][auth-invoke], a tool will be considered authorized if it has a valid OAuth 2.0 token that matches the Client ID or Audience.

[auth-invoke]: ../tools/_index.md#authorized-invocations

### Authenticated Parameters
When using [Authenticated Parameters][auth-params], any [claim provided by the id-token][provided-claims] can be used for the parameter.

[auth-params]: ../tools/_index.md#authenticated-parameters
[provided-claims]: https://developers.google.com/identity/openid-connect/openid-connect#obtaininguserprofileinformation

---

## Reference

| **field**      | **type** | **required** | **description**                                                                                                                              |
|----------------|:--------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------------|
| type           |  string  |     true     | Must be "google".                                                                                                                            |
| clientId       |  string  |    false     | Client ID of your application. Required for validating ID tokens in non-MCP web apps (`GetClaimsFromHeader`), and acts as a fallback for `audience` in MCP auth mode if `audience` is not configured. |
| audience       |  string  |    false     | Expected audience. Required for validating ID tokens in MCP Auth mode (unless `clientId` is configured as a fallback). If specified, also validates opaque token audiences. Disallowed if `mcpEnabled` is false. |
| mcpEnabled     |   bool   |    false     | Enforces global MCP transport authentication using the `Authorization: Bearer` header. Defaults to false.                                    |
| scopesRequired | []string |    false     | A list of required scopes that must be present in the token's claims/metadata to be considered valid. Disallowed if `mcpEnabled` is false. |

---

## File: docs/en/documentation/configuration/embedding-models/_index.md

---
title: "EmbeddingModels"
type: docs
weight: 7
  EmbeddingModels represent services that transform text into vector embeddings
  for semantic search.
---

EmbeddingModels represent services that generate vector representations of text
data. In the MCP Toolbox, these models enable **Semantic Queries**, allowing
[Tools](../tools/_index.md) to automatically convert human-readable text into numerical
vectors before using them in a query.

This is primarily used in two scenarios:

- **Vector Ingestion**: Converting a text parameter into a vector string during
  an `INSERT` operation.

- **Semantic Search**: Converting a natural language query into a vector to
  perform similarity searches.

## Hidden Parameter Duplication (valueFromParam)

When building tools for vector ingestion, you often need the same input string
twice:

1. To store the original text in a TEXT column.
1. To generate the vector embedding for a VECTOR column.

Requesting an Agent (LLM) to output the exact same string twice is inefficient
and error-prone. The `valueFromParam` field solves this by allowing a parameter
to inherit its value from another parameter in the same tool.

### Key Behaviors

1. Hidden from Manifest: Parameters with valueFromParam set are excluded from
   the tool definition sent to the Agent. The Agent does not know this parameter
   exists.
1. Auto-Filled: When the tool is executed, the Toolbox automatically copies the
   value from the referenced parameter before processing embeddings.

## Example

The following configuration defines an embedding model and applies it to
specific tool parameters.

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

### Step 1 - Define an Embedding Model

Define an embedding model with the `embeddingModel` kind:

```yaml
kind: embeddingModel
name: gemini-model # Name of the embedding model
type: gemini
model: gemini-embedding-001
apiKey: ${GOOGLE_API_KEY}
dimension: 768
```

### Step 2 - Embed Tool Parameters

Use the defined embedding model, embed your query parameters using the
`embeddedBy` field. Only string-typed parameters can be embedded:

```yaml
# Vector ingestion tool
kind: tool
name: insert_embedding
type: postgres-sql
source: my-pg-instance
description: Insert a new document into the database.
statement: |
  INSERT INTO documents (content, embedding)
  VALUES ($1, $2);
parameters:
  - name: content
    type: string
    description: The raw text content to be stored in the database.
  - name: vector_string
    type: string
    description: A hidden parameter holding a copy of 'content' to be embedded as a vector.
    # This parameter is hidden from the LLM.
    # It automatically copies the value from 'content' and embeds it.
    valueFromParam: content
    embeddedBy: gemini-model
---
# Semantic search tool
kind: tool
name: search_embedding
type: postgres-sql
source: my-pg-instance
description: Search for documents in the database.
statement: |
  SELECT id, content, embedding <-> $1 AS distance
  FROM documents
  ORDER BY distance LIMIT 1
parameters:
  - name: semantic_search_string
    type: string
    description: The search query that will be converted to a vector.
    embeddedBy: gemini-model # refers to the name of a defined embedding model
```

## Types of Embedding Models

---

## File: docs/en/documentation/configuration/embedding-models/gemini.md

---
title: "Gemini Embedding"
type: docs
weight: 1
  Use Google's Gemini models to generate high-performance text embeddings for
  vector databases.
---

## About

Google Gemini provides state-of-the-art embedding models that convert text into
high-dimensional vectors.

### Authentication

Toolbox supports two authentication modes:

1.  **Google AI (API Key):** Used if you
    provide `apiKey` (or set `GOOGLE_API_KEY`/`GEMINI_API_KEY` environment
    variables). This uses the [Google AI Studio][ai-studio] backend.
2.  **Vertex AI (ADC):** Used if provided `project` and `location` (or set
    `GOOGLE_CLOUD_PROJECT`/`GOOGLE_CLOUD_LOCATION` environment variables). This uses [Application
    Default Credentials (ADC)][adc].

We recommend using an API key for quick testing and using Vertex AI with ADC for
production environments.

[adc]: https://cloud.google.com/docs/authentication#adc
[api-key]: https://ai.google.dev/gemini-api/docs/api-key#api-keys
[ai-studio]: https://aistudio.google.com/app/apikey

## Behavior

### Automatic Vectorization

When a tool parameter is configured with `embeddedBy: <your-gemini-model-name>`,
the Toolbox intercepts the raw text input from the client and sends it to the
Gemini API. The resulting numerical array is then formatted before being passed
to your database source.

### Dimension Matching

The `dimension` field must match the expected size of your database column
(e.g., a `vector(768)` column in PostgreSQL). This setting is supported by newer
models since 2024 only. You cannot set this value if using the earlier model
(`models/embedding-001`). Check out [available Gemini models][modellist] for
more information.

[modellist]:
  https://docs.cloud.google.com/vertex-ai/generative-ai/docs/embeddings/get-text-embeddings#supported-models

## Example

### Using Google AI

Google AI uses API Key for authentication. You can get an API key from [Google
AI Studio][ai-studio].

```yaml
kind: embeddingModel
name: gemini-model
type: gemini
model: gemini-embedding-001
apiKey: ${GOOGLE_API_KEY}
dimension: 768
```

### Using Vertex AI

Vertex AI uses Application Default Credentials (ADC) for authentication. Learn
how to set up ADC [here][adc].

```yaml
kind: embeddingModel
name: gemini-model
type: gemini
model: gemini-embedding-001
project: ${GOOGLE_CLOUD_PROJECT}
location: us-central1
dimension: 768
```

[adc]: https://docs.cloud.google.com/docs/authentication/provide-credentials-adc

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

## Reference

| **field**   | **type** | **required** | **description**                                                                                                                                      |
| ----------- | :------: | :----------: | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| type        |  string  |     true     | Must be `gemini`.                                                                                                                                    |
| model       |  string  |     true     | The Gemini model ID to use (e.g., `gemini-embedding-001`).                                                                                             |
| dimension   | integer  |    false     | The number of dimensions in the output vector (e.g., `768`).                                                                                         |

---

## File: docs/en/documentation/configuration/groups/_index.md

---
title: "Groups"
type: docs
weight: 6
  Groups let you scope MCP primitives such as tools, prompts, resources, and resource templates together under a single name, with a description used as group metadata.
---

A Group is a single named collection that scopes MCP primitives together — including [**tools**](../tools/_index.md), [**prompts**](../prompts/_index.md), [**resources**](../resources/_index.md), and [**resource templates**](../resources/template/_index.md). Where a [Toolset](../toolsets/_index.md) groups only tools, a group bundles these primitives under one name and one MCP endpoint, and carries a `description` that describes the collection.

Connecting to a group's endpoint (`/mcp/{name}`) scopes the corresponding MCP list methods (such as `tools/list`, `prompts/list`, `resources/list`, `resources/templates/list`, and `resources/read`) to that group. Groups are also introspectable over MCP through methods which are available on the `com.google.cloud/toolbox.v1` [extension](https://github.com/googleapis/mcp-toolbox/tree/main/extensions).

## Defining Groups

Declare a group as a `kind: group` document in your configuration file. A group has the following fields:

| Field               | Required | Description                                                                                    |
| ------------------- | -------- | -----------------------------------------------------------------------------------------------|
| `name`              | Yes\*    | Unique name for the group. Used as the endpoint path (`/mcp/{name}`).                          |
| `description`       | No       | Human-readable description of the group, surfaced via `groups/list`.                           |
| `tools`             | No       | List of tool names to include in the group.                                                    |
| `prompts`           | No       | List of prompt names to include in the group.                                                  |
| `resources`         | No       | List of resource names to include in the group.                                                |
| `resourceTemplates` | No       | List of resource template names to include in the group.                                       |
| `ttlMs`             | No       | Time-to-live in milliseconds for cached group list responses. ([MCP TTL Spec](https://modelcontextprotocol.io/specification/2026-07-28/server/utilities/caching#time-to-live-ttl-field )). Defaults to `300000` (5 minutes).|
| `cacheScope`        | No       | Cache visibility for group list responses (either `public` or `private`). ([MCP Cache Scope Spec](https://modelcontextprotocol.io/specification/2026-07-28/server/utilities/caching#cache-scope-field)). Defaults to `public`.|

\* `name` is required for every named group. The single [default group](#the-default-group) omits it.

```yaml
kind: group
name: data_analyst
description: Tools, prompts, and resources for exploratory data analysis.
tools:
  - list_tables
  - execute_sql
prompts:
  - summarize_results
resources:
  - database_schema
resourceTemplates:
  - query_logs
---
kind: group
name: admin
description: Administrative operations.
tools:
  - create_user
  - list_users
resources:
  - admin_guide
ttlMs: 3600000
cacheScope: private
```

## The default group

A single **default (nameless) group** always exists and contains **all** configured primitives (every tool, prompt, resource, and resource template). Connecting to the default MCP endpoint (`/mcp`) returns everything.

You may declare a `kind: group` document with no `name` to set a `description` for the default group. Because the default group always contains everything, it **cannot** declare `tools`, `prompts`, `resources`, `resourceTemplates`, or any other primitive list:

```yaml
kind: group
description: All tools, prompts, and resources available on this server.
```

## Validation rules

At startup, Toolbox validates groups:

- **Unique names.** A named group must have a unique name that satisfies the standard name rules (alphanumeric characters, underscores, and hyphens).
- **One default group.** Declaring more than one nameless group is an error.
- **Default group restrictions.** The default group may set only a `description`; declaring `tools`, `prompts`, `resources`, `resourceTemplates`, or any other primitive list on it is an error.
- **No duplicate names across toolsets and groups.** A `kind: toolset` is parsed as a group, so defining the same name as both a `kind: toolset` and a `kind: group` is a duplicate-name error.
- **Valid parameters.** If specified, `ttlMs` must be non-negative (>=0), and `cacheScope` must be either `public` or `private`.
- **No UI resources in groups.** UI resources and UI resource templates (`ui: true`) are strictly global and cannot be included in `resources` or `resourceTemplates` of any group. Attempting to add a UI resource to a group fails startup validation. (See [MCP Apps](../mcp-apps/) for details on linking tools to UI resources.)

## Relationship to toolsets

Groups are a superset of toolsets: a toolset is equivalent to a tools-only group. Existing `kind: toolset` configurations still load — Toolbox parses every toolset as a group — but that parity is not exact, so review the differences below before assuming a toolset behaves as it did:

- A toolset has no `description` of its own, so one written on a `kind: toolset` is dropped rather than promoted, and Toolbox logs a warning. To give a collection a description, declare it as a `kind: group`.
- Unrecognized fields on a toolset are rejected at startup instead of being silently ignored.
- Declaring the same name as both a `kind: toolset` and a `kind: group` is a duplicate-name error; previously the group silently took precedence.

We recommend migrating to a `kind: group` even for tools-only collections, so the configuration matches what Toolbox actually loads and can grow to scope prompts, resources, and resource templates alongside tools. See [Toolsets](../toolsets/_index.md) for more.

To convert existing toolsets to groups automatically, run the `migrate` command. It rewrites both nested `toolsets:` blocks and already-flat `kind: toolset` documents to `kind: group`:

```bash
toolbox migrate --config tools.yaml
```

Use `--dry-run` to preview the changes without writing them.

---

## File: docs/en/documentation/configuration/pre-post-processing/go/_index.md

---
title: "Go: Pre & Post Processing"
type: docs
weight: 3
  How to add pre- and post- processing to your Agents using Go.
sample_filters: ["Pre & Post Processing", "Go", "ADK"]
is_sample: true
---

## Prerequisites

This tutorial assumes that you have set up MCP Toolbox with a basic agent as described in the [local quickstart](../../../getting-started/local_quickstart_go.md).

This guide demonstrates how to implement these patterns in your Toolbox applications.

## Implementation

{{< tabpane persist=header >}}
{{% tab header="ADK" text=true %}}
The following example demonstrates how to use the `beforeToolCallback` and `afterToolCallback` hooks in the ADK `LlmAgent` to implement pre and post processing logic.

{{< include "adk/agent.go" "go" >}}

You can also add model-level (`beforeModelCallback`, `afterModelCallback`) and agent-level (`beforeAgentCallback`, `afterAgentCallback`) hooks to intercept messages at different stages of the execution loop.

For more information, see the [ADK Callbacks documentation](https://google.github.io/adk-docs/callbacks/types-of-callbacks/).{{% /tab %}}
{{< /tabpane >}}

## Results

The output should look similar to the following.

{{< notice note >}}
The exact responses may vary due to the non-deterministic nature of LLMs and differences between orchestration frameworks.
{{< /notice >}}

```
AI: Booking Confirmed! You earned 500 Loyalty Points with this stay.

AI: Error: Maximum stay duration is 14 days.
```

---

## File: docs/en/documentation/configuration/pre-post-processing/js/_index.md

---
title: "Javascript: Pre & Post Processing"
type: docs
weight: 2
  How to add pre- and post- processing to your Agents using JS.
sample_filters: ["Pre & Post Processing", "JavaScript", "ADK", "LangChain"]
is_sample: true
---

## Prerequisites

This tutorial assumes that you have set up MCP Toolbox with a basic agent as described in the [local quickstart](../../../getting-started/local_quickstart_js.md).

This guide demonstrates how to implement these patterns in your Toolbox applications.

## Implementation

{{< tabpane persist=header >}}
{{% tab header="ADK" text=true %}}
The following example demonstrates how to use the `beforeToolCallback` and `afterToolCallback` hooks in the ADK `LlmAgent` to implement pre and post processing logic.

{{< include "adk/agent.js" "js" >}}

You can also add model-level (`beforeModelCallback`, `afterModelCallback`) and agent-level (`beforeAgentCallback`, `afterAgentCallback`) hooks to intercept messages at different stages of the execution loop. 

For more information, see the [ADK Callbacks documentation](https://google.github.io/adk-docs/callbacks/types-of-callbacks/).
{{% /tab %}}
{{% tab header="Langchain" text=true %}}
The following example demonstrates how to use `ToolboxClient` with LangChain's middleware to implement pre and post processing for tool calls.

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

You can also use the `wrapModelCall` hook to intercept messages before and after model calls.
You can also use [node-style hooks](https://docs.langchain.com/oss/javascript/langchain/middleware/custom#node-style-hooks) to intercept messages at the agent and model level.
See the [LangChain Middleware documentation](https://docs.langchain.com/oss/javascript/langchain/middleware/custom#tool-call-monitoring) for details on these additional hook types.

{{% /tab %}}
{{< /tabpane >}}

## Results

The output should look similar to the following.

{{< notice note >}}
The exact responses may vary due to the non-deterministic nature of LLMs and differences between orchestration frameworks.
{{< /notice >}}

```
AI: Booking Confirmed! You earned 500 Loyalty Points with this stay.

AI: Error: Maximum stay duration is 14 days.
```

---

## File: docs/en/documentation/configuration/pre-post-processing/python/_index.md

---
title: "Python: Pre & Post Processing"
type: docs
weight: 1
  How to add pre- and post- processing to your Agents using Python.
sample_filters: ["Pre & Post Processing", "Python", "ADK", "LangChain"]
is_sample: true
---

## Prerequisites

This tutorial assumes that you have set up MCP Toolbox with a basic agent as described in the [local quickstart](../../../getting-started/local_quickstart.md).

This guide demonstrates how to implement these patterns in your Toolbox applications.

## Implementation

{{< tabpane persist=header >}}
{{% tab header="ADK" text=true %}}
The following example demonstrates how to use `ToolboxToolset` with ADK's pre and post processing hooks to implement pre and post processing for tool calls.

{{< include "adk/agent.py" "python">}}

You can also add model-level (`before_model_callback`, `after_model_callback`) and agent-level (`before_agent_callback`, `after_agent_callback`) hooks to intercept messages at different stages of the execution loop.

For more information, see the [ADK Callbacks documentation](https://google.github.io/adk-docs/callbacks/types-of-callbacks/).
{{% /tab %}}
{{% tab header="Langchain" text=true %}}
The following example demonstrates how to use `ToolboxClient` with LangChain's middleware to implement pre- and post- processing for tool calls.

{{< include "langchain/agent.py" "python" >}}

You can also add model-level (`wrap_model`) and agent-level (`before_agent`, `after_agent`) hooks to intercept messages at different stages of the execution loop. See the [LangChain Middleware documentation](https://docs.langchain.com/oss/python/langchain/middleware/custom#wrap-style-hooks) for details on these additional hook types.
{{% /tab %}}
{{< /tabpane >}}

## Results

The output should look similar to the following.

{{< notice note >}}
The exact responses may vary due to the non-deterministic nature of LLMs and differences between orchestration frameworks.
{{< /notice >}}

```
AI: Booking Confirmed! You earned 500 Loyalty Points with this stay.

AI: Error: Maximum stay duration is 14 days.
```

---

## File: docs/en/documentation/configuration/pre-post-processing/_index.md

---
title: "Pre- and Post- Processing"
type: docs
weight: 13
  Intercept and modify interactions between the agent and its tools either before or after a tool is executed.
---

Pre- and post- processing allow developers to intercept and modify interactions between the agent and its tools or the user.

{{< notice note >}}

These capabilities are typically features of **orchestration frameworks** (like LangChain, LangGraph, or Agent Builder) rather than the Toolbox SDK itself. However, Toolbox tools are designed to fully leverage these framework capabilities to support robust, secure, and compliant agent architectures.

{{< /notice >}}

## Types of Processing

### Pre-processing

Pre-processing occurs before a tool is executed or an agent processes a message. Key types include:

- **Input Sanitization & Redaction**: Detecting and masking sensitive information (like PII) in user queries or tool arguments to prevent it from being logged or sent to unauthorized systems.
- **Business Logic Validation**: Verifying that the proposed action complies with business rules (e.g., ensuring a requested hotel stay does not exceed 14 days, or checking if a user has sufficient permission).
- **Security Guardrails**: Analyzing inputs for potential prompt injection attacks or malicious payloads.

### Post-processing

Post-processing occurs after a tool has executed or the model has generated a response. Key types include:

- **Response Enrichment**: Injecting additional data into the tool output that wasn't part of the raw API response (e.g., calculating loyalty points earned based on the booking value).
- **Output Formatting**: Transforming raw data (like JSON or XML) into a more human-readable or model-friendly format to improve the agent's understanding.
- **Compliance Auditing**: Logging the final outcome of transactions, including the original request and the result, to a secure audit trail.

## Processing Scopes

While processing logic can be applied at various levels (Agent, Model, Tool), this guide primarily focuses on **Tool Level** processing, which is most relevant for granular control over tool execution.

### Tool Level (Primary Focus)

Wraps individual tool executions. This is best for logic specific to a single tool or a set of tools.

- **Scope**: Intercepts the raw inputs (arguments) to a tool and its outputs.
- **Use Cases**: Argument validation, output formatting, specific privacy rules for sensitive tools.

### Other Levels

It is helpful to understand how tool-level processing differs from other scopes:

- **Model Level**: Intercepts individual calls to the LLM (prompts and responses). Unlike tool-level, this applies globally to all text sent/received, making it better for global PII redaction or token tracking.
- **Agent Level**: Wraps the high-level execution loop (e.g., a "turn" in the conversation). Unlike tool-level, this envelopes the entire turn (user input to final response), making it suitable for session management or end-to-end auditing.

## Best Practices

### Security & Guardrails

- **Principle of Least Privilege**: Ensure that tools run with the minimum necessary permissions. Middleware is an excellent place to enforce "read-only" modes or verify user identity before executing sensitive actions.
- **Input Sanitization**: Actively strip potential PII (like credit card numbers or raw emails) from tool arguments before logging them.
- **Prompt Injection Defense**: Use pre-processing hooks to scan user inputs for known jailbreak patterns or malicious directives before they reach the model or tools.

### Observability & Debugging

- **Structured Logging**: Instead of simple print statements, use structured JSON logging with correlation IDs. This allows you to trace a single user request through multiple agent turns and tool calls.
- **Logging for Testability**: LLM responses are non-deterministic and may summarize away key details.
  - **Pattern**: Add explicit logging markers in your post-processing middleware (e.g., `logger.info("ACTION_SUCCESS: ")`).
  - **Benefit**: Your integration tests can grep logs for these stable markers to verify tool success, rather than painfully parsing variable natural language responses.

### Performance & Cost Optimization

- **Token Economy**: Tools often return verbose JSON. Use post-processing to strip unnecessary fields or summarize large datasets *before* returning the result to the LLM's context window. This saves tokens and reduces latency.
- **Caching**: For read-heavy tools (like "search_knowledge_base"), implement caching middleware to return previous results for identical queries, saving both time and API costs.

### Error Handling

- **Graceful Degradation**: If a tool fails (e.g., API timeout), catch the exception in middleware and return a structured error message to the LLM (e.g., `Error: Database timeout, please try again`).
- **Self-Correction**: Well-formatted error messages often allow the LLM to understand *why* a call failed and retry it with corrected parameters automatically.


## Samples

## 2. Official Technical Reference & Guides (googleapis/googleapis.github.io)

# GAPIC Generators

**Generated API Clients (GAPICs)** are produced from declarative descriptions
of APIs. These API descriptions are written in the
[Protocol Buffer language](https://developers.google.com/protocol-buffers/) and
build on nearly 20 years of experience describing APIs within Google.

Our GAPIC generators are open source and are published in
[github.com/googleapis](https://github.com/googleapis). The original
[gapic-generator](https://github.com/googleapis/gapic-generator) produced API
clients in seven languages and continues to be the preferred generator for Java
and PHP.

## Microgenerators

In 2018, we began developing a new set of generators, each written in the
language that it generates. Some of our language-specific GAPIC generators are
listed below:

- [gapic-generator-python](https://github.com/googleapis/gapic-generator-python)
- [gapic-generator-go](https://github.com/googleapis/gapic-generator-go)
- [gapic-generator-java](https://github.com/googleapis/gapic-generator-java)
- [gapic-generator-ruby](https://github.com/googleapis/gapic-generator-ruby)
- [gapic-generator-kotlin](https://github.com/googleapis/gapic-generator-kotlin)
- [gapic-generator-csharp](https://github.com/googleapis/gapic-generator-csharp)
- [gapic-generator-cpp](https://github.com/googleapis/gapic-generator-cpp)
- [gapic-generator-typescript](https://github.com/googleapis/gapic-generator-typescript)

## Testing GAPIC Generators

To verify GAPIC generator implementations, we test them with a common
[gapic-showcase](https://github.com/googleapis/gapic-showcase) API that
"showcases" important GAPIC features.

## Issues

For questions on a specific GAPIC generator, please file an issue on the
corresponding repository.