Skip to content

Instantly share code, notes, and snippets.

@paulsmith
Created February 27, 2026 21:21
Show Gist options
  • Select an option

  • Save paulsmith/339cf9cd29c9f16e5f3b4ddf2cc09532 to your computer and use it in GitHub Desktop.

Select an option

Save paulsmith/339cf9cd29c9f16e5f3b4ddf2cc09532 to your computer and use it in GitHub Desktop.
Hammerspoon ClipboardTool skill for Claude Code — query clipboard history from the command line
#!/usr/bin/env python3
"""Query Hammerspoon ClipboardTool history from the command line."""
import argparse
import plistlib
import subprocess
import sys
import tempfile
def load_clipboard_items():
with tempfile.NamedTemporaryFile(suffix=".plist") as tmp:
subprocess.run(
["defaults", "export", "org.hammerspoon.Hammerspoon", tmp.name],
check=True,
capture_output=True,
)
with open(tmp.name, "rb") as f:
data = plistlib.load(f)
return [
item["content"]
for item in data.get("ClipboardTool.items", [])
if item.get("type") == "text" and item.get("content", "").strip()
]
def cmd_list(args):
items = load_clipboard_items()
limit = args.limit or len(items)
width = args.width
for i, content in enumerate(items[:limit]):
content = content.strip().replace("\n", " ")
preview = content[:width] + ("..." if len(content) > width else "")
print(f"{i}: {preview}")
def cmd_get(args):
items = load_clipboard_items()
if args.index < 0 or args.index >= len(items):
print(f"Index {args.index} out of range (0-{len(items) - 1})", file=sys.stderr)
sys.exit(1)
print(items[args.index])
def cmd_search(args):
items = load_clipboard_items()
query = args.query.lower()
width = args.width
for i, content in enumerate(items):
if query in content.lower():
preview = content.strip().replace("\n", " ")
preview = preview[:width] + ("..." if len(preview) > width else "")
print(f"{i}: {preview}")
def main():
parser = argparse.ArgumentParser(description="Query Hammerspoon clipboard history")
sub = parser.add_subparsers(dest="command", required=True)
p_list = sub.add_parser("list", help="List clipboard items")
p_list.add_argument("-n", "--limit", type=int, help="Max items to show")
p_list.add_argument("-w", "--width", type=int, default=80, help="Preview width")
p_list.set_defaults(func=cmd_list)
p_get = sub.add_parser("get", help="Get full content of item by index")
p_get.add_argument("index", type=int, help="Item index (from list command)")
p_get.set_defaults(func=cmd_get)
p_search = sub.add_parser("search", help="Search clipboard history")
p_search.add_argument("query", help="Search term (case-insensitive)")
p_search.add_argument("-w", "--width", type=int, default=80, help="Preview width")
p_search.set_defaults(func=cmd_search)
args = parser.parse_args()
args.func(args)
if __name__ == "__main__":
main()
name description
hammerspoon-clipboard
Use when you need to access, list, search, or retrieve items from the user's clipboard history managed by Hammerspoon's ClipboardTool spoon

Hammerspoon Clipboard

Access the user's clipboard history (managed by Hammerspoon's ClipboardTool spoon) from the command line.

Helper Script

~/.claude/skills/hammerspoon-clipboard/clipboard.py supports three commands:

# List recent items (numbered with previews)
python3 ~/.claude/skills/hammerspoon-clipboard/clipboard.py list -n 10

# Get full content of a specific item by index
python3 ~/.claude/skills/hammerspoon-clipboard/clipboard.py get 3

# Search clipboard history by keyword (case-insensitive)
python3 ~/.claude/skills/hammerspoon-clipboard/clipboard.py search "tailscale"

Usage

When the user says things like:

  • "paste from my clipboard" / "what did I copy?" → list -n 5, then get the relevant index
  • "find that URL I copied" → search with a keyword
  • "use my 3rd clipboard item" → get 2 (0-indexed)

Items are ordered newest-first (index 0 = most recent copy).

How It Works

Reads ClipboardTool.items from macOS preferences (defaults export org.hammerspoon.Hammerspoon), parsed via Python's plistlib. No IPC or hs.ipc module required — works as long as Hammerspoon is running with ClipboardTool loaded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment