Alfred Automation Tasks: 20+ Practical Tasks You Can Automate on macOS

Matthew Diakonov··12 min read

Alfred Automation Tasks: 20+ Practical Tasks You Can Automate on macOS

Alfred's workflow system turns your Mac into a personal automation engine. If you have been wondering which tasks are actually worth automating, this post gives you concrete examples organized by category, with real scripts you can drop into Alfred workflows today.

File and Folder Tasks

File management is where Alfred automation pays off the fastest. These tasks replace multi-click Finder operations with a single keyword.

Batch Rename Files

Select files in Finder, trigger the workflow via a Universal Action, and rename them with a pattern.

# Run Script node (bash)
COUNT=1
while IFS= read -r file; do
    DIR=$(dirname "$file")
    EXT="${file##*.}"
    mv "$file" "$DIR/{query}_$(printf '%03d' $COUNT).$EXT"
    COUNT=$((COUNT + 1))
done <<< "$@"

Sort Downloads by File Type

Run on a schedule (via external trigger + cron) or manually with a keyword. Moves files from ~/Downloads into subfolders by extension.

# Run Script node (bash)
DOWNLOADS="$HOME/Downloads"
for file in "$DOWNLOADS"/*; do
    [ -f "$file" ] || continue
    EXT="${file##*.}"
    mkdir -p "$DOWNLOADS/$EXT"
    mv "$file" "$DOWNLOADS/$EXT/"
done

Create Project Scaffolding

Type scaffold {name} to create a standard project directory structure with boilerplate files.

# Run Script node (bash)
BASE="$HOME/code/{query}"
mkdir -p "$BASE"/{src,tests,docs}
echo "# {query}" > "$BASE/README.md"
echo "node_modules/" > "$BASE/.gitignore"
cd "$BASE" && git init

Text and Clipboard Tasks

Alfred's clipboard history is a Powerpack feature, but workflows extend what you can do with copied text.

Strip URL Tracking Parameters

Copy a URL, trigger this workflow, and get a clean URL on your clipboard.

# Run Script node (python3)
import sys, urllib.parse

url = sys.argv[1]
parsed = urllib.parse.urlparse(url)
clean_params = {
    k: v for k, v in urllib.parse.parse_qsl(parsed.query)
    if not k.startswith(('utm_', 'fbclid', 'gclid', 'mc_'))
}
clean = parsed._replace(query=urllib.parse.urlencode(clean_params))
print(urllib.parse.urlunparse(clean))

Markdown to Plain Text

Convert clipboard Markdown to plain text, stripping headers, bold markers, links, and code fences.

# Run Script node (bash)
pbpaste | sed 's/^#\+ //' | sed 's/\*\*//g' | sed 's/\[([^]]*)\]([^)]*)/\1/g' | sed 's/`//g' | pbcopy

Multi-Clipboard Merge

Select multiple clipboard history entries, then combine them into a single paste with newlines between each item.

| Task | Trigger | Output | |---|---|---| | Strip tracking params | Universal Action on URL | Clean URL to clipboard | | Markdown to plain text | Hotkey | Plain text to clipboard | | Multi-clipboard merge | Keyword merge | Combined text to clipboard | | Text case conversion | Universal Action on text | Transformed text to clipboard | | JSON prettify | Hotkey | Formatted JSON to clipboard |

Developer Tasks

These are the workflows that save developers the most time per week.

Git Status Dashboard

Type gs to see uncommitted changes, current branch, and last commit across all your repos.

# Script Filter node (python3)
import json, os, subprocess

items = []
repos = [d for d in os.listdir(os.path.expanduser("~/code"))
         if os.path.isdir(os.path.join(os.path.expanduser("~/code"), d, ".git"))]

for repo in repos[:10]:
    path = os.path.join(os.path.expanduser("~/code"), repo)
    branch = subprocess.check_output(
        ["git", "-C", path, "branch", "--show-current"],
        text=True
    ).strip()
    status = subprocess.check_output(
        ["git", "-C", path, "status", "--porcelain"],
        text=True
    ).strip()
    changes = len(status.splitlines()) if status else 0
    items.append({
        "title": f"{repo} [{branch}]",
        "subtitle": f"{changes} uncommitted changes" if changes else "clean",
        "arg": path
    })

print(json.dumps({"items": items}))

Quick SSH Connection

Type ssh followed by a server alias. The workflow opens Terminal with the SSH session.

# Run Script node (bash)
osascript -e "tell application \"Terminal\"
    activate
    do script \"ssh {query}\"
end tell"

Docker Container Manager

Type dock to list running containers, select one to see logs, stop, or restart.

# Script Filter node (python3)
import json, subprocess

output = subprocess.check_output(
    ["docker", "ps", "--format", "{{.Names}}\t{{.Status}}\t{{.Ports}}"],
    text=True
)
items = []
for line in output.strip().splitlines():
    name, status, ports = line.split("\t")
    items.append({
        "title": name,
        "subtitle": f"{status} | {ports}",
        "arg": name
    })

print(json.dumps({"items": items}))
Alfred Automation Task CategoriesFiles &FoldersText &ClipboardDeveloperToolsSystem &Web APIsBatch renameSort downloadsScaffold projectMove to folderStrip UTMsMD to plain textMerge clipboardCase conversionGit dashboardSSH connectDocker managerDB queryWiFi toggleDNS flushWeather lookupTranslate text

System Control Tasks

These workflows replace trips to System Settings or Terminal commands you can never remember.

Toggle WiFi

A single keyword to flip WiFi on or off. Useful when you need to reset a network connection.

# Run Script node (bash)
STATUS=$(networksetup -getairportpower en0 | awk '{print $4}')
if [ "$STATUS" = "On" ]; then
    networksetup -setairportpower en0 off
    echo "WiFi Off"
else
    networksetup -setairportpower en0 on
    echo "WiFi On"
fi

Flush DNS Cache

Type flushdns and you are done. No more googling the command every time.

# Run Script node (bash)
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
echo "DNS cache flushed"

Kill Process by Name

Type kill followed by a partial process name. The script filter shows matching processes; select one to terminate it.

# Script Filter node (python3)
import json, subprocess, sys

query = sys.argv[1].lower()
ps = subprocess.check_output(["ps", "aux"], text=True)
items = []
for line in ps.strip().splitlines()[1:]:
    parts = line.split(None, 10)
    if len(parts) < 11:
        continue
    pid, cmd = parts[1], parts[10]
    if query in cmd.lower():
        items.append({
            "title": cmd[:80],
            "subtitle": f"PID: {pid}",
            "arg": pid
        })

print(json.dumps({"items": items[:10]}))

Web and API Tasks

Alfred can talk to any HTTP API, which opens up a wide range of automation possibilities.

Weather Lookup

Type weather followed by a city name for a quick forecast without opening a browser.

# Script Filter node (python3)
import json, sys, urllib.request

query = sys.argv[1]
url = f"https://wttr.in/{query}?format=j1"
data = json.loads(urllib.request.urlopen(url).read())
current = data["current_condition"][0]

items = [{
    "title": f"{current['temp_C']}°C - {current['weatherDesc'][0]['value']}",
    "subtitle": f"Humidity: {current['humidity']}% | Wind: {current['windspeedKmph']} km/h",
    "arg": f"https://wttr.in/{query}"
}]
print(json.dumps({"items": items}))

Quick Translation

Translate selected text using a free API, then copy the result to your clipboard.

URL Shortener

Shorten a URL on your clipboard using a URL shortening API and replace the clipboard contents.

Warning

API-based workflows need error handling for rate limits and network failures. Wrap API calls in a try/except and show a notification on failure instead of silently failing. Alfred's built-in "Post Notification" output node is good for this.

Productivity and Notes Tasks

Append to Daily Journal

Type jot followed by a thought. It gets appended to today's journal file with a timestamp.

# Run Script node (bash)
JOURNAL="$HOME/Documents/journal/$(date +%Y-%m-%d).md"
echo "- $(date +%H:%M) {query}" >> "$JOURNAL"
echo "Saved to journal"

Quick Timer

Type timer 5 to set a 5-minute timer. Uses macOS notifications when it fires.

# Run Script node (bash)
MINUTES={query}
(sleep $((MINUTES * 60)) && osascript -e "display notification \"Timer done: $MINUTES minutes\" with title \"Alfred Timer\"") &
echo "Timer set for $MINUTES minutes"

Meeting Note Template

Type meeting followed by a meeting name. Creates a pre-formatted note with date, attendees section, agenda, and action items.

# Run Script node (bash)
NOTE="$HOME/Documents/meetings/$(date +%Y-%m-%d)-{query}.md"
cat > "$NOTE" << TEMPLATE
# {query}
**Date:** $(date +%Y-%m-%d)

## Attendees
-

## Agenda
-

## Notes


## Action Items
- [ ]
TEMPLATE
open "$NOTE"

Task Comparison: Alfred Workflows vs. AI Agents

Some tasks fit perfectly into Alfred's keyword + script model. Others need something more flexible. Here is where each approach works best.

| Task | Alfred Workflow | AI Agent | Why | |---|---|---|---| | Open project in IDE | Works perfectly | Overkill | Deterministic, same every time | | Rename files by pattern | Works perfectly | Overkill | Simple string transform | | Summarize a long email | Cannot do this | Natural fit | Requires language understanding | | Fill out a web form | Fragile (AppleScript) | Natural fit | Needs visual context | | SSH into server | Works perfectly | Overkill | Single command | | Research a topic across 5 tabs | Cannot do this | Natural fit | Cross-app reasoning required | | Toggle system setting | Works perfectly | Overkill | One shell command | | Organize messy desktop | Partially (by extension) | Better | Needs semantic understanding of file contents | | Convert clipboard text | Works perfectly | Overkill | Text in, text out | | Book a meeting across calendars | Fragile | Natural fit | Multi-step, requires reading UI state |

Tip

The best setup is using both. Keep Alfred for fast, deterministic tasks (launchers, clipboard transforms, system toggles) and use an AI agent for anything that requires reading the screen, understanding context, or reasoning across multiple apps.

Common Pitfalls

  • Over-engineering simple tasks. If the automation is more complex than doing it manually, skip it. A workflow that saves 3 seconds but took 2 hours to build needs to run 2,400 times to break even.
  • Hardcoded paths. Use $HOME instead of /Users/yourname. Use {query} variables instead of baking in specific filenames. Your workflows should survive a machine migration.
  • No error feedback. When a workflow fails silently, you waste time wondering if it worked. Always add a "Post Notification" output node to confirm success or surface errors.
  • Forgetting about Powerpack. Many of these features (clipboard history, snippets, workflows) require Alfred's Powerpack license. The free version is limited to basic launching and search.
  • Ignoring Alfred's built-in features. Before building a custom workflow, check if Alfred already handles it natively. Clipboard history, snippet expansion, and file search are built in and more reliable than custom scripts.

Quick-Start Checklist

  1. Install Alfred and purchase the Powerpack ($34 one-time, or included in the Mega Supporter license)
  2. Set up your default hotkey (most people use Cmd + Space or Option + Space)
  3. Pick 2-3 tasks from this post that match your daily routine
  4. Build each as a workflow: create a new blank workflow, add a keyword trigger, connect a run script action
  5. Test each workflow manually 5 times before relying on it
  6. Share workflows with your team by exporting the .alfredworkflow file

Wrapping Up

Alfred automation tasks range from single-command system toggles to multi-step API-driven workflows. The best ones are the boring ones: file renaming, clipboard transforms, project launchers. They are simple, deterministic, and save a few seconds hundreds of times. For tasks that need visual context, language understanding, or cross-app reasoning, an AI desktop agent is the better tool.

Fazm is an open source macOS AI agent that handles the tasks Alfred workflows cannot reach. Open source on GitHub.

Related Posts