Skip to content

Tools Reference

Judah Paul edited this page Mar 2, 2026 · 7 revisions

πŸ”§ Tools Reference

GPT Home includes several built-in tools that the LangGraph agent can invoke to perform actions. This page documents each tool's functionality, parameters, and usage examples.

Tool Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         Tool Registry                                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                       β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  Weather    β”‚  β”‚  Spotify    β”‚  β”‚   Lights    β”‚  β”‚  Calendar   β”‚   β”‚
β”‚  β”‚             β”‚  β”‚             β”‚  β”‚             β”‚  β”‚             β”‚   β”‚
β”‚  β”‚ Open-Meteo  β”‚  β”‚  Spotipy    β”‚  β”‚ Philips Hue β”‚  β”‚   CalDAV    β”‚   β”‚
β”‚  β”‚ OpenWeather β”‚  β”‚  Spotifyd   β”‚  β”‚             β”‚  β”‚             β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                       β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                     β”‚
β”‚  β”‚   Alarm     β”‚  β”‚   Memory    β”‚                                     β”‚
β”‚  β”‚             β”‚  β”‚ (LangMem)   β”‚                                     β”‚
β”‚  β”‚  Timers &   β”‚  β”‚             β”‚                                     β”‚
β”‚  β”‚  Reminders  β”‚  β”‚  manage_mem β”‚                                     β”‚
β”‚  β”‚             β”‚  β”‚  search_mem β”‚                                     β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                     β”‚
β”‚                                                                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Tool Category API Key Required Description
weather_tool information Optional Current weather and forecasts
spotify_tool entertainment Yes Music playback control
lights_tool smart_home Yes Philips Hue light control
calendar_tool productivity Yes Calendar events and tasks
alarm_tool productivity No Alarms and reminders

Weather Tool

File: src/tools/weather.py

Description

Retrieves current weather conditions and forecasts. Supports automatic location detection via IP geolocation when no location is specified.

API Sources

  • Primary: OpenWeatherMap API (if OPEN_WEATHER_API_KEY set)
  • Fallback: Open-Meteo API (free, no key required)

Function Signature

@tool
async def weather_tool(query: str) -> str:
    """Get current weather or forecast for a location.
    
    Args:
        query: Weather query like "weather in New York" or "what's the temperature"
    
    Returns:
        Weather information string
    """

Location Detection Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  Location Resolution                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                            β”‚
β”‚  1. Parse query for city name                              β”‚
β”‚     "weather in New York" β†’ "New York"                     β”‚
β”‚                                                            β”‚
β”‚  2. If no city specified:                                  β”‚
β”‚     a. Check DEFAULT_LOCATION env var                      β”‚
β”‚     b. Try IP geolocation services:                        β”‚
β”‚        β€’ ipapi.co                                          β”‚
β”‚        β€’ ipinfo.io                                         β”‚
β”‚        β€’ ip-api.com                                        β”‚
β”‚        β€’ ipwho.is                                          β”‚
β”‚                                                            β”‚
β”‚  3. Get coordinates (lat/lon)                              β”‚
β”‚     β€’ OpenWeatherMap geocoding (if API key)                β”‚
β”‚     β€’ Nominatim/OpenStreetMap (fallback)                   β”‚
β”‚                                                            β”‚
β”‚  4. Fetch weather data                                     β”‚
β”‚     β€’ OpenWeatherMap One Call API (if API key)             β”‚
β”‚     β€’ Open-Meteo API (free fallback)                       β”‚
β”‚                                                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Weather Codes

The tool interprets WMO weather codes for Open-Meteo:

Code Day Description Night Description
0 Sunny Clear
1 Mainly Sunny Mainly Clear
2 Partly Cloudy Partly Cloudy
3 Cloudy Cloudy
45, 48 Foggy Foggy
51, 53, 55 Drizzle Drizzle
61, 63, 65 Rain Rain
71, 73, 75 Snow Snow
80, 81, 82 Showers Showers
95 Thunderstorm Thunderstorm

Example Queries

"What's the weather?"           β†’ Auto-detect location
"Weather in London"             β†’ Specific city
"What's the temperature"        β†’ Current conditions
"Will it rain tomorrow?"        β†’ Forecast (future enhancement)

Configuration

Environment Variable Required Description
OPEN_WEATHER_API_KEY No OpenWeatherMap API key for premium data
DEFAULT_LOCATION No Fallback location if IP detection fails

Spotify Tool

File: src/tools/spotify.py

Description

Controls Spotify playback. Spotifyd runs as a Spotify Connect audio endpoint. Playback control uses MPRIS D-Bus first (direct spotifyd communication), falling back to the Spotify Web API when D-Bus is unavailable.

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Spotify Integration                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                       β”‚
β”‚  β”‚ spotify_   │──▢│ FastAPI        β”‚                       β”‚
β”‚  β”‚ tool       β”‚    β”‚ /spotify-*     β”‚                       β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜                       β”‚
β”‚                            β”‚                                β”‚
β”‚                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”                       β”‚
β”‚                    β”‚ Try MPRIS      β”‚                       β”‚
β”‚                    β”‚ D-Bus first    β”‚                       β”‚
β”‚                    β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜                       β”‚
β”‚                     β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”                         β”‚
β”‚                     β”‚             β”‚                         β”‚
β”‚                     β–Ό             β–Ό                         β”‚
β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                β”‚
β”‚              β”‚ MPRIS D-Busβ”‚ β”‚ Spotify Web  β”‚                β”‚
β”‚              β”‚ (primary)  β”‚ β”‚ API (fallbackβ”‚                β”‚
β”‚              β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β”‚ + search)    β”‚                β”‚
β”‚                     β”‚       β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                β”‚
β”‚                     β–Ό              β–Ό                        β”‚
β”‚                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚                    β”‚   Spotifyd (audio endpoint)        β”‚   β”‚
β”‚                    β”‚   - Spotify Connect receiver       β”‚   β”‚
β”‚                    β”‚   - Audio output via ALSA          β”‚   β”‚
β”‚                    β”‚   - Device name: "GPT Home"        β”‚   β”‚
β”‚                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

How It Works

  1. Spotifyd runs as a Spotify Connect device named "GPT Home"
  2. MPRIS D-Bus is the primary control path for playback commands:
    • Play/pause/next/previous
    • Volume control
    • Shuffle and repeat modes
    • Communicates directly with spotifyd without cloud round-trip
  3. Spotify Web API is used as fallback when D-Bus is unavailable, and for:
    • Search and playback initiation (play by URI)
    • Now playing metadata and progress
  4. Credentials are auto-provisioned from the backend's PKCE access token
  5. Audio output uses the same ALSA device as the backend (shared via alsa-config volume)

Credential & Discovery Architecture

Spotifyd supports two authentication modes: zeroconf discovery (advertises on the network, waits for a Spotify client to connect) and cached credentials (authenticates directly with Spotify servers using stored OAuth tokens).

The startup script (compose/spotify/Dockerfile) generates spotifyd.conf at runtime:

  • If cached credentials exist (oauth/credentials.json or zeroconf/credentials.json): sets disable_discovery = true to force direct credential authentication
  • If no credentials exist (first boot): sets disable_discovery = false to allow the backend to provision credentials via zeroconf

This is critical because when disable_discovery = false, spotifyd uses zeroconf as the primary mode with cached credentials as fallback. In this mode, the MPRIS D-Bus interface is not reliably exposed after reconnection via cached OAuth (known spotifyd issue). Setting disable_discovery = true forces spotifyd to authenticate immediately with cached credentials and reliably expose MPRIS on D-Bus.

The backend auto-provisions credentials at /root/.spotifyd/cache/oauth/credentials.json using the PKCE access token (format: {username, auth_type: 3, auth_data: base64(token)}). Spotifyd converts these to reusable credentials (auth_type 1) on first use.

Function Signature

@tool
async def spotify_tool(
    command: str,
    search_type: Optional[str] = None,
    query: Optional[str] = None,
) -> str:
    """Control Spotify playback - play music, pause, skip, search for songs.
    
    Args:
        command: The action to perform:
            - "play" (with query and search_type for playing music)
            - "pause" or "stop"
            - "next" or "skip"
            - "previous"
            - "volume 50"
            - "shuffle on"
        search_type: Required when command is "play". Specifies what to search for:
            - "album" - Play ALL tracks from an album in order
            - "artist" - Play top tracks by an artist
            - "track" - Play a single specific song
            - "playlist" - Play a playlist
            - "show" - Play a podcast/show
        query: Required when command is "play". The search query.
    
    Returns:
        Status message about the action taken
    """

Supported Commands

