跳转到主要内容

Wiring 44 Scripts into Raycast

April 8, 2026
3 min read
Tianli Zeng
developer-tools
cli
raycast
automation

Why Bother Integrating with Raycast

I've got 44 CLI scripts spread across 4 repositories (doctools/devtools/mactools/clashx), covering document processing, developer productivity, system management, and network proxy. They're useful tools — but they share one problem: I can't remember the commands.

python3 ~/Dev/tools/doctools/scripts/document/md2word.py --template standard --input foo.md — who keeps that in their head?

Raycast solves it: ⌘+Space → type a keyword → enter.

Wrapper Architecture

Each Raycast wrapper is a shell script under raycast/commands/:

#!/bin/bash
# @raycast.title MD → Word
# @raycast.description Convert Markdown to a Word document
# @raycast.icon 📄
# @raycast.mode compact

python3 ~/Dev/tools/doctools/scripts/document/md2word.py "$@"

Key design choices:

  • Metadata-driven: title, description, icon all live in comments — Raycast parses them automatically
  • Mode selection: compact (silent execution) vs fullOutput (display output) vs inline (show in the search bar)
  • Argument passing: declared via @raycast.argument

Wrapper Distribution Across 4 Repos

RepositoryScriptsWrappersTypical Functions
doctools1727MD→Word, PDF merge, Excel processing
devtools1012repo management, CF API, health checks
mactools1113file organization, window management, system settings
clashx66proxy switching, node speed test

Why are there more wrappers than scripts? Because some scripts have multiple invocation modes, and splitting them into separate wrappers is more intuitive. For example, cf_api.py is split into "DNS list," "DNS add," and "Access list."

Pitfalls Along the Way

1. PATH issues

Raycast's shell environment doesn't load .zshrc, so python3, pnpm, etc. can't be found. Fix: source it manually at the top of each wrapper:

source ~/.zshrc 2>/dev/null

2. Working directory

Raycast executes in / by default, which breaks every relative path inside a script. Fix: each wrapper cds to the right directory first.

3. Interactive input

Raycast doesn't support stdin interaction. Anything that needs input has to be rewritten to take arguments or environment variables.

4. Notification feedback

The user can't see terminal output, so success/failure feedback is invisible. Fix: emit notifications via osascript:

osascript -e 'display notification "Conversion complete" with title "doctools"'

Efficiency Gains

I quantified the before/after on 10 frequent operations (averaged):

  • Time per action: dropped from 12 seconds (open terminal → type command → enter) to 3 seconds (⌘+Space → keyword → enter)
  • Memory load: shifted from "remember command path and arguments" to "remember a function keyword"
  • Error rate: typo-driven retries dropped from 15% to nearly zero

Next Steps

  • Wrap commonly used Claude Code skills as Raycast wrappers
  • Add parameter forms (Raycast Script Commands support multi-input fields)
  • Consider migrating to Raycast Extensions (TypeScript, richer UI)