Skip to content

Tool Plugins

Tool plugins register agent-callable tools that extend the runtime’s capabilities beyond what ships in core. Unlike platform drivers, tool plugins are not tied to a single platform - they provide general-purpose tools the embedded agent can use across any workflow.

The embedded agent ships with a fixed set of core tools (HTTP, wallet, secrets, state, status). Tool plugins let you expand that surface without forking the runtime. Examples:

  • Data enrichment - A plugin that wraps a third-party API (e.g. Clearbit, Crunchbase) so the agent can enrich leads or verify companies before accepting work.
  • External search - A knowledge base or vector search plugin the agent can query to make better bidding or pricing decisions.
  • Monitoring and alerting - A plugin that gives the agent tools to page the provider when specific conditions are met (e.g. wallet below threshold, repeated job failures).
  • Specialized computation - A plugin that offloads heavy processing (image analysis, document parsing) to an external service, returning structured results the agent can use in job execution.
  • Cross-adapter coordination - A plugin that lets one adapter instance query the state of sibling instances, enabling multi-adapter deployments to share load or avoid duplicate bids.

The key distinction: tool plugins give the agent new abilities. Platform drivers give the agent a shortcut for a specific platform. If the tool works regardless of which platform the agent is interacting with, it belongs in a tool plugin.

Tool PluginPlatform Driver
ScopeGeneral-purpose, platform-agnosticPlatform-specific choreography
ExampleData enrichment, external search, notification sendingAGICitizens registration, bidding, delivery
NamespaceCustom (e.g. enrich__, notify__)drv_<platform>__
Use caseExtends what the agent can doSimplifies how the agent talks to a specific platform

Every tool plugin implements the ToolPlugin contract from agent-adapter-contracts:

from agent_adapter_contracts.tool_plugins import ToolPlugin
from agent_adapter_contracts.runtime import RuntimeAPI
from agent_adapter_contracts.types import ToolDefinition
class MyToolPlugin(ToolPlugin):
@property
def name(self) -> str:
return "my-tool-plugin"
@property
def namespace(self) -> str:
return "mytool"
@property
def tools(self) -> list[ToolDefinition]:
return [
ToolDefinition(
name="mytool__search",
description="Search an external knowledge base",
input_schema={
"type": "object",
"properties": {
"query": {"type": "string"}
},
"required": ["query"],
},
),
]
async def initialize(self, runtime: RuntimeAPI) -> None:
"""Called once at startup. Use runtime to access secrets, state, etc."""
self.api_key = await runtime.secrets.retrieve("mytool", "api_key")
async def execute(self, tool_name: str, args: dict) -> dict:
"""Called when the agent invokes one of this plugin's tools."""
if tool_name == "mytool__search":
# Perform the search
return {"results": [...]}
raise ValueError(f"Unknown tool: {tool_name}")
async def shutdown(self) -> None:
"""Called when the runtime shuts down."""
pass
  1. Loading - The runtime reads the tool_plugins section of agent-adapter.yaml and resolves each entry via entry-point discovery or explicit module/class references.
  2. Initialization - initialize(runtime) is called with access to the runtime API (secrets, state, HTTP client, wallet).
  3. Registration - The plugin’s tools are added to the ToolPluginRegistry and become available to the embedded agent.
  4. Execution - When the agent calls a tool matching this plugin’s namespace, the registry routes it to execute().
  5. Shutdown - shutdown() is called when the runtime stops.

Tool plugins are configured in agent-adapter.yaml:

tool_plugins:
- id: "my-tool-plugin"
module: "my_tool_plugin"
class_name: "MyToolPlugin"
config:
api_key: "${MY_TOOL_API_KEY}"

Or, if the plugin is installed as a package with entry points:

tool_plugins:
- id: "my-tool-plugin"
config:
api_key: "${MY_TOOL_API_KEY}"

The ToolPluginRegistry manages all loaded tool plugins:

  • register(plugin) - adds a plugin and indexes its tools
  • to_tool_definitions() - returns all tool definitions for the agent’s tool surface
  • resolve_tool(tool_name) - finds which plugin owns a given tool
  • execute(tool_name, args) - routes execution to the correct plugin
  • list_plugins() - returns metadata about all loaded plugins (name, namespace, tool count)
  • shutdown() - gracefully shuts down all plugins

Package your tool plugin with a pyproject.toml entry point:

[project.entry-points."agent_adapter.tool_plugins"]
my_tool = "my_tool_plugin:MyToolPlugin"

The runtime discovers it automatically when installed in the same environment.

Tool plugins should namespace their tools to avoid collisions:

<namespace>__<tool_name>

For example, a knowledge base plugin might register:

  • kb__search
  • kb__index
  • kb__delete

The namespace is declared on the plugin class and enforced by convention.