Tools

apfelclaw loads its runtime tool catalog from a JSON manifest (tools.json). The model does not read this file directly — the app converts it into an OpenAI-compatible tools payload, sends that to apfel, and maps approved tool calls back to local Swift executors.

Most tools are read-only. add_calendar_event and write_note write to the user’s calendar or Apple Notes and always require confirmation before execution. Whether the user is prompted before execution depends on the configured approval mode and each tool’s confirmation policy. The local TUI auto-approves tools. Telegram can create notes only after tool auto-approve is enabled.

find_files

Find files on this Mac using Spotlight-backed search.

PropertyValue
Domainfiles
Read-onlyYes
Follow-up reuseNo

Parameters:

NameTypeRequiredDescription
querystringYesSearch phrase or filename
limitintegerNoMaximum results (prefer 5 or fewer)

Use when: The user needs to locate files by name or search phrase.

Avoid when: The user already has an exact absolute path — use get_file_info instead.

Examples:

  • “Find my resume”
  • “Where is the project proposal?”
  • “Search for files named budget”

get_file_info

Get metadata for one exact file or directory path, including paths that start with ~/.

PropertyValue
Domainfiles
Read-onlyYes
Follow-up reuseNo

Parameters:

NameTypeRequiredDescription
pathstringYesExact file or directory path. Prefer an absolute path; ~/... is also supported

Use when: The user already provided the exact path and wants metadata (size, dates, type).

Avoid when: The user needs to search for the path first — use find_files instead.

Examples:

  • “What’s in ~/Documents/report.pdf?”
  • “Get info on /Applications/Xcode.app”

list_calendar_events

Read upcoming events from the user’s calendars via EventKit.

PropertyValue
Domaincalendar
Read-onlyYes
Follow-up reuseYes
Deterministic fallbackNo

Parameters:

NameTypeRequiredDescription
timeframestringYesNatural-language time range in the Mac’s locale, such as today, tomorrow, next week, April 12, or 2026-04-12
limitintegerNoMaximum events (prefer 10 or fewer)

Use when: The user asks about meetings or schedule items for a specific time range.

Avoid when: The user wants to create, edit, or delete events.

Relative phrases such as “today” or “this week” are parsed in the Mac’s current locale, so the same tool call works for heute, demain, and other local equivalents. There is no English keyword table.

Examples:

  • “What meetings do I have today?”
  • “Show my schedule for tomorrow”
  • “Any events this week?”

This tool supports follow-up reuse: if the user asks about “today” and then follows up with “what about tomorrow?”, the classifier sees the last calendar snapshot and can select this tool again.


add_calendar_event

Create one calendar event in the user’s calendars via EventKit.

PropertyValue
Domaincalendar
Read-onlyNo
Follow-up reuseNo
ConfirmationAlways

Parameters:

NameTypeRequiredDescription
titlestringYesEvent title
starts_atstringYesEvent start time as natural language in the system locale or ISO 8601. It must include a specific time
ends_atstringNoExplicit end time as natural language in the system locale or ISO 8601
duration_minutesintegerNoEvent duration in minutes when no explicit end time is provided
locationstringNoEvent location
notesstringNoEvent notes

Use when: The user asks to add, create, or schedule a calendar event, meeting, or appointment.

Avoid when: The user wants to list events, edit or delete an existing event, or create a recurring event.

Notes:

  • This tool creates single events only in v1.
  • If the user did not clearly specify an end time or duration, the assistant should ask one short clarification question instead of guessing.
  • Start and end times are parsed in the Mac’s current locale, or as ISO 8601.
  • apfelclaw uses the system default calendar for new events.

Examples:

  • “Add my weekly sync meeting for today at 14:00 to my calendar”
  • “Create a dentist appointment tomorrow at 9am”
  • “Schedule lunch with Sam on Friday from 12:00 to 13:00”

get_mac_status

Read current status information from this Mac.

PropertyValue
Domainsystem
Read-onlyYes
Follow-up reuseYes
Deterministic fallbackYes

Parameters:

NameTypeRequiredDescription
sectionsarrayNoOptional section list. Allowed values: battery, power, thermal, memory, storage, uptime. Omit for an overview

Use when: The user asks about this Mac’s current battery, power, thermal state, memory, disk space, or uptime.

Avoid when: The question is about files, calendar, mail, or requires a shell command rather than direct system status APIs.

Examples:

  • “How much battery do I have left?”
  • “What’s my Mac status?”
  • “How much free disk space do I have?”

This tool supports follow-up reuse: if the user first asks for an overview and then follows up with a narrower system-health question, the classifier can select this tool again.


run_safe_command

Run one read-only native macOS terminal command from the safe allowlist.

PropertyValue
Domainterminal
Read-onlyYes
Follow-up reuseNo

Parameters:

NameTypeRequiredDescription
commandstringYesCommand name from the allowlist
argumentsarrayNoArray of string arguments. Each command has its own safe argument rules

Use when: A single allowlisted read-only shell command directly answers the question.

Avoid when: The task needs shell syntax, write access, or commands not on the list.

Safe command allowlist

The following commands are permitted:

pwd ls whoami date mdfind mdls stat find ps lsof

Examples:

  • “What’s my username?”
  • “List files in my Downloads folder”
  • “Show running processes”

list_recent_mail

Read recent messages from the Apple Mail inbox.

PropertyValue
Domainmail
Read-onlyYes
Follow-up reuseYes
Deterministic fallbackYes

Parameters:

NameTypeRequiredDescription
limitintegerNoMaximum messages (prefer 5 or fewer)

Use when: The user asks for latest or recent emails.

Avoid when: The user asks for specific mail search, message bodies, or mail actions.

Examples:

  • “Check my email”
  • “Any new mail?”
  • “Show me the last 3 emails”

This tool supports follow-up reuse: if the user asks “any new mail?” and then follows up with “show me more”, the classifier can select this tool again.


write_note

Create one new note in Apple Notes.

PropertyValue
Domainnotes
Read-onlyNo
Follow-up reuseNo
ConfirmationAlways

Parameters:

NameTypeRequiredDescription
titlestringYesShort specific note title
bodystringYesFull note text, preserving the user’s wording

Use when: The user asks to write, create, save, or jot down a note in Apple Notes, including incomplete requests and later replies that supply the title, body, or a confirmation to save.

Avoid when: The user wants to list, search, edit, or delete notes; create a calendar event or reminder; or find or write a file.

Notes:

  • This tool creates one note in the default Notes folder.
  • If the user dictated one block of text, the assistant should derive a short title and put the full text in the body.
  • If the user did not say what to write, the assistant should ask one short clarification question instead of inventing content.
  • Creating a note requires macOS Automation permission for Notes.app, the same class of prompt as Apple Mail.
  • The local TUI auto-approves this write. Telegram keeps it denied until you run /remotecontrol enable-tools telegram.
  • The assistant should not claim a note was saved unless this tool actually ran.

Examples:

  • “Write a note that I need milk”
  • “Can you write a note for me?”
  • “Create a note titled Groceries with eggs, bread, and coffee”
  • “Save this as a note: call the dentist tomorrow”

Tool behavior notes

Argument normalization

Each tool module validates the model’s raw argument JSON before execution. Unexpected keys and missing required parameters are rejected instead of being guessed from the user’s message. Optional limits are still clamped to safe ranges.

Result snapshots

After execution, each tool can produce a ToolResultSnapshot — a structured summary of what the tool covered. This snapshot includes:

  • scopeSummary: A human-readable description (e.g., “Previous calendar lookup covered today (2026-04-07) and returned 3 event(s).”)
  • machineReadableScope: A JSON object the router uses to compare previous vs. requested scope

These snapshots are injected into the Intent Router’s classifier context for subsequent turns, so it can decide whether to select the same tool again or pick a different one.

Deterministic fallback

Tools marked with “deterministic fallback” (list_recent_mail) can be invoked with empty {} arguments when the model fails to produce valid arguments but routing has already decided a tool should run.