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
ToolDefinitionto build these.execute(self, tool_name: str, tool_input: dict[str, Any]) -> ToolResultExecute 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