windy-word-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| WINDY_WORD_MCP_HOST | No | Override the control-server host | 127.0.0.1 |
| WINDY_WORD_MCP_PORT | No | Override the control-server port | 18765 |
| WINDY_WORD_MCP_TIMEOUT_MS | No | Default per-request timeout (in ms) | 5000 |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| get_platformA | Return OS / arch / distro / display-server / desktop-environment / tool-availability info for the machine running Windy Word. Use this first when diagnosing paste / hotkey issues — the platform determines which strategies and capabilities are valid. |
| list_paste_strategiesA | List all 12 paste strategies (macOS / Windows / Linux X11 / Linux Wayland) with full capability metadata, a per-strategy availableOnThisMachine flag, the resolved default fallback chain, and a hotkeyCollisionDetected flag indicating whether Mutter or another compositor is eating Windy Word's own paste keystroke (which silently breaks the Ctrl+Shift+V family on Wayland+GNOME). |
| get_active_paste_strategyA | Return the currently selected paste strategy, the user-configured fallback chain, and the resolved chain that will actually be tried at paste time. When strategy is "auto", the chain comes from defaultFallbackChain() with hotkey-collision demotion applied. |
| set_paste_strategyA | Select a paste strategy. Pass "auto" to use the platform default chain, or a specific strategy name (e.g. "wtype", "ydotool_type", "osascript_cmdv"). Optionally override the fallback chain. Strategy names come from list_paste_strategies. |
| test_paste_strategyA | WARNING: injects test text ("wtest") into whatever window currently has focus. Use to verify a specific strategy works on this machine. Returns timing + success flag. Have the user focus a known-safe target (e.g. a text editor) before calling. |
| run_paste_injection_testA | Real end-to-end paste injection test. Spawns a focusable Tk scratchpad target, temporarily flips Mutter's focus-new-windows policy to "strict" so the target auto-grabs focus, fires the requested paste strategy, captures what landed in the target, and returns whether the captured text matches what was sent. SAFE TO RUN — the target is a spawned scratchpad, not the user's active window; the focus-policy flip is reverted after the test. Wayland+GNOME only in v0 (the gsettings focus-policy flip is GNOME-specific). Returns the paste-strategy attempt diagnostic too. |
| auto_pasteA | Execute the auto-paste flow against an explicit candidate chain. Returns the winning strategy + per-strategy diagnostic data. Useful for stress-testing fallback behavior. WARNING: injects text into the focused window. |
| get_paste_historyA | Return the last N paste attempts with diagnostic data: timestamp, text length, content hash (NOT the actual text), strategy chain attempted, winner, target window type. The buffer is in-memory and resets when the app restarts. |
| clear_paste_historyA | Reset the in-memory paste history buffer. Useful between stress-test runs. |
| get_paste_targetA | Detect whether the currently focused window is XWayland or Wayland-native (or unknown). This is what xdotool sees — agents use it to verify their assumptions before picking a strategy, because XWayland targets accept different keystrokes than Wayland-native ones. |
| list_hotkeysA | List all current keyboard shortcut bindings, the set of rebindable actions, and the list of accelerators that are reserved (cannot be assigned). Use this before set_hotkey. |
| set_hotkeyA | Rebind a keyboard shortcut. Action keys: toggleRecording, pasteTranscript, pasteClipboard, showHide, quickTranslate. Accelerator format is Electron-style (e.g. "CommandOrControl+Shift+Space", "Alt+W"). Triggers an immediate re-registration. |
| list_modelsB | List available Whisper transcription models (tiny / base / small / medium / large-v3), their on-disk size and accuracy/speed tradeoff, the current selected model, and the WindyTune ladder. |
| set_modelA | Switch the active transcription model. Hot-reloads the running Python engine over WebSocket if it is currently active — no app restart needed. Model must be in the WindyTune ladder (see list_models). |
| get_windytune_stateA | Return WindyTune auto-tune state: whether it is enabled, the current model, the model ladder, switch thresholds, the recent transcription timing history, and the rolling average ratio (used to decide when to climb or descend the ladder). |
| list_installable_dependenciesA | List the whitelisted system tools that Windy Word can install on this machine to expand its capabilities (e.g. wtype for instant Wayland paste). Returns supported platform check + distro detection + the resolved install command per tool. Always safe to call (no system mutation). v0 supports Linux only — returns supported=false with a friendly explanation on macOS/Windows. |
| install_dependencyA | Install a missing system tool via the distro package manager wrapped in pkexec. WARNING: this triggers a graphical sudo (polkit) prompt that the user must approve interactively — do not call without telling the user a prompt will appear. The tool must be in Windy Word's whitelist: wtype, ydotool, wl-clipboard, xdotool. Linux only. After a successful install of wtype, re-check list_paste_strategies — wtype will flip to availableOnThisMachine=true and become first-pick in the resolved chain (paste becomes instant on Wayland-native targets). Use dryRun=true to see the command without executing it. |
| get_install_historyA | Return the audit log of recent install_dependency attempts on this machine (timestamp, tool, package, exact command, exit code, elapsed ms, whether the tool is on PATH after, stdout/stderr tails). In-memory; resets when Windy Word restarts. |
| clear_install_historyA | Wipe the in-memory install audit log. Useful between test runs. |
| setup_install_polkit_ruleA | Install or remove the Linux polkit auto-approve rule that lets install_dependency run without prompts. CRITICAL ONE-TIME SETUP for the agent-native install flow on a fresh machine: triggers a single pkexec password prompt for THIS call (the user types their password once); thereafter every install_dependency call for a whitelisted tool (wtype/ydotool/wl-clipboard/xdotool/ffmpeg) runs prompt-free. Uses subject.active so the rule applies to any logged-in user on the machine (not hardcoded to a single account). Linux only — returns 501 on macOS/Windows. Recommended flow:
Pass enable=false to remove the rule (also triggers a polkit prompt). |
| install_dependency_asyncA | Fire-and-poll variant of install_dependency. Returns a jobId immediately and runs the install in the background. Use get_install_status to check progress. Useful when the install might take >10 minutes (e.g., compiling from source, large package downloads on slow networks) or when the agent wants to surface a "still installing…" UI without holding a connection open. The whitelist + platform constraints + polkit/sudo flow are identical to install_dependency. |
| get_install_statusA | Return the current state of an async install job started by install_dependency_async. Status is "running" (still in flight) or "completed" (finished — check result.ok for success). If the job is not found (FIFO-evicted after 50 jobs, or wrong jobId), returns status="unknown". |
| list_install_jobsA | List all install jobs currently in memory — both running and recently completed. Useful for dashboards or when an agent forgot a jobId. |
| export_soul_file_to_pathA | Export the user's entire Windy Word archive (audio + video + transcripts) as a single zip file at the given path. The Forma Animae artifact — Grant's exportable "soul" for use with the Windy Clone digital-twin pipeline or as a portable backup. Includes a manifest.json with stats (file counts, word counts, date range). Refuses to overwrite existing files unless overwrite=true. Creates parent directories as needed. Pairs with the existing export-soul-file IPC the renderer uses via the Soul File button (which opens a save dialog) — this is the path-based variant for agent-driven exports. |
| transcribe_audio_fileA | Transcribe an audio file at a given path. Accepts any format ffmpeg can read (wav, mp3, m4a, ogg, flac, webm, etc. — auto-detected). Routes through the same Python Whisper engine the Windy Word desktop app uses for live transcripts (no cold start when the engine is warm — WebSocket-routed for sub-second hand-off). Returns transcript text + timing diagnostics (transcribeMs, audioDurationSec, ratio = transcribe/audio, modelUsed). 500MB file cap; 60s ffmpeg ceiling; 120s WS ceiling. Designed for individual files — agents wanting bulk processing should iterate over a directory and call this per file. |
| get_sound_effect_stateA | Return the current sound-effects configuration: per-hook-stage enabled/volume settings (the 6 stages are start, during, stop, process, warning, paste), the active sound pack, master SFX volume, and any per-stage custom sound overrides. The 6 hookStages are always returned even when live state read fails (so agents can show the stage catalog). Phase 1 limitation: Sound state lives in renderer-side localStorage, not the main electron-store. Reading via webContents.executeJavaScript currently fails (Electron context-isolation) — expect rendererReadable=false with rendererError set. Phase 2 will add a renderer-side IPC bridge in windy-pro to expose live state + writes. |
| set_sound_hookA | Configure a single sound-effect hook stage. Hooks are the 6 lifecycle points where Windy Word plays sounds: start (🎬 begin recording), during (🎤 mid-recording chirps), stop (⏹️ end recording), process (⏳ Whisper transcribing), warning (⚠️ approaching session limit), paste (📋 transcript injected). Each hook has enabled (boolean) + volume (0-100 int). Pass any combo of those args — omitted ones are unchanged. Routes through the renderer EffectsEngine and persists via _saveSettings to localStorage. |
| set_active_sound_packA | Switch the active sound pack. Pack ids come from list_sound_effect_packs — typical built-ins are "_silent", "classic-beep", "soft-chime". Affects all 6 hook stages unless individually overridden via custom-sound assignments. Persisted via EffectsEngine _saveSettings. |
| set_master_sfx_volumeA | Set the master SFX volume (0-100). Affects every hook stage as a multiplier on per-stage volumes. Persists immediately to localStorage windy_sfxVolume and applies to the live EffectsEngine.sound master. |
| set_sound_effect_modeA | Switch the EffectsEngine mode: "silent" (no sounds), "classic" (built-in beeps), "surprise" (random selection from a category), "custom" (per-hook user-assigned sounds), "pack" (active pack drives everything). Persisted via _saveSettings. |
| get_widget_stateA | Return mini-widget (tornado) runtime state via the renderer bridge: whether the WidgetEngine is present, whether the widget is currently visible, and the localStorage tornadoSize value. Complements the catalog-driven set_setting path for tornadoX/tornadoY/tornadoSize/widgetSettings. |
| list_sound_effect_packsA | List the sound-effect packs the Windy Word EffectsEngine knows about (_silent, classic-beep, soft-chime, and other built-in synthesized packs). Pairs with the 6 hook stages (start/during/stop/process/warning/paste) to drive per-stage sound assignments. Phase 1 limitation: Same as get_sound_effect_state — the renderer EffectsEngine isn't globally exposed, so live pack-list queries return ok=false until Phase 2 (renderer-side IPC bridge). The endpoint shape is finalized for forward-compat. |
| detect_hardwareA | Return system hardware info: totalRAM (GB), freeRAM (GB), cpuModel, cpuCores, platform, arch, gpu (NVIDIA via nvidia-smi on Linux/Windows; Apple Silicon Metal/MPS on macOS arm64; null otherwise), diskFreeGB (homedir partition). Used by Doctor checks and model-selection decisions — bigger models need more RAM, GPU-accelerated paths only fire when gpu != null. |
| get_autostart_statusA | Check whether Windy Word is configured to auto-launch on user login. Returns {platform, enabled, desktopFile?}. Linux checks for ~/.config/autostart/windy-pro.desktop; macOS/Windows use electron's app.getLoginItemSettings(). Pure read — no state change. |
| set_autostartA | Enable or disable Windy Word's auto-launch on user login. Linux writes/removes a .desktop autostart entry; macOS/Windows toggle via Electron's setLoginItemSettings. Returns the resulting state (enabled boolean) so agents can verify the change took. |
| translate_textA | Translate text to a target language. Tries the local translation-memory cache first (instant + free); on miss, calls Groq (preferred) or OpenAI via Windy Word's configured key. The TM cache auto-populates from successful calls so repeat translations are free. Source language defaults to "auto" (model detects); only concrete source-lang calls hit the TM. Returns {ok, translation, fromCache, sourceLang, targetLang, engine}. |
| lookup_translation_memoryA | Look up a (text, sourceLang, targetLang) tuple in the local translation-memory cache. Returns {ok, match: {translation, hits} | null}. No external API call — pure local SQLite query. |
| save_translation_memoryA | Store a (source, target, sourceLang, targetLang) tuple in the TM cache. Useful when an agent has a known-good translation it wants future lookups to find without re-calling the LLM. Upserts on duplicate keys (increments the hits counter). |
| get_translation_memory_statsA | Return TM cache stats: totalEntries, topPairs (top 10 source→target language pairs by count), recentEntries (last 50 by updated_at). |
| clear_translation_memoryA | Wipe the entire translation-memory cache. Destructive — confirm with the user before calling. |
| extract_document_textA | Extract plain text from a document file at a given path. Supports .txt / .md / .csv (read as UTF-8), .html (strip tags), .pdf (regex scrape — best-effort, may return [PDF text extraction yielded nothing] for image-only PDFs), .docx (xml-strip). Default size cap 5MB; override via maxBytes (up to 20MB). Returns {ok, path, ext, sizeBytes, textLength, text}. |
| save_text_fileA | Write text content to a file at a given path. Default: refuses to overwrite existing files (returns a 409-shaped error with the existing file size). Pass overwrite=true to replace. Creates parent directories as needed. Returns {ok, path, bytesWritten}. |
| list_archive_entriesA | List archived recording sessions (the user's historical transcripts + linked audio/video). Each entry has an opaque id (use it with read_archive or delete_archive_entry), date, full transcript text, wordCount, engine used, and hasAudio / hasVideo booleans. Newest first. Path information is NOT returned — agents work with the opaque id. |
| get_archive_statsA | Return aggregate stats for the user's recording archive: totalFiles, totalSizeMB, days (number of distinct date directories), audioHours, videoHours, totalWords, totalSessions, totalChars. Cached server-side for 30s — responses include |
| read_archive_entryA | Return an archive entry's metadata + optionally the base64 audio or video media bytes. The mediaType parameter selects which stream ("audio" default, or "video"). Pass metadataOnly=true to skip the base64 payload (responses can be MBs otherwise). Returns { ok, present, mimeType, base64 } or { ok, present: false } if the requested media isn't attached to this entry. |
| delete_archive_entryA | Tear down an archive entry: removes the transcript .md file + linked audio + linked video, all path-confined to the archive folder. Irreversible — confirm with the user before calling. Returns the list of filenames actually deleted. |
| open_archive_folderA | Pop the archive root directory in the user's OS file manager. Side-effect on the desktop (opens a Files / Finder / Explorer window). Use when the user asks "show me where my recordings are saved" or similar. |
| list_voice_clonesA | List all voice clones the user has on this machine. Returns each clone's id, name, duration, created_at, status, plus a hasAudio boolean (no raw audio in the response — use preview_voice_clone to fetch base64 audio for a specific clone). Also returns activeId — which clone is the current TTS default. Use this to answer "what clones does the user have?" without paging through audio bytes. |
| get_active_voice_cloneA | Return the currently-active voice clone (the one used for TTS playback), or {active: null} if no clone is selected. |
| set_active_voice_cloneA | Set which voice clone is the active TTS default. Pass id=null to deactivate (no clone — falls back to built-in TTS). The id must match an existing clone (use list_voice_clones to discover ids). |
| delete_voice_cloneA | Delete a voice clone (metadata + audio file on disk). If the deleted clone was the active one, activeId is reset to null. Returns the deleted clone's id and name for audit purposes. Irreversible — confirm with the user before calling. |
| preview_voice_cloneA | Return a voice clone's metadata, optionally with the base64-encoded audio sample. Pass metadataOnly=true to skip the audio (responses can be several MB otherwise). The mimeType field tells the agent how to interpret audioBase64 (typically audio/webm). |
| create_voice_clone_from_pathA | Create a voice clone from an audio file on disk. Copies the source file into Windy Word's voice-samples directory under a fresh UUID, registers the clone in the local DB, and returns the new clone's metadata (with hasAudio=true). Supported audio extensions: .webm, .wav, .mp3, .ogg, .m4a, .flac. Source file must exist and be readable; the copy itself is path-confined to Windy's voice-samples dir. Use list_voice_clones afterward to see it and set_active_voice_clone to activate. |
| submit_voice_clone_to_cloudA | Submit a local voice clone to Windy Clone for ElevenLabs training. Idempotent on cloud_order_id: if the clone has already been submitted, returns { ok: false, error: "Already submitted...", cloud_order_id: } without firing a second submission. Requires the user to be signed in to their Windy account (auth.token in electron-store). On success returns { ok: true, order_id, status }; poll get_cloud_clone_order_status with the returned order_id for training progress. Get clone ids from list_voice_clones. |
| get_cloud_clone_order_statusA | Check the status of a Windy Clone cloud-training order — used after submit_voice_clone_to_cloud to poll for ElevenLabs training completion. Requires the user to be signed in to their Windy account; returns a clean 401-shape error if not. Returns the raw order body from the Windy Clone API. |
| list_clone_bundlesA | List training-bundle catalog — audio/video recordings the user has marked as candidates for voice-clone training. Each entry has bundle_id, name, device info, sync_status, training_ready flag, file size, created_at, and fileExists. Pairs with InstaBio voice-clone ingestion which reads from these bundles. See [[project_instabio_voice_clone_data]] memory for the broader voice-clone training-data contract. |
| run_diagnosticsA | Run the local Windy Doctor check battery and return a structured report: overall health (healthy / degraded / unhealthy), per-check status (ok / warning / error / not_applicable), severity, what was found, and (for non-ok findings) an actionable remediation step that often references the specific MCP tool to call next (e.g., "install_dependency({tool: "wtype"})"). Covers: paste-stack tooling presence, /dev/uinput permissions, ydotoold daemon health, polkit rule installation, Python transcription engine liveness, Mutter hotkey collision. No system mutation — pure read. Use this as the starting point for any "why is paste broken / why is transcription failing" agent flow. |
| list_diagnostic_checksA | List the catalog of Windy Doctor diagnostic checks without running them. Returns each check's name, description, and whether it applies to this platform. Useful for agent introspection — understanding what the doctor knows how to look at before kicking off a diagnostic run. |
| cloud_diagnoseA | Run local diagnostics AND route the findings to the windy-fix-me cloud-relay for LLM-augmented remediation. Returns both the local rule-based findings and the cloud-relay's structured remediation (each entry has rootCause, a specific MCP tool call to invoke, fallback, verification steps). Use this when local run_diagnostics surfaces warnings/errors and you want expert-level fix guidance that knows about platform-specific quirks the local rules don't. Relay endpoint: https://windy-fix-me.windyword.workers.dev/diagnose (override via WINDY_FIX_ME_URL env var on the Windy Word side). May add ~2-3s of latency from the LLM round-trip. |
| list_settingsA | List every setting Windy Word exposes as an agent-discoverable, schema-validated path. Returns each setting's dotted path, type, description, allowed values (if enum / range), default, side effects of changing it, restartRequired flag, sensitivity (writable vs readonly), tags, and the current live value. The response also includes availableTags so agents can discover what tag filters exist. Use this as the entry point for any agent setting introspection. Paths outside the catalog are accessible only via the lower-level get_config / set_config tools. Optional |
| describe_settingA | Return the full catalog entry for one setting (type / allowed values / description / default / side effects / restartRequired / sensitivity) plus its current value from the live store. Returns an error if the path is not in the catalog — use get_config for paths outside it. |
| set_settingA | Validate and apply a setting change against the catalog. Rejects unknown paths, type mismatches, out-of-range numbers, invalid enum values, malformed accelerators, and attempts to write read-only settings (e.g. license.*). On success, returns the previous + new value, any side effects that fired (e.g. "global shortcuts re-registered", "python engine hot-reload sent"), and whether a restart is required for the change to take full effect. Use set_config to bypass the catalog (low-level, no validation — for paths outside the catalog). |
| get_configA | Return the full electron-store config tree (every setting Windy Word has persisted). Large but read-only — use this to discover what setting paths exist before set_config. |
| set_configA | Patch the config store. Pass EITHER {path, value} for a single dotted-path write (e.g. path="engine.model", value="small"), OR {patch: {...}} for a flat object of dotted-path → value pairs applied in order. Changes persist immediately. |
| get_versionA | Return the running Windy Word version (app.getVersion()) plus the underlying Electron and Node versions. Mirrors the "Windy Word v1.6.2" display in Settings → About. Read-only and safe to call. |
| search_archivesA | Full-text substring search across every archived transcript. Returns matches with a short snippet of surrounding context. Case-insensitive by default. Scales to thousands of entries (the scan is a single _agentArchiveScan pass + in-memory filter). Use this when the user asks "what did I say about X" or "when did I last talk to Y". For richer queries (regex, semantic, embedding) — defer; this is the fast substring path. |
| check_for_updatesA | Trigger electron-updater's update check. Mirrors the "Check for Updates" button in Settings → About. Returns immediately; the actual check runs asynchronously. Agents can poll get_config lastUpdateCheck to see when it last ran. SAFE — only downloads; install still requires a user-driven quitAndInstall via the in-app button. |
| set_themeA | Switch the UI theme. "dark" / "light" force one mode; "auto" follows the OS appearance. Mirrors Settings → Appearance → Theme. Persists to electron-store and propagates to the renderer (light-theme body class + localStorage.windy_theme) live — no app restart. |
| get_window_stateA | Snapshot the main window's current state: exists, maximized, minimized, focused, visible, fullScreen, simpleFullScreen, bounds {x,y,width,height}, fontSize, opacity, alwaysOnTop. Read-only. The cheapest call to find out "is the user actively using the app right now" — check focused + isRecording (via get_recording_state) before doing anything intrusive. |
| minimize_windowA | Minimize the main Windy Word window to the dock/taskbar. Mirrors the title-bar minimize button. Idempotent — calling on an already-minimized window is a no-op. |
| maximize_windowA | Maximize the main Windy Word window to fill the screen. Mirrors the title-bar maximize button. Different from fullscreen: keeps the title bar visible and stays in the current OS space. Use set_video_fullscreen for true fullscreen. |
| unmaximize_windowA | Restore the main window from maximized to its previous size. No-op if not maximized. |
| bring_window_to_frontA | Restore the window if minimized, show it if hidden, and raise it above other windows. DOES NOT steal keyboard focus on macOS — the main window is focusable:false to protect the recording flow from focus-theft against the user's external app. The window comes to the visual front; input focus stays where it was. Returns {focused:false} on macOS to make this explicit. |
| set_window_geometryA | Set the main window's position and size in screen pixels. Updates the live window AND persists to window.{x,y,width,height} so it survives restart. Useful for arranging the app before a demo or moving it to a specific monitor. |
| set_analytics_enabledA | Opt in or out of anonymous usage analytics (engine, duration, mode, language — never transcript content). Mirrors Settings → Analytics → "Help improve Windy Word". Off by default. Live-applies to the renderer's localStorage flag. |
| set_panel_visibilityA | Configure how one of the bottom panel rows behaves in the main app: "always" pins it open, "hover" reveals it when the cursor is near the bottom edge, "hidden" never shows it. Mirrors Settings → Bottom Panel. "playback" and "export" default to "hover"; "control" defaults to "always". |
| set_languageA | Set the Whisper transcription language. ISO 639-1 code (e.g. "en", "es", "fr", "ja", "zh", "ar", "hi", "de", "pt", "ko", "ru", "it", "nl", "pl", "tr", "sv", "vi", "th") — or "auto" to let Whisper detect per-utterance. Mirrors Settings → Transcription → Language. Hot-swappable: the live Python engine reconfigures over WebSocket without app restart; the new language applies on the next recording. |
| open_urlA | Open an http/https URL or one of the Windy ecosystem schemes (windypro://, windychat://, windyword://, windyfly://) in the user's default browser via Electron's shell.openExternal. Mirrors UI buttons like "View all history in Web Portal" and the Upgrade → checkout flow. Allowlisted: file://, javascript:, and other dangerous schemes are rejected with 403. |
| reset_hotkeysA | Restore all global keyboard shortcuts to their catalog defaults and re-register them. Mirrors the "Reset All to Defaults" button in Settings → Keyboard Shortcuts. Returns the applied bindings so the agent can confirm. Idempotent — safe to call repeatedly. |
| set_font_sizeA | Set the UI font-size zoom factor (70-150%). 100 is default. Mirrors the A- / A+ buttons in the Settings header. Persists to appearance.fontSize and broadcasts a font-size-changed event to the renderer so the live UI updates immediately. |
| set_video_fullscreenA | Toggle the main window into native OS-level fullscreen. On macOS uses setSimpleFullScreen (works with the focusable:false main window — doesn't need key window); other platforms use standard setFullScreen. Used by the History video-expand button (PR #143). For UI font zoom use set_font_size; for in-window maximize use maximize_window. |
| get_recording_stateA | Return the recording-flow state: isRecording (main-process truth), pythonEngineRunning (transcription backend alive), totalPasteAttempts (counter — increments after every paste attempt; use to detect activity between polls). Read-only and cheap. Use this BEFORE doing anything intrusive — if isRecording=true, the user is actively recording and you should defer or use toggle_recording to stop them gracefully. |
| archives_by_date_rangeA | Return archived sessions whose start timestamp falls within [from, to]. Either endpoint is optional — omit from for "since beginning", omit to for "until now". Sorted newest first. Use ISO 8601 (date or date+time, e.g. "2026-05-20" or "2026-05-20T18:00:00Z"). |
| bulk_delete_archivesA | Tear down multiple archive entries in one call. Each entry's .md transcript + linked audio + linked video are removed. REQUIRES an explicit confirm token "YES-DELETE-" where N matches the ids.length — this is the guard that prevents an agent hallucinating "yes" and accidentally wiping the entire history. Each id's outcome is reported independently in the response (not-found ids do not abort the batch). |
| cancel_recordingA | Cancel an in-flight recording without saving the result. Safe to call when idle (returns wasRecording:false). Unlike toggle_recording which stops the recording AND triggers transcribe + paste, this drops the audio entirely. Useful when the agent realizes the recording was started by mistake or the user said "wait, scratch that". |
| restart_appA | Relaunch Windy Word. app.relaunch() + app.exit(0). Returns 200 immediately; the actual exit fires ~250ms later so this response lands. DESTRUCTIVE — closes the running app, losing any in-flight recording. Get user confirmation before calling. |
| quit_appA | Quit Windy Word cleanly. app.quit(). Returns 200 immediately; exit fires ~250ms later. DESTRUCTIVE — app will not auto-restart. Get user confirmation before calling. |
| set_always_on_topA | Toggle whether the Windy Word window stays above other windows. Mirrors Settings → Appearance → Always on Top. Live update on the window + persist to appearance.alwaysOnTop. Idempotent. |
| set_opacityA | Set the Windy Word window opacity (0.1 = mostly transparent, 1.0 = fully opaque). Mirrors Settings → Appearance → Window Opacity. Live update on the window + persist to appearance.opacity. Values outside [0.1, 1.0] are rejected. |
| send_notificationA | Show an OS-native notification via Electron's Notification API. Returns ok:true if shown. Title is capped at 200 chars, body at 1000 chars. Pass silent:true to suppress sound. Returns 500 on platforms where notifications aren't supported. |
| bulk_export_archives_textA | Export the transcript text of multiple archive entries to a directory. One file per entry, named by the archive id. Format = "md" (default — with header), "txt" (plain transcript), or "json" (full entry metadata + text). targetDir is created recursively if missing. Per-id status returned; failures do not abort the batch. Pair with search_archives or archives_by_date_range to assemble the id list. |
| start_recordingA | Begin a voice recording (mode-aware: batch / streaming / API engine). The actual mic-capture + WebSocket setup completes asynchronously after the call returns — poll get_recording_state to confirm the live state. Idempotent: if already recording, returns { ok: true, alreadyRecording: true } without firing a second start. |
| stop_recordingA | End the current recording and trigger the transcription + paste pipeline against the window that had focus when recording started. Idempotent: returns { ok: true, alreadyStopped: true } if no recording is active. |
| list_audio_devicesA | Enumerate audio input devices (microphones) available to Windy Word. Returns each device with { deviceId, label, groupId, isCurrent } plus the currently-selected micDeviceId and a hint when labels are hidden (the OS hides labels until mic permission has been granted at least once — the user must start a recording one time before labels become visible). To switch devices, call set_setting with path "engine.micDeviceId" and the desired deviceId. |
| get_my_planA | Return the signed-in user's identity and license tier — the answer to "what plan am I on", "what tier am I on", "am I a pro user", "what subscription do I have". Returns { userId, name, email, tier, devices, deviceLimit, createdAt }. Tier is one of {free, pro, lifetime, team}. If the user is not signed in, returns ok:false with a "Not signed in" error — surface that to the user and offer to walk them through sign-in. |
| get_billing_historyA | Return the user's purchase / transaction history — the answer to "show me my receipts", "what have I paid for", "list my transactions". Returns an array of transactions with { id, tier, billing_type, amount_cents, currency, created_at, stripe_session_id }. Requires sign-in. |
| get_billing_summaryA | Return a high-level billing summary — current tier, lifetime spend, next renewal (if subscribed). Answer to "what does my bill look like", "billing summary", "how much have I spent on Windy Word". Requires sign-in. |
| open_upgrade_checkoutA | Open a Stripe Checkout page in the user's default browser to upgrade to a paid tier. Use this for "upgrade me", "I want pro", "switch me to lifetime", "buy the yearly plan". Returns { ok, url, sessionId, opened } — |
| open_billing_portalA | Open the Stripe Customer Portal in the user's default browser. Use this for "manage my subscription", "update my credit card", "cancel my plan", "view my invoices", "I want a refund". Returns { ok, url, opened }. Cancellation, plan changes, and card updates all happen in the portal — the user must complete those steps there. Requires sign-in AND a prior purchase (account-server returns 400 if the user has never bought anything). |
| logout_accountA | Sign the user out of their Windy account. Use this for "sign me out", "log me out", "switch accounts". Best-effort upstream logout, then ALWAYS clears the local auth + cached license fields (auth.token, auth.storageToken, license.tier, license.email, license.purchasedAt, license.expiresAt, license.stripeSessionId). Safe to call when already signed out and safe to call offline. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/sneakyfree/windy-word-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server