liveBook · Manning

BaseTool

As explained in Build an AI Agent (From Scratch)

BaseTool is the framework's abstract base class that defines the required interface and behavior for executable tools.

BaseTool is the abstract base class that gives every executable tool one interface. It bundles identification, LLM-facing metadata, execution, and context propagation instead of keeping function definitions and callable implementations synchronized manually. section 4.4.1 section 4.4.2

The contract requires:

  • A name for identification, defaulting to the subclass name. section 4.4.2
  • A description explaining the tool, defaulting to its docstring. section 4.4.2
  • A tool_definition schema describing the parameters that the LLM may supply; subclasses can generate it lazily through _tool_definition. section 4.4.2
  • An asynchronous execute(context, **kwargs) method, with ExecutionContext always passed first so tools can access execution state. section 4.4.2
  • An asynchronous __call__ method that delegates to execute for concise invocation. section 4.4.2

Local and remote tools through one interface

A calculator or search_web function can be wrapped in FunctionTool, while an MCP server tool can be adapted into the same interface. The Agent can then execute local and remote tools without knowing where their implementations run. The MCP adapter supplies the server's existing input schema and calls session.call_tool(); its simple implementation opens a new connection for each call, adding production overhead. section 4.4.4 section 4.9

Listing 4.5 BaseTool abstract class
class BaseTool(ABC):
    """Abstract base class for all tools."""

    def __init__(
        self, 
        name: str = None, 
        description: str = None, 
        tool_definition: Dict[str, Any] = None,
    ):
        self.name = name or self.__class__.__name__
        self.description = description or self.__doc__ or ""
        self._tool_definition = tool_definition

    @property
    def tool_definition(self) -> Dict[str, Any] | None:
        return self._tool_definition

    @abstractmethod
    async def execute(self, context: ExecutionContext, **kwargs) -> Any:
        pass

    async def __call__(self, context: ExecutionContext, **kwargs) -> Any:
        return await self.execute(context, **kwargs)

Use the abstract-class listing to inspect the minimal Python contract, including defaults, schema storage, asynchronous execution, and callable delegation. section 4.4.2

How Build an AI Agent (From Scratch) covers it

How deep it goes
Defines the Python contract and execution flow, but delegates concrete tool logic and schema generation to subclasses or wrappers.
Examples
Uses calculator, search_web, FunctionTool wrappers, and MCP adapters as concrete tool implementations.
What it assumes
Assumes Python functions and ExecutionContext, while teaching the common interface from its required properties upward.
What you can do after
Build executable tools that expose schemas, receive execution context, and run through a consistent asynchronous interface.
How it connects
Connects tool calling with FunctionTool, ExecutionContext, Agent, and MCP.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Build an AI Agent (From Scratch). The section links point to the parts of the book it draws on.