Command search_type query Action
play album Album name Play all tracks from an album
play artist Artist name Play artist's top tracks
play track Song name Play a specific song
play playlist Playlist name Play a playlist
play - - Resume playback
pause / stop - - Pause playback
next / skip - - Skip to next track
previous - - Go to previous track
volume 50 - - Set volume to 50%
shuffle on - - Enable shuffle mode
shuffle off - - Disable shuffle mode

Search Type Selection

The LLM agent uses these guidelines to select the correct search_type:

  • "play the album X" or "play X album" β†’ search_type="album"
  • Album titles (like "The Forever Story", "1989") β†’ search_type="album"
  • Artist's music (like "play some JID") β†’ search_type="artist"
  • Specific song (like "play Surround Sound") β†’ search_type="track"

Examples

# Play an album
spotify_tool(command="play", search_type="album", query="The Forever Story")

# Play an artist
spotify_tool(command="play", search_type="artist", query="JID")

# Play a specific song
spotify_tool(command="play", search_type="track", query="Surround Sound by JID")

# Pause playback
spotify_tool(command="pause")

# Skip to next track
spotify_tool(command="next")

Configuration

Environment Variable Required Description
SPOTIFY_CLIENT_ID Yes Spotify app client ID
SPOTIFY_CLIENT_SECRET Yes Spotify app client secret

Setup Steps

  1. Create app at Spotify Developer Dashboard
  2. Add Redirect URI: https://gpt-home.judahpaul.com/spotify/callback
  3. Add credentials via the web interface's Integrations page
  4. Click "Authorize" to complete OAuth flow

Not Configured Response

If Spotify credentials are not set, the tool returns:

"Spotify is not configured. Please visit http://<host-ip>/settings to add your Spotify Client ID and Client Secret."


Lights Tool

File: src/tools/lights.py

Description

Controls Philips Hue smart lights through the Hue Bridge API. Supports on/off, brightness, and color control.

Function Signature

@tool
def lights_tool(command: str) -> str:
    """Control Philips Hue smart lights.
    
    Args:
        command: Light command like "turn on lights", "turn off lights", 
                "dim lights to 50", "change lights to red"
    
    Returns:
        Status message about the action taken
    """

Supported Commands

Command Pattern Action
turn on lights Turn all lights on
turn off lights Turn all lights off
dim lights to [%] Set brightness percentage
set brightness to [%] Set brightness percentage
change lights to [color] Set light color
set lights to [color] Set light color

Supported Colors

Color Hue Value
Red 0
Orange 6000
Yellow 12750
Green 25500
Blue 46920
Purple 56100
Pink 56100
White 15330

Configuration

Environment Variable Required Description
PHILIPS_HUE_BRIDGE_IP Yes IP address of Hue Bridge
PHILIPS_HUE_USERNAME Yes API username (from bridge pairing)

Bridge Pairing

  1. Press the button on your Hue Bridge
  2. Connect via web interface at http://<host-ip>/settings
  3. Username is saved automatically after successful pairing

Not Configured Response

If Philips Hue is not configured, the tool returns:

"Philips Hue is not configured. Please visit http://<host-ip>/settings to connect your Hue Bridge."

The host IP is automatically detected from inside the Docker container.


Calendar Tool

File: src/tools/calendar.py

Description

Manages calendar events and tasks via CalDAV protocol. Compatible with Nextcloud, Google Calendar (via CalDAV), iCloud, and other CalDAV servers.

Function Signature

@tool
def calendar_tool(command: str) -> str:
    """Manage calendar events and tasks.
    
    Args:
        command: Calendar command like "what's on my calendar", 
                "add task called X", "schedule meeting on 2024-01-15 at 14:00"
    
    Returns:
        Information about calendar events or confirmation of changes
    """

Supported Commands

Command Pattern Action
what's on my calendar List upcoming events
upcoming events List events (next 30 days)
next event / next appointment Show next event
add task called [name] Create a new task
create task [name] Create a new task
what is left to do List pending tasks
pending tasks List incomplete tasks
completed tasks List completed tasks
schedule [event] on [date] at [time] Create calendar event

Event Creation Format

"schedule meeting on 2024-01-15 at 14:00"
         β”‚            β”‚            β”‚
         β–Ό            β–Ό            β–Ό
    Event name    YYYY-MM-DD    HH:MM

Configuration

Environment Variable Required Description
CALDAV_URL Yes CalDAV server URL
CALDAV_USERNAME Yes CalDAV username
CALDAV_PASSWORD Yes CalDAV password

CalDAV URL Examples

Provider URL Format
Nextcloud https://your-server/remote.php/dav/calendars/username/
Google https://apidata.googleusercontent.com/caldav/v2/calid/events
iCloud https://caldav.icloud.com/
Fastmail https://caldav.fastmail.com/dav/calendars/user/

Not Configured Response

If CalDAV credentials are not set, the tool returns:

"Calendar is not configured. Please visit http://<host-ip>/settings to add your CalDAV credentials."

The host IP is automatically detected from inside the Docker container.


Alarm Tool

File: src/tools/alarm.py

Description

Sets alarms and reminders using Python's threading Timer. Plays audio through ALSA when triggered.

Function Signature

@tool
def alarm_tool(command: str) -> str:
    """Set, delete, or snooze alarms and reminders.
    
    Args:
        command: Alarm command like "set alarm for 7:00 AM", 
                "remind me in 10 minutes to take a break"
    
    Returns:
        Confirmation message about the alarm action
    """

Supported Commands

Command Pattern Action
set alarm for [time] Create alarm
wake me up at [time] Create alarm
wake me up in [duration] Create alarm
remind me in [duration] to [task] Create reminder
delete alarm / cancel alarm Cancel all alarms
snooze for [minutes] Snooze current alarm

Time Formats

Format Example Notes
12-hour 7:00 AM, 2:30 PM With AM/PM
24-hour 14:30, 07:00 Military time
Relative minutes in 30 minutes From now
Relative hours in 2 hours From now

Alarm Storage

Alarms are stored in memory (not persisted):

_alarms: dict[str, Timer] = {}

# Format: alarm_YYYYMMDDHHMM or reminder_YYYYMMDDHHMM or snooze_YYYYMMDDHHMM

Audio Output

Alarms play /usr/share/sounds/alarm.wav via aplay (ALSA):

def _play_alarm():
    subprocess.Popen(["aplay", "/usr/share/sounds/alarm.wav"])

Memory Tools (LangMem)

In addition to the action tools, the agent has access to memory tools provided by LangMem:

manage_memory_tool

Allows the agent to save new memories about the user.

create_manage_memory_tool(namespace=("memories", "{user_id}"))

search_memory_tool

Allows the agent to search stored memories for relevant context.

create_search_memory_tool(namespace=("memories", "{user_id}"))

See Memory System for detailed documentation.


Tool Registry

Tools are registered and managed through the ToolRegistry class:

class ToolRegistry:
    """Registry pattern for managing tools."""
    
    def register(self, tool: Tool, metadata: Optional[ToolMetadata] = None):
        """Register a tool with optional metadata."""
        
    def get(self, name: str) -> Optional[Tool]:
        """Get a tool by name."""
        
    def get_all(self) -> List[Tool]:
        """Get all registered tools."""
        
    def get_by_category(self, category: str) -> List[Tool]:
        """Get tools by category."""
        
    def get_available(self) -> List[Tool]:
        """Get tools that have their required API keys configured."""

Tool Metadata

@dataclass
class ToolMetadata:
    name: str
    description: str
    category: str  # "information", "entertainment", "smart_home", "productivity"
    requires_api_key: bool = False
    api_key_env_var: Optional[str] = None

Creating Custom Tools

Step 1: Create Tool File

# src/tools/my_tool.py
from langchain_core.tools import tool
from .env_utils import get_env

@tool
async def my_tool(query: str) -> str:
    """Description for the LLM to understand when to use this tool.
    
    Args:
        query: What the user wants
    
    Returns:
        Result string
    """
    api_key = get_env("MY_API_KEY")
    if not api_key:
        return "My tool is not configured. Add MY_API_KEY to settings."
    
    # Your implementation
    result = await do_something(query, api_key)
    return f"Result: {result}"

Step 2: Register Tool

# src/tools/__init__.py
from .my_tool import my_tool

__all__ = [..., "my_tool"]
# src/tools/registry.py
from .my_tool import my_tool

registry.register(
    my_tool,
    ToolMetadata(
        name="my_tool",
        description="Does something useful",
        category="productivity",
        requires_api_key=True,
        api_key_env_var="MY_API_KEY"
    )
)

Step 3: Add to get_all_tools()

def get_all_tools() -> List[Tool]:
    from .my_tool import my_tool
    
    # ... existing registrations ...
    
    registry.register(my_tool, ToolMetadata(...))
    
    return registry.get_available()

Next Steps

Clone this wiki locally