π΄ 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.
π΄ Required Information
Is your feature request related to a specific problem?
McpToolset.header_provideronly 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:Describe the Solution You'd Like
Allow
header_providerto accept both sync and async callables. Both call sites are already insideasyncmethods, so a one-lineasyncio.iscoroutine()guard per site is sufficient β fully backwards-compatible.Two call sites need the same one-line guard, both already inside
asyncmethods:src/google/adk/tools/mcp_tool/mcp_toolset.pyβ_execute_with_session(), line ~306src/google/adk/tools/mcp_tool/mcp_tool.pyβ_run_async_impl(), line ~389Impact 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
Additional Context
Both call sites are inside
asyncmethods andasynciois already imported in both files β no structural changes needed.