Skip to content

McpToolset: support async header_providerΒ #6090

@RayaneKADEM

Description

@RayaneKADEM

πŸ”΄ Required Information

Is your feature request related to a specific problem?

McpToolset.header_provider only accepts sync callables. Passing an async callable silently fails β€” the coroutine is never awaited, and every MCP tool call crashes at runtime with no warning at construction time:

TypeError: 'coroutine' object is not iterable
RuntimeWarning: coroutine 'my_header_provider' was never awaited

Describe the Solution You'd Like

Allow header_provider to accept both sync and async callables. Both call sites are already inside async methods, so a one-line asyncio.iscoroutine() guard per site is sufficient β€” fully backwards-compatible.

Two call sites need the same one-line guard, both already inside async methods:

  • src/google/adk/tools/mcp_tool/mcp_toolset.py β€” _execute_with_session(), line ~306
  • src/google/adk/tools/mcp_tool/mcp_tool.py β€” _run_async_impl(), line ~389
result = self._header_provider(context)
if asyncio.iscoroutine(result):
    result = await result

Impact on your work

Connecting ADK agents to authenticated MCP servers (e.g. Cloud Run behind IAM) requires per-request OIDC tokens. Without async support, teams using async HTTP clients or secret stores for token retrieval are forced to block the event loop on every cache miss.

Willingness to contribute

Yes β€” I can submit a PR.


🟑 Recommended Information

Describe Alternatives You've Considered

Sync provider with token cache: works but blocks the event loop on cache miss and rules out async token sources entirely. Monkey-patching the installed package: confirmed working locally, not viable long-term.

Proposed API / Implementation

async def my_header_provider(ctx: ReadonlyContext) -> dict[str, str]:
    token = await fetch_token_async()
    return {"Authorization": f"Bearer {token}"}

McpToolset(
    connection_params=StreamableHTTPConnectionParams(url=MCP_URL),
    header_provider=my_header_provider,
)

Additional Context

Both call sites are inside async methods and asyncio is already imported in both files β€” no structural changes needed.

Metadata

Metadata

Assignees

Labels

mcp[Component] Issues about MCP supporttools[Component] This issue is related to tools
No fields configured for Feature.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions