What Ships by Default
These capabilities are included in the default workspace when Wolffish creates~/.wolffish/workspace/ on first launch. Each lives in its own folder under brain/cerebellum/.
tool-discovery, introspect, filesystem, shell, ask, utilities, web-search, secrets, system, video, plus the workflow and channel capabilities when active. Everything else (GitHub, Google, browsers, media, documents, MCP servers) loads on demand via tool_search / tool_activate and is callable the same turn. See Capabilities Overview for how exposure works.Self-Management
Wolffish can read, manage, and write its own capabilities at runtime — no code change, no restart. This is the heart of what makes it extensible: a workflow you do often can become a permanent tool just by asking.automations — Manage its own scheduled heartbeat jobs
automations — Manage its own scheduled heartbeat jobs
In (15m) / Once (2026-...)) fire once and delete themselves.Tools:automation_list— List every automation: schedule, plain-English timing, instruction, and whether it’s valid/runningautomation_create— Create a job (recurring or one-time) from a schedule + instruction, with an optionalmode(single or workflow) and an optionalicon— an emoji Wolffish picks to fit the job (📧 for an inbox sweep, 📰 for a news digest), shown on the job’s card and stamped on its run conversationsautomation_edit— Change a job’s schedule, instruction, and/or modeautomation_delete— Permanently remove a job (asks you to confirm)automation_check— Runtime status: what’s running now and how recent runs wentautomation_run— Run a job immediately, to test it
mode:, icon:, and project: lines that bind a job to a project so its runs get the project’s context. The tools preserve the markers automatically.Heartbeat jobs run with tool calls auto-approved, so it confirms anything recurring or consequential with you before scheduling it. Memory compaction is configured separately in Settings, not here.procedures — Manage saved prompts you run on demand
procedures — Manage saved prompts you run on demand
procedure_list— List every saved procedure: number, title, and a one-line prompt previewprocedure_view— Show one procedure’s full title and complete promptprocedure_create— Save a new procedure (title + self-contained prompt, optional single/workflow mode)procedure_edit— Change a procedure’s title, prompt, and/or modeprocedure_delete— Permanently remove a procedureprocedure_run— Run a procedure now, in a fresh background conversation
projects — Manage projects: standing instructions plus files
projects — Manage projects: standing instructions plus files
project_list— Every project: number, icon, title, file count, last-edited timeproject_view— One project in full: icon, title, complete instructions, and its file list with per-file existence and sizeproject_create— Create a project (title, optional emoji icon, optional instructions)project_update— Change a project’s title, icon, and/or instructionsproject_add_files— Attach files by path; each source is copied into the project’s own folder (uploads/project-<id>/), so a project never dangles on a moved or deleted originalproject_remove_file— Detach a file (the project’s own copy is deleted; originals outside the workspace are never touched)project_conversations— List every conversation belonging to a project: title, message count, last activityproject_delete— Permanently remove a project; its past conversations stay in history and simply lose the project context on future turns
workflow — Design and drive a model-led multi-agent run
workflow — Design and drive a model-led multi-agent run
workflow_plan— Declare (or revise) the run’s phases; they light up on the workflow card as their agents run and completeagent_spawn— Start a live background agent on a self-contained task, with an optional per-agentmodel(provider/model-id), reasoningeffort, andphaseagent_send— Send a follow-up to an idle agent; it runs again with its prior context intactagents_await— Block until the next agent lands and return its full report (first landing, not all)agent_cancel— Cancel an agent immediately, aborting its in-flight tool call
mcp — Manage its own MCP server connections
mcp — Manage its own MCP server connections
mcp_list— Every configured server: name, local/remote, live status, tool countmcp_add— Add and immediately connect a server (a command for local, an http(s) URL for remote; optional name and env vars)mcp_test— Verify a server now; kicks an offline one into reconnectingmcp_enable/mcp_disable— Pause or resume a server without deleting itmcp_remove— Permanently remove a server and its stored sign-in (asks you to confirm)mcp_authorize— Start the browser sign-in flow for a remote server that requires it
Asking Wolffish to build a skill for itself
You don’t write any code — you describe the ability in plain language and Wolffish authors the capability for you. The clearest requests signal a recurring need:- “From now on, whenever I send you a CSV, clean it up and reply with a summary table.”
- “Make yourself a skill that posts a daily standup to our Slack channel.”
- “You keep doing this resize-and-watermark dance by hand — turn it into a reusable tool.”
- “Teach yourself to look up parcel tracking from a tracking number.”
- Picks the kind of skill — a pure skill (a written procedure it follows with tools it already has), a plugin skill (a real new tool backed by JavaScript), or a plugin with npm dependencies — choosing the smallest that does the job.
- Writes the files via
skill_create— theSKILL.md(name, description, triggers) plusplugin/index.mjsand apackage.jsononly when a real new tool is needed. - Loads and tests it live, then it’s available from your next message — listed in the capability index and found by
tool_searchwhenever your wording matches its triggers.
Core System
tool-discovery — Find and load tools on demand
tool-discovery — Find and load tools on demand
tool_search— Search every installed capability (including MCP servers) by what you need to do. Matches capability names, descriptions, trigger keywords, and tool names; the best match is auto-loaded and its tools are callable the same turn.tool_activate— Load a specific capability by exact name, taken from the capability index or atool_searchresult.
shell — Execute shell commands
shell — Execute shell commands
child_process to execute shell commands. The workhorse tool that many other capabilities depend on.Tools:shell_exec— Run a command with optional cwd and timeout. Commands run until they exit naturally. Passtimeoutonly when you want fast failure (e.g. 5000ms for a quickwhichcheck). Omit for installs, builds, or anything with unpredictable duration.
- Block:
mkfs,dd if=(disk-level destruction) - Destructive:
rm -rf,sudo(requires approval) - Confirm: package installs, docker operations
sudo / doas) authenticates through the app’s saved admin session: you type your password into at most one native OS dialog per app run, and later privileged commands reuse the in-memory session — no TTY needed. The session is app-wide, so workflow agents and scheduled runs elevate through the same session as the chat.Background mode (background: true) detaches the process and returns its PID immediately — use for dev servers, watchers, and long-running processes.filesystem — Read, write, and edit files
filesystem — Read, write, and edit files
fs for precise file operations without needing shell access.Tools:file_read— Read file contents with optional line range (startLine/endLine). Reads are streamed, so pulling a slice out of a gigabyte log costs only the slice.file_write— Create or overwrite a file (supports append mode)file_patch— Find and replace a literal string in a file (all occurrences)image_view— Return an image’s actual pixels (downscaled) to a vision model on demand — the model-led way to look at an image instead of having it auto-injected
shell_exec for file operations — they’re faster, safer, and produce cleaner audit trails.package-manager — Cross-platform package installation
package-manager — Cross-platform package installation
pkg_check— Check which package manager is availablepkg_install_manager— Install Homebrew on macOS if missing (no-op elsewhere)pkg_install— Install a package with platform-specific name resolution
packages field in SKILL.md — the package-manager resolves the correct name per platform.node — Node.js runtime
node — Node.js runtime
node_check— Verify Node.js is installed and get versionnode_install— Install Node.js via system package manager
shell_exec for node, npm, and npx commands.File Delivery
utilities — Deliver files and openable location cards
utilities — Deliver files and openable location cards
send_file— Deliver any file (up to 50 MB, any type) to you as an attachment in the conversation you’re in. Renders as a file card in the desktop app and uploads natively on Telegram and WhatsApp.show_path— Push an openable location card into the in-app chat: a folder gets an Open button (straight into your OS file manager), a file gets Reveal (its folder opens with the file selected). This is how a place is delivered — a folder Wolffish scaffolded or organized, a batch of outputs, a file deliberately left where you asked. Nothing is parsed out of prose: the card exists only when the tool is called, and the path must actually exist. In-app only — on Telegram and WhatsApp the path is named in prose instead.
pdf_create, not ffmpeg, not the browser, not a shell script. Wolffish treats delivery as part of the task: the moment a file-producing task finishes, send_file is the final tool call — even for tiny text files, even when the content was also shown in chat. Ending with “saved to ~/path” is not delivery. If you explicitly ask for a file to just be saved somewhere, that’s respected — and when Wolffish is genuinely unsure, it asks rather than silently withholding. The runtime lists files already sent this turn, so you never receive the same file twice.Paths can be absolute, ~/-relative, or workspace-relative; files outside the workspace are copied into files/ so the in-app viewer can load them. Files over 50 MB stay on disk and Wolffish tells you where to find them.Web & Search
web-search — Search the web and read pages
web-search — Search the web and read pages
web_search— Search the web. Returns titles, snippets and URLs — never a page. Defaults to 5 results, no upper limit enforced. Each query spends real money, so it’s for settling one fact or finding which URL to open.web_fetch— One plain HTTP GET of a URL, returned as text. Instant and free, but it sees only what the server sends a bare request: JS-rendered pages come back empty, and paywalls, logins, consent walls and bot checks defeat it.
browser — Headless browser automation
browser — Headless browser automation
timeout_ms.Tools:browser_launch— Start a browser session (headed/headless, viewport size, locale)browser_navigate— Go to a URLbrowser_click— Click an element by CSS selectorbrowser_type— Type text into an inputbrowser_screenshot— Capture the current pagebrowser_evaluate— Execute JavaScript in the page contextbrowser_close— End the session
web_fetch for static pages — only use the browser when you need interaction.Documents & Media
document — Word documents and rich text
document — Word documents and rich text
document_read— Extract content as text, HTML, or markdown from any documentdocument_create— Create .docx with headings, paragraphs, tables, images, lists, headers/footersdocument_modify— Edit existing documentsdocument_convert— Convert between formatsdocument_merge— Combine multiple documents
pdf — PDF creation and manipulation
pdf — PDF creation and manipulation
pdf_info— A PDF’s facts without reading it: page count, metadata, size — the first call on any big documentpdf_search— Full-text search inside a PDF, returning matching pages with snippets — how a 3,000-page book gets navigatedpdf_read— Extract text by page range (lazy and cached, so successive reads of a huge document stay fast)pdf_create— Create PDFs with headings, paragraphs, images, tables (supports RTL with custom fonts)pdf_modify— Edit an existing PDF (pages, content)pdf_form— Read and fill PDF form fieldspdf_render_pages— Render whole pages to PNG/JPEG — how a figure, chart, algorithm or table gets shown, since it captures the page as printedpdf_extract_images— Save the photos and raster figures embedded in named pages as image filespdf_merge— Combine multiple PDFspdf_split— Extract page ranges into separate filespdf_secure— Encrypt/decrypt with passwordspdf_compress— Reduce file size
pdf_render_pages (which captures the page as printed and always works), and pdf_extract_images is for the assets a PDF genuinely stores: a photograph, a scanned plate, an illustration wanted on its own. Both take a pages selection and are page-scoped, so neither needs the document split first — and extraction over a whole book is never the right call, since a large reference text stores tens of thousands of sub-kilobyte fragments. Fragments under 80px are skipped by default.Design guidance for authored documents lives in the pdf-design manual below — the agent loads it before creating anything styled; pdf_create remains the plain, unstyled fallback.pdf-design — the document design manual (core)
pdf-design — the document design manual (core)
pdf_design loads the document design manual into context, and the operating contract requires the agent to call it before authoring any PDF or styled document you’ll read. Generated documents used to swing between genuinely good and visibly broken because the design recipe lived where the model rarely read it; the manual is now that recipe in one place — a page-planning step so no page ships half empty, a fixed-sheet page architecture with running footers and real page numbers, one type scale, one accent color with light body pages always, a component kit (cover, table of contents, section openers, stat tiles, hairline tables, callouts, provenance pills), Arabic/RTL rules, chart integration, and a mandatory verify pass: the agent renders sample pages as images with pdf_render_pages and looks at them before delivering anything.Tools:pdf_design— Load the document design manual (the manual body costs nothing until called — always-on is just the schema line)
dataviz — charts that earn their place (core)
dataviz — charts that earn their place (core)
dataviz loads the visualization manual the agent consults before laying out numbers — when a chart earns its place (and when a number or a table is the honest answer), which chart form fits which data, and how to label, order, and source it. It covers both output paths:- Interactive chart cards in the app chat. The agent writes a spec file ending in
.chart.jsonand delivers it withsend_file; the app renders it as a live, app-themed chart card in light and dark. Eleven types — column, bar, line, area, pie, donut, scatter, heatmap, radar, gauge, funnel — with tooltips, legends, an expandable full-screen view with a Chart ⇄ Data toggle, and Save as image. An invalid or oversized (over 1 MB) spec degrades to a plain file card, still downloadable. - Charts inside generated PDFs, drawn to the same visual system with print-perfect geometry and a fixed 8-slot, colorblind-validated palette assigned in order.
.chart.json arrives as a plain document attachment, so the agent is taught to prefer a text table there.Tools:dataviz— Load the visualization manual
web-design — the web design manual (core)
web-design — the web design manual (core)
web_design loads the web design manual into context, and the operating contract requires the agent to call it before writing a line of HTML for anything a person will open in a browser — exactly as pdf-design already works for documents.The manual carries:- Treatment calibration and a section map — a planning step before any markup, so the page’s shape is decided rather than discovered.
- A rail-and-column architecture that stays responsive from desktop down to phone widths.
- Dual light and dark themes — system preference plus a toggle override — built on one set of tokens.
- Type voices from system font stacks, and a component kit: cover plate, index rail, notes, figure plates, hairline tables, pills, card grids, Q&A, steps, checklists.
- Hand-drawn SVG figure rules, themed to the page rather than dropped in as stock art.
- JS as enhancement — a page must read complete with scripts switched off, and arrives as one self-contained file.
- Arabic and RTL rules, the same discipline the document manual applies.
- A mandatory verify pass: the agent screenshots the finished page with
browser_screenshotand looks at it throughimage_view— both themes, desktop and phone widths — before handing it over.
web_design— Load the web design manual (the manual body costs nothing until called — always-on is just the schema line). Takes an optionalpageline naming what you’re about to design; stating it commits the agent to the manual.
spreadsheet — Excel and CSV files
spreadsheet — Excel and CSV files
spreadsheet_read— Read xlsx/csv/tsv with optional sheet selection and cell rangespreadsheet_create— Create new spreadsheets with multiple sheets, columns, rows, and stylesspreadsheet_modify— Edit existing files (add rows, update cells, add sheets)spreadsheet_analyze— Compute statistics, summaries, and derived columns
archive — Zip archives, without a shell
archive — Zip archives, without a shell
.zip files, working in-process — no unzip or zip binary needed, same behaviour on macOS and Windows. A .zip is also a first-class attachment (up to 512 MB), so an archive arrives somewhere the tools can reach it.Tools:archive_list— List what’s inside without unpacking: entry paths, unpacked sizes, dates, top-level layout, totals, and which entries are encrypted. Reads only the archive’s index, so it’s fast at any size. Pages withoffset/limitand filters by glob — and never truncates silently.archive_read— Read one text file straight out of the zip, nothing written to disk. Pages withstart_line/end_line; a binary entry returns its size and the right tool to open it, not garbage bytes.archive_extract— Unpack everything, or only the entries you name. Without a destination it creates a new folder beside the archive (an uploaded one unpacks into the workspacefiles/folder) and never overwrites an existing folder.archive_create— Pack files and folders into a new.zip. A folder keeps its own name as the archive root, so unzipping produces a folder instead of loose files. Warns whennode_modules,.gitorvenvwent in, so you can re-run withexclude.
src/, public/, package.json, plus a 40 MB video”), and then you’re asked what you want done with it. A request that already answers the question (“unzip this”, “what does the README say”) just gets done.Safety: entries that would write outside the destination are refused outright, symlink entries are stored as plain files, and __MACOSX/, .DS_Store and Thumbs.db are skipped with the count reported. Encrypted archives still list (the index isn’t encrypted); archive_read and archive_extract take a password.Zip only — and the file’s actual signature is checked, not its extension. A .tar.gz, .7z or .rar is rejected with the exact shell command that handles it. Office files (.docx, .xlsx, .pptx, .epub) are zips and open here, but that’s a debugging move: use the document tools for those.ffmpeg — Audio and video processing
ffmpeg — Audio and video processing
ffmpeg_check— Verify ffmpeg is installedffmpeg_install— Install via package-managerffmpeg_run— Run any ffmpeg command (pass args afterffmpeg)
video — Generate video with MiniMax H3
video — Generate video with MiniMax H3
video_check— Confirm the service is configured and the key works. Free, spends no credits.video_generate— Start a render; returns a task id immediately and raises a live task card in the chatvideo_await— Park until the task lands and return the saved mp4’s absolute pathvideo_status— Non-blocking snapshot of this conversation’s video tasksvideo_cancel— Cancel a queued or running task server-side
send_file (or telegram_send_video / whatsapp_send_video). A render that outlives its turn is finished by the app itself — polled, saved, and delivered to the channel it came from. Runs on its own key under Settings → Services → Video generation, deliberately separate from the MiniMax chat provider.Voice
speech-to-text — Transcribe audio with faster-whisper
speech-to-text — Transcribe audio with faster-whisper
stt_transcribe— Transcribe an audio file at a given pathstt_transcribe_upload— Transcribe a file uploaded in the current conversationstt_transcribe_voice_memo— Transcribe a voice memo generated by text-to-speechstt_detect_language— Detect the spoken language without a full transcription
text-to-speech — Generate voice memos
text-to-speech — Generate voice memos
voice_generate— Convert text to MP3 (returns file path)voice_respond— Respond entirely as a voice memo (the audio IS the response)voice_list— List all voice memo files in the workspace
af_/am_, e.g. the default af_bella) and British (bf_/bm_). The voice and speech rate are chosen in Settings → Text-to-Speech and applied automatically; the model installs into a managed Python runtime on first use (or on demand from Settings, with a live progress bar and a real in-app preview).Version Control & Code
git — Git operations (pure skill)
git — Git operations (pure skill)
shell_exec for Git with the user’s conventions. Instructions include:- Always run
git statusbefore making changes - Use Conventional Commits format:
type(scope): subject - Show diffs and proposed commit messages before executing
- Branch naming:
feature/,fix/,chore/prefixes with kebab-case
github — GitHub API integration
github — GitHub API integration
per_page at 100. For larger result sets, page through with multiple calls.See GitHub Integration for full setup and usage.External Services
google — Google Workspace
google — Google Workspace
notion — Notion pages and databases
notion — Notion pages and databases
cloudflared — Expose local services
cloudflared — Expose local services
cloudflared_check— Check if cloudflared is installedcloudflared_install— Install via package-managercloudflared_tunnel— Create a tunnel for a local port (returns public URL)
Desktop Automation
computer-use — Screen interaction
computer-use — Screen interaction
computer_screenshot— Capture the full screen (or specific display)computer_mouse_move— Move cursor to x,y coordinatescomputer_mouse_click— Click at position (left/right/double)computer_keyboard_type— Type textcomputer_keyboard_press— Press key combinationscomputer_scroll— Scroll at position
Interaction
ask — Ask the user with multiple-choice cards
ask — Ask the user with multiple-choice cards
ask_user— Pose one or more multiple-choice questions and wait for the answers. Each question carries 2–5 numbered options with short descriptions, plus (unless disabled) a free-text box for your own instructions. Returns every answer at once.
Memory & Self-Awareness
introspect — Memory retrieval and self-awareness
introspect — Memory retrieval and self-awareness
memory_search— Ranked full-text search across all memory sources, filterable by source and date range. Returns snippets with refs to follow up on.memory_get— Fetch the full stored content behind a ref;file:refs return the actual file (workspace-confined)conversation_list— Enumerate past conversations: id, title, channel, dates, message count — optionally ranked by a content queryconversation_read— Read a specific past conversation with pagination, including tool calls and results. Also recovers turns of the current conversation that were summarized out of context.memory_save— Durably save one self-contained fact to long-term knowledge (deduplicated), typed as projects, people, preferences, technical, or decisionsusage_report— Wolffish’s own LLM spend: requests, tokens, and cost, total and per model, for a chosen periodwolffish_recall— Keyword-and-date recall, kept as a stable alias and now served from the index
wolffish_status— Uptime, active provider, loaded capabilities, and system healthchannel_status— Whether each messaging channel (Telegram, WhatsApp, in-app) is connected, and the exact steps to reconnect one that isn’twolffish_performance— Task success rates, most used tools, error rateswolffish_memory— Recent conversation topics and knowledge areas at a glancewolffish_list_files— Structured file tree of the workspace (and only the workspace)
memory_save. Wolffish uses these unprompted: a definite reference (“the flight plan”, “that file”) triggers a search before answering, and it tries two differently-worded searches before ever claiming it doesn’t remember — a search miss is never treated as proof something didn’t happen. It also checks channel_status before sending you an out-of-band message — Telegram and WhatsApp are connected channels reached through their own tools, never desktop apps to launch.Fun
memes — Generate and find memes
memes — Generate and find memes
meme_generate— Create a meme from a template (drake, fry, buzz, distracted-boyfriend, this-is-fine, etc.)meme_templates— List available templatesgif_search— Search for reaction GIFsgif_trending— Get trending GIFsadd_to_chat— Insert the generated meme/GIF into the conversation
add_to_chat is called — generation alone doesn’t deliver it.Task Execution (Motor Runtime)
The motor cortex executes all tool calls with these defaults:- Output buffer: 100KB per tool result — the LLM sees substantial output without truncation
- Retries: Up to 10 attempts for retryable errors (network, timeout). Non-retryable errors (permission, validation, not-found) bail immediately. Backoff scales up to 60s between attempts.
- No global timeout: Tools run until they complete or the user stops them
Customizing Capabilities
Built-in capabilities are managed and updated by Wolffish — don’t edit them directly, as your changes will be overwritten on the next update. Instead:- Disable a built-in capability from Settings if you don’t need it (the load-bearing core ones are protected — see below)
- Fork it — copy the folder to a new name, then edit the copy however you like
- Create your own from scratch following the same structure
skills capability, projects, automations, procedures, the pdf-design, dataviz and web-design manuals, and the shared file-delivery tools the rest leans on. In Settings → Capabilities these wear a Core badge, sort to the bottom of the list, and show a locked Always on marker where their switch would be — so a stray click can’t pull the floor out from under a feature you depend on. Everything you imported yourself stays fully toggleable.