toolbox-core
Google's framework-agnostic Python SDK for loading and invoking MCP Toolbox database tools as native async functions.
Repository Health
Technical Analysis
toolbox-core is the base Python client for MCP Toolbox for Databases, Google’s open-source gateway that exposes database operations as callable tools for AI agents. It handles protocol negotiation, tool discovery, and invocation so a Python application can call toolbox.load_tool("name") and get back an object that behaves like a normal async function, complete with an inspectable signature, docstring, and pydantic-backed argument validation.
Beyond basic invocation, the SDK layers on the plumbing that production agent code otherwise has to write by hand: parameter binding to keep sensitive values out of an LLM’s control, Google ID token auth for calling protected Toolbox deployments, per-tool authentication requirement checks that fail loudly instead of silently, and OpenTelemetry-based tracing. It is the base package underneath the framework-specific toolbox-langchain and toolbox-llamaindex SDKs in the same monorepo, so teams that later adopt one of those frameworks keep the same tool definitions and server connection.
What You Get
- An async
ToolboxClient(plus aToolboxSyncClientfor non-async codebases) that loads a single tool or an entire named toolset from a Toolbox server in one call - Callable
ToolboxToolobjects with a real__signature__,__doc__, and type annotations generated from the server’s schema, sohelp(), IDE autocomplete, andinspectall work - Automatic MCP protocol version negotiation with transparent fallback across five supported protocol revisions when client and server don’t share a version
- Parameter binding (
bind_params/bind_param) and secure-parameter binding to inject values or callables at call time without exposing them as LLM-controllable arguments - Google ID token authentication helpers (
auth_methods.get_google_id_token/aget_google_id_token) with in-memory, audience-scoped token caching - Optional OpenTelemetry tracing and per-call telemetry attributes (
add_telemetry_attributes) for observability into tool invocations
Common Use Cases
- Giving an LLM agent safe, schema-validated access to database operations defined and governed centrally on a Toolbox server
- Building a GenAI application that needs the same tool definitions available across LangChain, LlamaIndex, and plain-Python integration paths
- Binding user-identity or request-scoped values (like a tenant ID) to a tool’s parameters so the model can’t override them
- Connecting to a Toolbox server that requires Google-authenticated (ID token) access from a Cloud Run, GKE, or local ADC environment
Under The Hood
Architecture
The client is layered around an ITransport interface implemented once per supported MCP protocol version (v20241105 through v20260728, each its own module under mcp_transport/). A _McpTransportProxy sits in front of the active transport, catching ProtocolNegotiationError and transparently rebuilding itself against a mutually supported version rather than surfacing the mismatch to the caller. ToolboxClient owns discovery and tool construction (__parse_tool splits a server schema into regular, bound, secure, and auth-gated parameters), while ToolboxTool in tool.py is the callable proxy itself, using an internal __copy method so that bind_params, add_auth_token_getter, and add_telemetry_attributes each return a new immutable tool instance rather than mutating shared state. ToolboxSyncClient/ToolboxSyncTool wrap the same async core in a background event-loop thread, so the sync and async surfaces share one code path with no duplicated logic. Extension points are clear: adding a protocol version means adding one transport module and one branch in the proxy’s match statement.
Tech Stack
Pure Python 3.10+ with pydantic 2.7+ for schema-to-model conversion and payload validation, aiohttp for the async HTTP transport, and requests as the synchronous counterpart. Authentication leans on google-auth and google-oauth2 (google.oauth2.id_token) for Google ID token minting and verification. The deprecated package marks the legacy add_headers method. An optional telemetry extra pulls in opentelemetry-api/sdk/exporter-otlp for tracing. The build uses a plain setuptools backend with dynamic versioning read from toolbox_core/version.py, and the package ships a py.typed marker for downstream static type-checking.
Code Quality
Testing is extensive and structured: dedicated unit test files for the client, tool, sync client/tool, auth methods, protocol schemas, and utils (nearly 3,000 lines across just three of those files), a per-protocol-version test module under tests/mcp_transport/, end-to-end tests (test_e2e.py, test_e2e_mcp.py, test_sync_e2e.py), and a separate conformance test harness with a baseline YAML for cross-SDK protocol compliance. Type checking is enforced via mypy with disallow_incomplete_defs, formatting via black and isort, and CI runs a conformance workflow on GitHub Actions. Error handling is explicit throughout — auth and bound-parameter mismatches raise descriptive ValueErrors rather than failing silently, and secure parameters are validated as missing before a call is ever sent.
API Design
The public surface is intentionally small: ToolboxClient, ToolboxSyncClient, and TelemetryAttributes are the only exports. Loaded tools present themselves as ordinary callables with a real signature and docstring generated from the server schema, so help(tool) and IDE autocomplete work without any extra glue. The immutable builder pattern for bind_params/add_auth_token_getter/add_telemetry_attributes avoids accidental cross-call state leakage, a common footgun in comparable SDKs. Protocol version handling is fully abstracted away from the caller, and load_toolset’s validation of unused auth tokens or bound parameters surfaces configuration mistakes at load time rather than as a confusing runtime failure deep in a request.