Custom Tools

You can extend Folderbot with custom tools by creating .folderbot/tools.py in your root folder.

Basic Example

This example adds a tool that appends timestamped entries to a daily journal:

# .folderbot/tools.py
from datetime import datetime
from pathlib import Path
from typing import Any

from pydantic import BaseModel, Field

from folderbot.tools import ToolDefinition, ToolResult


class JournalEntryInput(BaseModel):
    content: str = Field(description="The journal entry content")
    mood: str = Field(
        default="neutral",
        description="Current mood (happy, sad, neutral, excited)",
    )


class CustomTools:
    def __init__(self, root_folder: Path):
        self.root_folder = root_folder

    def get_tool_definitions(self) -> list[dict[str, Any]]:
        tools = [
            ToolDefinition(
                name="add_journal_entry",
                description="Add a timestamped entry to today's journal",
                input_model=JournalEntryInput,
            ),
        ]
        return [t.to_api_format() for t in tools]

    def execute(self, tool_name: str, tool_input: dict[str, Any]) -> ToolResult:
        if tool_name == "add_journal_entry":
            return self._add_journal_entry(tool_input)
        return ToolResult(content=f"Unknown tool: {tool_name}", is_error=True)

    def _add_journal_entry(self, tool_input: dict[str, Any]) -> ToolResult:
        params = JournalEntryInput(**tool_input)
        journal_dir = self.root_folder / "journal"
        journal_dir.mkdir(exist_ok=True)

        today = datetime.now().strftime("%Y-%m-%d")
        journal_file = journal_dir / f"{today}.md"

        if not journal_file.exists():
            journal_file.write_text(f"# Journal - {today}\n\n")

        timestamp = datetime.now().strftime("%H:%M")
        entry = f"### {timestamp}\n\n{params.content}\n\n---\n\n"

        with open(journal_file, "a") as f:
            f.write(entry)

        return ToolResult(content=f"Added journal entry to {today}.md")

Now you can tell the bot: “Add to my journal: Had a great meeting today”.

Required Interface

Your CustomTools class must implement:

__init__(self, root_folder: Path)

Constructor that receives the root folder path.

get_tool_definitions(self) -> list[dict[str, Any]]

Return a list of tool definitions in API format. Use ToolDefinition to build these.

execute(self, tool_name: str, tool_input: dict[str, Any]) -> ToolResult

Execute a tool and return a ToolResult.

Factory Function

Instead of a CustomTools class, you can export a create_tools function:

def create_tools(root_folder: Path):
    return CustomTools(root_folder)

Package Structure

For more complex tools, use a package at .folderbot/tools/__init__.py:

.folderbot/
└── tools/
    ├── __init__.py      # Exports CustomTools or create_tools
    ├── journal.py       # Journal tool implementation
    └── reminders.py     # Reminder tool implementation