> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nimbleway.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Google ADK

> Connect Google ADK agents to the Nimble web data platform via the MCP server.

Give Google ADK agents real-time web data by connecting to the Nimble MCP server. No extra SDK wiring needed.

[Google ADK (Agent Development Kit)](https://google.github.io/adk-docs/) uses the [Model Context Protocol](https://modelcontextprotocol.io/) to connect agents to external tools. Since Nimble provides a hosted MCP server, ADK agents can discover and use all Nimble tools automatically.

## Prerequisites

```bash theme={"system"}
pip install google-adk
```

Set environment variables:

```bash theme={"system"}
export GOOGLE_API_KEY="your-google-api-key"
export NIMBLE_API_KEY="your-nimble-api-key"
```

Get a Nimble API key from the [dashboard](https://online.nimbleway.com/settings/api-keys) (free trial available).

The MCP examples pass an `X-Client-Source: google-adk` header, and the SDK example sets the Nimble client's `client_source` to `google-adk`, so requests are attributed to this integration.

## Quick Start

Connect an ADK agent to the Nimble MCP server using `McpToolset` with `StreamableHTTPConnectionParams`. ADK auto-discovers all available Nimble tools: search, extraction, mapping, crawling, Extract Templates, and Web Search Agents.

```python Python theme={"system"}
import os
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams

NIMBLE_API_KEY = os.environ["NIMBLE_API_KEY"]

root_agent = LlmAgent(
    model="gemini-2.5-flash",
    name="web_research_agent",
    instruction=(
        "You are a research assistant with access to real-time web data. "
        "Use the available tools to search the web, extract content from URLs, "
        "crawl sites, and discover URLs."
    ),
    tools=[
        McpToolset(
            connection_params=StreamableHTTPConnectionParams(
                url="https://mcp.nimbleway.com/mcp",
                headers={"Authorization": f"Bearer {NIMBLE_API_KEY}", "X-Client-Source": "google-adk"}
            )
        )
    ],
)
```

### Run the Agent

```python Python theme={"system"}
import asyncio
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService

async def main():
    session_service = InMemorySessionService()
    session = await session_service.create_session(
        app_name="nimble_app", user_id="user"
    )

    runner = Runner(
        agent=root_agent,
        app_name="nimble_app",
        session_service=session_service,
    )

    from google.genai import types

    response = await runner.run_async(
        user_id="user",
        session_id=session.id,
        new_message=types.Content(
            role="user",
            parts=[types.Part(text="What are the latest trends in AI agents?")]
        ),
    )

    for event in response:
        if event.content and event.content.parts:
            for part in event.content.parts:
                if part.text:
                    print(part.text)

asyncio.run(main())
```

## Filter Tools

By default, ADK discovers all Nimble MCP tools. Use `tool_filter` to expose only the tools the agent needs:

```python Python theme={"system"}
McpToolset(
    connection_params=StreamableHTTPConnectionParams(
        url="https://mcp.nimbleway.com/mcp",
        headers={"Authorization": f"Bearer {NIMBLE_API_KEY}", "X-Client-Source": "google-adk"}
    ),
    tool_filter=["nimble_search", "nimble_extract"]
)
```

## Agent API V2: autonomous research tool

The hosted MCP tools above (`nimble_search`, `nimble_extract`, `nimble_map`, `nimble_crawl_run`, and `nimble_extract_templates_run`) are **synchronous and single-shot**. One call returns data directly, and the ADK model does the reasoning.

[Agent API V2](/nimble-sdk/web-search-agents/overview) is different. It exposes an **asynchronous research agent** that plans, searches across many sources, and returns a synthesized answer with a per-claim [trust report](/nimble-sdk/web-search-agents/trust). The lifecycle is **create a run → poll to a terminal state → retrieve the result**.

The Nimble MCP server exposes Agent API V2 too (creating a run, polling its status, and fetching the result), so an MCP-connected ADK agent can call these tools directly. Because a V2 run is asynchronous, you can also wrap the [Nimble SDK](/nimble-sdk/sdks/python) lifecycle in a single Python function. The model then calls one synchronous "deep research" tool, and the create-poll-retrieve loop stays in your code. Register it as an ADK callable tool alongside the MCP toolset shown above.

```bash theme={"system"}
pip install google-adk nimble_python
```

### 1. Wrap the run lifecycle

This helper uses a stable `agent_name`, so every call — from this process or any other — reuses the same agent and its memory instead of spinning up a fresh one each time. It creates the run, polls until terminal, handles `failed` and `cancelled` runs, and returns the answer plus its trust and citation metadata. Errors return a safe message, so no API key or raw exception is surfaced.

```python Python theme={"system"}
import os
import time
from nimble_python import Nimble

nimble_client = Nimble(api_key=os.environ["NIMBLE_API_KEY"], client_source="google-adk")

# Stable name for this integration's research agent. The first call creates
# it; every later call (here or from another process) reuses it and its memory.
# Pick a name unique to this deployment - anyone reusing the same name on the
# same account reuses the same agent and its memory.
NIMBLE_AGENT_NAME = os.environ["NIMBLE_AGENT_NAME"]

def nimble_deep_research(query: str) -> dict:
    """Run an autonomous, fully-cited web-research task with Nimble Agent API V2.

    Use for open-ended questions that need synthesis across multiple sources,
    not single-page lookups. Returns a cited answer with a trust grade.

    Args:
        query: The research question or task, in plain language.

    Returns:
        A dict with the answer, an overall confidence grade, and citations.
    """
    try:
        # Create-or-reuse the named agent, then start the run.
        run = nimble_client.agents.run(input=query, agent_name=NIMBLE_AGENT_NAME)

        agent_id = run.web_search_agent_id

        # Poll until the run reaches a terminal state.
        deadline = time.time() + 300
        while run.is_active:
            if time.time() > deadline:
                return {"status": "timeout", "error": "Run did not finish in time."}
            time.sleep(10)
            run = nimble_client.agents.runs.get(run.id, agent_id=agent_id)

        # Handle failed or cancelled runs.
        if run.status != "completed":
            return {"status": run.status, "error": f"Run ended as '{run.status}'."}

        # Retrieve the completed result and summarize its trust report.
        result = nimble_client.agents.runs.result(run.id, agent_id=agent_id)
        output = result.output
        return {
            "status": "completed",
            "answer": output.content,
            "confidence": output.trust.confidence,
            "citations": [
                {"url": s.url, "title": s.title, "source_type": s.type}
                for s in output.trust.sources
            ],
        }
    except Exception:
        # Never leak credentials or raw exceptions back to the model.
        return {"status": "error", "error": "Nimble request failed."}
```

<Tip>
  Pass an `output_schema` to `agents.run` (or `agents.runs.create`) to get structured JSON in `result.output` instead of prose. Trust is then keyed by JSON path. See [Dataset Building](/nimble-sdk/web-search-agents/use-cases/dataset-building).
</Tip>

### 2. Register it as an ADK tool

Pass the function straight into `LlmAgent`. ADK auto-wraps it as a `FunctionTool`, reading the signature and docstring for the schema. The model calls one tool; the async run loop stays hidden.

```python Python theme={"system"}
from google.adk.agents import LlmAgent

research_agent = LlmAgent(
    model="gemini-2.5-flash",
    name="deep_research_agent",
    instruction=(
        "You are a research analyst. Use nimble_deep_research for questions "
        "that need current, cited web evidence. Report the confidence grade "
        "and cite the sources it returns."
    ),
    tools=[nimble_deep_research],
)
```

Run it with the same `Runner` setup shown in the [Quick Start](#run-the-agent). The tool returns the synthesized answer, an overall `confidence` grade (`high`, `medium`, or `low`), and the source URLs behind it, so the model can weigh how much to trust each claim. See [Trust](/nimble-sdk/web-search-agents/trust) for the full report structure.

## Available Tools

ADK auto-discovers these tools from the Nimble MCP server:

| Tool | Description |
| - | - |
| `nimble_search` | Web search with configurable depth and focus modes |
| `nimble_extract` | Extract content from any URL with rendering support |
| `nimble_map` | Discover all URLs on a website via sitemaps and link crawling |
| `nimble_crawl_run` | Crawl multiple pages with path filtering and progress tracking |
| `nimble_extract_templates_run` | Run pre-built [Extract Templates](/nimble-sdk/web-tools/extract/template) for structured data from popular sites |

<Tip>
  The tool names above are a curated subset. See the [Nimble MCP Server](/integrations/mcp-server/mcp-server) docs for setup details and the full tool list.
</Tip>

## Next Steps

<CardGroup cols={2}>
  <Card title="Nimble MCP Server" icon="server" href="/integrations/mcp-server/mcp-server">
    Full MCP server setup for Cursor, Claude Desktop, and other clients
  </Card>

  <Card title="Web Search Agent" icon="robot" href="/nimble-sdk/web-search-agents/overview">
    Agent API V2: autonomous research runs with per-claim trust
  </Card>

  <Card title="OpenAI" icon="bolt" href="/integrations/connectors/openai">
    Use Nimble with OpenAI function calling and the Agents SDK
  </Card>

  <Card title="Anthropic" icon="microchip" href="/integrations/connectors/anthropic">
    Use Nimble with Claude's tool-use API and Tool Runner
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.