Skip to main content

Cross-platform screenshot & annotation tool (macOS first)

Project description

ShotQuill icon

ShotQuill

A fast, privacy-respecting screenshot & annotation tool for macOS — with Linux/X11 and Windows GUI plus cross-platform CLI/MCP support.

CI Platform: macOS | Linux | Windows Python 3.10+ License: Apache 2.0

ShotQuill lives in your menu bar and turns a screenshot into a finished, shareable image in one motion: press a hotkey, then let the pointer pick a window / region / the whole screen, then annotate, redact, extract text, save, copy, or pin it from the built-in editor. Prefer a no-editor flow? Turn on auto-save, auto-copy, or both in Settings.

  • macOS — the primary, most complete platform, and the one every other is measured against: full menu-bar GUI, two global hotkeys, smart window / region / full-screen capture (real pixels even under overlap, via ScreenCaptureKit), the annotation editor, optional hands-free save + clipboard, launch-at-login, window enumeration, blocklist redaction, and on-device OCR (Apple Vision) — plus the full CLI and MCP server.
  • Linux / X11 — full menu-bar GUI plus CLI / MCP, including window enumeration (smart-capture window highlight, squill window list, and blocklist redaction of full-screen grabs) and on-device OCR via Tesseract when it's installed.
  • Linux / Wayland — GUI plus CLI / MCP through xdg-desktop-portal for capture and the GlobalShortcuts portal for hotkeys when the compositor exposes it. Window enumeration is still unavailable by Wayland design, so smart capture degrades to screen / region selection there.
  • Windows — full menu-bar GUI plus CLI / MCP: capture, window enumeration (Win32), global hotkeys, and launch-at-login (the per-user Run key). On-device OCR runs on the Windows WinRT engine, installed with the optional windows-ocr extra (pip install "shotquill[windows-ocr]").

Status: early development — macOS is usable day-to-day; Linux and Windows support are newer and still being smoothed out. Expect rough edges either way.

Jump to: Highlights · Install · Usage · Scripting & agents (CLI · MCP) · App blocklist · App allowlist · Configuration · Troubleshooting · Privacy · Tech stack · Development · Packaging · Uninstall · Roadmap · Contributing


Highlights

  • Two capture hotkeys, both customizable:
    • Capture (⌥A) — one overlay; the pointer picks the mode:

      • click a window — grab just it, real pixels even when partly covered;
      • click empty space — the whole screen;
      • drag — a region, with a live size readout and a pixel loupe (magnified pixels + crosshair + position/colour) for precise edges.

      The hovered target is spotlit against the dimmed desktop. An optional delay (Settings → Highlight window after, off by default) fully highlights a window first, lifting its pixels out from under any overlap.

    • Full screen (⌥S) — every display at once, instantly.

  • Configurable after-capture flow — open the annotation editor by default, or make captures hands-free by auto-saving, auto-copying, or both.
  • Annotation editor — rectangles, ellipses, arrows, lines, freehand pen, highlighter, text, and mosaic redaction that pixelates the real pixels (not just an overlay, so the sensitive data never survives in the exported image).
  • On-device OCR — pull text out of a shot, fully offline, no network, no API key. Recognizes Chinese (Simplified) + English. Apple Vision on macOS, Tesseract on Linux (when installed), and the WinRT engine on Windows (via the optional windows-ocr extra).
  • Scriptable & agent-ready — a headless CLI (squill capture / window list / display list / ocr / diff / session / doctor / mcp, plus blocklist / allowlist — one path on stdout, exit codes as the contract) and a built-in MCP server that gives AI agents eyes on your screen. Every programmatic capture is audit-logged. See Scripting & agents.
  • Pin to screen — float an annotated shot on top of the desktop for reference; drag to move, double-click or Esc to dismiss.
  • Bilingual UI — English / 中文, switchable in Settings (defaults to English).
  • Menu-bar resident — no Dock clutter; optional launch-at-login.

Install

macOS

Homebrew (recommended):

brew install --cask wardmos/tap/shotquill

brew upgrade keeps it current.

Direct download: grab the .dmg from Releasesarm64 for Apple Silicon, x86_64 for Intel Macs, or universal2 if unsure (works on both, roughly twice the size) — open it, and drag ShotQuill to your Applications folder. Each release ships a .sha256 sidecar so you can verify the download:

shasum -a 256 -c ShotQuill-*.dmg.sha256

ShotQuill is open source and ad-hoc signed (not notarized) so the developer can stay anonymous. On first launch macOS Gatekeeper will warn that it can't verify the developer — right-click the app → Open once, or run:

xattr -dr com.apple.quarantine /Applications/ShotQuill.app

The Homebrew cask strips quarantine automatically, so this only applies to the direct download.

Linux

Two channels, pick by what you need:

You want… Use
The menu-bar GUI + CLI + MCP pipx (or pip) install from PyPI
Just the CLI / MCP in one self-contained binary AppImage from Releases

pipx (recommended for the GUI):

pipx install shotquill                # menu-bar app, plus `shotquill` and `squill`
squill desktop install          # add ShotQuill to your app menu (pipx-only step)
shotquill                             # launch the menu-bar app

pipx upgrade shotquill keeps it current. pip install --user shotquill works too if you prefer pip — in that case the .desktop launcher and icon land under ~/.local/share automatically, so you can skip the desktop install step. (pipx stores data files inside its private venv, which the desktop doesn't search, hence the one-liner.)

AppImage (CLI / MCP only): download the .AppImage from Releases, chmod +x, run. It bundles Python + Qt headless bits (no QtWidgets, no GUI) so the binary stays small and the CLI/MCP work even where the GUI's dependencies wouldn't. Built on Ubuntu 22.04 → glibc 2.35 floor (Ubuntu 22.04+ / Debian 12+).

Wayland users also need xdg-desktop-portal plus a portal backend for your desktop (xdg-desktop-portal-gnome, -kde, or -wlr) — squill doctor will tell you when screenshot or GlobalShortcuts support is missing. X11 users need nothing extra.

Linux GUI notes. ShotQuill needs a system tray to run. GNOME 42+ shipped without legacy tray support — install the AppIndicator and KStatusNotifierItem Support extension; KDE, XFCE, MATE, and Cinnamon already include a tray. Global hotkeys (Alt+A, Alt+S) work on X11. On Wayland they use the GlobalShortcuts portal when available; otherwise ShotQuill reports the missing portal support so you can use the tray menu or bind a compositor-level shortcut.

Windows

Download ShotQuill-*-windows-x64.zip from Releases, unzip it, and run ShotQuill.exe for the tray GUI. The same bundle includes squill.exe for the CLI and MCP server.

Windows OCR uses the on-device WinRT engine, but the Python WinRT projections are optional and are not included in the default package / bundle. For a pip install that needs OCR, install:

pip install "shotquill[windows-ocr]"

Usage

ShotQuill runs in the menu bar. Click its icon for the menu, or use the global hotkeys from anywhere.

Capture hotkeys

Action macOS Linux / Windows Notes
Capture ⌥A Alt+A Click a window to grab it, click empty space for full screen, or drag for a region. Esc / right-click cancels.
Full-screen ⌥S Alt+S All displays composited into one image, instantly.

Both are remappable in Settings — any combination of modifiers (⌘ ⌃ ⌥ ⇧ on macOS, Super+ Ctrl+ Alt+ Shift+ on Linux/Windows) plus a key. Hotkey labels in the tray menu and Settings render natively per platform (Apple keycap glyphs on macOS, text labels on Linux/Windows).

Linux / Wayland: global hotkeys use the xdg-desktop-portal GlobalShortcuts interface when your compositor supports it. If not, ShotQuill raises a notification so you can use the tray menu, or bind a compositor-level shortcut to squill capture (full screen) / squill capture --interactive (the compositor's own picker frames a window, region, or screen).

What happens after a capture

By default ShotQuill opens the annotation editor after a capture. You can make captures hands-free in Settings → After capture by enabling auto-save, auto-copy, or both:

Auto-save Auto-copy Result
Saved and copied, no editor.
Saved only.
Copied only.
Opens the annotation editor instead (default).

Annotation editor

When both auto-output toggles are off (or whenever you want to mark a shot up), the editor opens with a toolbar:

  • Tools: select, rectangle, ellipse, arrow, line, pen, highlighter, mosaic, text — with adjustable color and stroke width, plus undo / redo.
  • Copy Text runs OCR on the capture and copies the recognized text.
  • Pin floats the annotated shot on top of the desktop.

Keyboard:

Key Action
Space Copy to the clipboard, then close
Enter Save to your folder, then close
⌘Z / ⌘⇧Z Undo / redo
Esc Close without saving

The copy and save keys are configurable in Settings, and each can be disabled individually. Settings rejects keys that would clash with the built-in editor shortcuts (copy/save/undo/redo/Esc), with each other, or with a global capture hotkey.

Saved files

Captures are written to ~/Pictures/ShotQuill by default (configurable), named with a timestamp — e.g. ShotQuill 2026-06-04 14.30.00.png. Choose PNG or JPG in Settings.


Scripting & agents

ShotQuill has a headless CLI — shotquill, or the short alias squill — and a built-in MCP server, so shell scripts and AI agents can capture, read, and record the screen without the GUI:

squill capture --app safari -o shot.png    # capture a window to a file
squill ocr --window-id 42 --contains Login # capture + assert on-screen text (exit 20 if absent)
squill session start --agent builder        # begin a replayable session trace
squill mcp                                 # serve the Model Context Protocol over stdio

Running it bare launches the GUI; with a subcommand it stays headless and prints one path on stdout (warnings on stderr), with exit codes as the contract. It captures one image (capture), reads or asserts on-screen text (ocr), or records an ordered trail of frames an agent leaves behind (session) — and the same loop is exposed to MCP clients as twelve tools.

→ Full reference: docs/scripting.md — the stdout/exit-code contract, capture flags (--json / --max-width / --deterministic / --mask / --reveal), OCR assertions, best-effort PII redaction (capture --redact-pii, session frame --scan-pii / --redact-pii, session export --fail-on-pii — OCR the frame and mask or flag likely emails, cards, SSNs before output), the flight recorder + OpenTelemetry trace export, and the MCP tools. The exit-code contract is also printed in every squill … --help.


App blocklist

Name apps that must never be captured — a password manager, your keychain — and ShotQuill refuses to capture their windows and redacts them out of full-screen and region captures (an opaque block painted over the pixels, not an overlay, so nothing sensitive survives in the image). This covers the GUI, the CLI, and the MCP server alike.

Manage it from Settings → Blocked apps… (on macOS, pick from the running apps), from the command line, or by hand-editing the JSON file directly:

squill blocklist add --bundle-id com.1password.1password
squill blocklist add --name keychain      # app-name substring
squill blocklist list                     # --json for machines
squill blocklist remove --name keychain

The list is a plain JSON file, read by every surface so one rule protects them all:

  • macOS: ~/Library/Application Support/shotquill/blocklist.json
  • Windows: %APPDATA%\shotquill\blocklist.json
  • elsewhere: $XDG_CONFIG_HOME/shotquill/blocklist.json
{
  "version": 1,
  "rules": [
    { "bundle_id": "com.1password.1password" },
    { "name": "keychain" }
  ]
}

A window is blocked when any rule matches it: bundle_id matches the owning app's identifier exactly (case-insensitive — the robust default, since bundle ids are stable and unspoofable), or name matches its app name as a case-insensitive substring (handy for a quick edit). squill doctor prints the active rules; a blocked capture exits 6 (the MCP capture tool returns error type: "blocked"); every refusal and redaction is audit-logged.

Know the boundary — this is privacy hygiene, not a security control. Anything running as you can capture the screen by other means, so the blocklist defends against an over-eager or prompt-injected agent reaching for a password manager through ShotQuill, not against a determined adversary with code execution. Two honest limits: a full-screen capture can only be redacted where windows can be enumerated (macOS and X11; not under Wayland, which forbids it — blocklist-protected whole-screen / interactive captures are refused there rather than captured plainly), and an unreadable blocklist file fails closed (captures are refused until you fix it).


App allowlist

The inverse of the blocklist, and a tighter leash. The blocklist names what may never be captured; the allowlist, when you enable it, flips the default — ShotQuill then captures only the apps you list and refuses everything else. It is especially useful for agents driving the CLI or MCP: pin the allowlist to the one or two apps a task needs and the agent cannot wander off and screenshot your mail, chats, or desktop. Disabled by default, so it never gets in the way until you ask for it.

Manage it from Settings → Allowed apps… (tick the box to turn it on), from the command line, or by hand-editing the JSON file:

squill allowlist add --bundle-id com.apple.Terminal
squill allowlist add --name firefox       # app-name substring
squill allowlist enable                    # turn the restriction on
squill allowlist list                      # shows enabled state + rules (--json)
squill allowlist disable                   # back to normal capture
squill allowlist remove --name firefox

Enforcement covers the GUI, CLI, and MCP alike — the same as the blocklist. In the GUI, full-screen capture (and the region / full-screen modes of smart capture) are refused with a tray note, and smart capture only lets you pick a window that's on the list; non-allowed windows are skipped just like blocklisted ones.

When the allowlist is enabled:

  • a window or app capture is refused unless its target is on the list;
  • a whole-screen capture (full-screen, region, or display) is refused outright — its "only these apps" promise cannot be kept for a grab of everything, so the caller must target a specific window (--window-id) or app (--app);
  • a refused capture exits 6 (the MCP capture tool returns error type: "blocked"), and every refusal is audit-logged as capture_not_allowed.

It stacks with the blocklist: a window must be both off the blocklist and on the allowlist to be captured. The rule shape is identical to the blocklist (bundle_id exact match, or name substring). The file lives next to the blocklist:

  • macOS: ~/Library/Application Support/shotquill/allowlist.json
  • Windows: %APPDATA%\shotquill\allowlist.json
  • elsewhere: $XDG_CONFIG_HOME/shotquill/allowlist.json
{
  "version": 1,
  "enabled": true,
  "rules": [
    { "bundle_id": "com.apple.Terminal" },
    { "name": "firefox" }
  ]
}

Two things to know: an allowlist that is enabled with no rules allows nothing — a deliberate full lockdown, surfaced by squill doctor and the editor rather than left as mysterious blanket refusals; and like the blocklist it fails closed — an unreadable file, or a by-id capture on a backend that cannot enumerate windows to verify the target, is refused rather than passed through. The same boundary applies: this constrains ShotQuill's own capture paths against an over-eager or prompt-injected agent, not an adversary with code execution.

For agents: the allowlist can only be changed from the CLI or the GUI — it is deliberately not exposed over MCP, so an agent on the leash cannot loosen its own. Set it up before handing control over.


Configuration

Open Settings… from the menu-bar icon:

  • Language — English / 中文.
  • Save folder & image format (PNG / JPG).
  • Hotkeys for both capture modes.
  • Highlight window after — a delay before the hovered window fully lights up in smart capture, lifting its pixels out from under any overlap (off by default).
  • Editor finish keys — the in-editor copy and save keys (Space / Enter by default), each with its own enable toggle.
  • Adjust region with arrow keys (on) — keep a region crop nudgeable in the editor until the first annotation lands.
  • Edit in place (on) — open the editor frameless over the dimmed screen, rather than as a normal titled window.
  • Toolbar buttons — icon and text, icon only, or text only (icon and text by default).
  • After capture — auto-save and/or auto-copy toggles (above).
  • Include mouse pointer (off) — composite the cursor into captures.
  • Blocked apps… — manage the app blocklist (apps that are never captured).
  • Allowed apps… — manage the app allowlist (when enabled, the only apps that can be captured; off by default).
  • Launch at login — installs the platform's per-user startup entry (LaunchAgent on macOS, XDG autostart on Linux, the Run key on Windows).
  • Flash on capture (on) and Sound on capture (off) — capture feedback.

Troubleshooting

macOS

Captures come out black or empty. macOS is withholding screen content: grant Screen Recording in System Settings → Privacy & Security, then restart ShotQuill (macOS only applies the grant to freshly launched processes). For the CLI/MCP, remember the permission is attributed to the invoking app — your terminal or agent host — not to ShotQuill itself; squill doctor reports exactly which grant is missing.

A hotkey is silently dead. Another app may own the same combo — macOS gives no error; the events simply never arrive. Remap it in Settings. ShotQuill uses Carbon RegisterEventHotKey, so global capture hotkeys do not require Input Monitoring.

"ShotQuill can't be opened" on first launch. That's Gatekeeper on the ad-hoc-signed direct download — see Install for the right-click → Open / xattr fix. The Homebrew cask is not affected.

Linux

ShotQuill exits at startup with "needs a system tray". The Qt application came up, but no system-tray host is running. GNOME 42+ ships without legacy tray support — install the AppIndicator and KStatusNotifierItem Support extension and log out / in. KDE, XFCE, MATE, and Cinnamon include a tray by default. The squill CLI and MCP server still work even without a tray.

Global hotkeys do nothing on Wayland. ShotQuill uses the xdg-desktop-portal GlobalShortcuts interface there, because Wayland blocks classic out-of-band key grabs. If your compositor or portal backend does not implement GlobalShortcuts, ShotQuill reports that at startup. Workarounds: use the tray menu, or bind a compositor-level shortcut to squill capture (full screen → file) in your desktop's keyboard settings.

Captures fail with "Wayland blocks out-of-band grabs". Install xdg-desktop-portal and a backend for your desktop: xdg-desktop-portal-gnome, -kde, or -wlr. squill doctor will report when the portal is reachable.

squill ocr errors with "Tesseract is not installed" on Linux. Install the tesseract-ocr package (and language data such as tesseract-ocr-eng / tesseract-ocr-chi-sim) from your distribution; squill doctor reports OCR as available once the tesseract binary is on PATH. macOS uses Apple Vision and needs no extra install.

squill window list fails with "no EWMH-compatible window manager is running" (or "cannot connect to the X server"). X11 enumeration reads the window manager's EWMH properties, so it needs a running, EWMH-compliant WM (virtually all modern ones are) and a reachable display. Under Wayland it stays unsupported by design — the compositor refuses to let an app enumerate other apps' windows. Full-screen and region capture work regardless; smart-capture degrades to those modes.

Smart capture's window highlight never appears. Same reason as above — without window enumeration the overlay can't outline a window. Drag for a region or click for full screen instead.

Audit log

Which agent captured what? Read the audit log:

tail -f ~/Library/Logs/shotquill/audit.log                     # macOS (also in Console.app)
tail -f "${XDG_STATE_HOME:-$HOME/.local/state}/shotquill/audit.log"  # Linux
Get-Content "$env:LOCALAPPDATA\shotquill\Logs\audit.log" -Wait       # Windows PowerShell

Each JSONL entry records the action, target, destination, and the process chain that drove it (via: "cli" or "mcp"); the same line is mirrored to the unified log / journald, which user-space processes can't rewrite.

Still stuck? Run squill doctor and attach its output to a GitHub issue.


Privacy

ShotQuill is built to be trustworthy, and it's open source so you can verify it:

  • No keylogging. The global-hotkey listener only checks for your configured shortcut combos; it never records, stores, or forwards keystrokes.
  • OCR is on-device. Text recognition uses Apple Vision on macOS, Tesseract on Linux, and Windows OCR through WinRT — nothing is uploaded, and it works with no network connection.
  • Redaction is real. The mosaic tool rewrites the underlying pixels before export, so blurred-out content isn't recoverable from the saved image.
  • PII can be redacted automatically. Programmatic captures can OCR a frame and mask likely personal data — emails, card numbers, SSNs — before it ever leaves ShotQuill (squill capture --redact-pii, session frame --scan-pii / --redact-pii, session export --fail-on-pii). It is best-effort, not a guarantee, and runs fully on-device. See Scripting & agents.
  • Sensitive apps can be blocklisted. Name a password manager (or any app) and ShotQuill refuses to capture its windows and paints it out of full-screen shots — for the GUI, CLI, and agents alike. See App blocklist.
  • Agents can be put on an allowlist. Flip the default the other way: enable the app allowlist and ShotQuill captures only the apps you name, refusing every other window and every whole-screen grab — a tight leash for an agent on the CLI or MCP, off by default.
  • No telemetry. ShotQuill makes no network requests of its own.
  • Programmatic captures are accountable. Scripts and AI agents using the CLI or the MCP server go through the same OS consent as any app — macOS attributes Screen Recording to the invoking app, so the permission dialog names the real controller — and every programmatic capture leaves an audit entry (metadata only, never pixels) in a local JSONL file plus the tamper-resistant OS log store. The MCP server is strictly opt-in and, by design, returns captures to the agent's model — see Scripting & agents for what that means.

Tech stack

Python 3.10+ + PySide6 (Qt) for a self-drawn, cross-platform UI:

Concern macOS Linux Windows
GUI / editor canvas PySide6 (Qt Widgets + Graphics View) same same
Screen capture ScreenCaptureKit (macOS 14+), CGWindowList* fallback X11: QScreen.grabWindow; Wayland: xdg-desktop-portal over QtDBus QScreen.grabWindow (per-window via user32)
Window enumeration CGWindowList (always available) X11: EWMH over python-xlib; Wayland: by design refuses user32 EnumWindows (Z-order top-level windows)
Global hotkeys Carbon RegisterEventHotKey (no Input Monitoring needed) X11: pynput; Wayland: xdg-desktop-portal GlobalShortcuts when available pynput Win32 listener (no permission needed)
Launch at login per-user LaunchAgent XDG ~/.config/autostart/shotquill.desktop per-user Run key (HKCU\…\CurrentVersion\Run)
Image processing Qt (QImage) same same
OCR pyobjc → Apple Vision tesseract CLI (when installed) WinRT Windows.Media.Ocr (optional windows-ocr extra)

Platform-specific code (capture, hotkeys, OCR, autostart) sits behind small base.py interfaces, so the editor and output layers stay portable and adding a new OS means implementing those interfaces rather than touching the UI.


Development

python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

python -m shotquill              # launch the menu-bar app (macOS)
ruff check src tests             # lint
ruff format --check src tests    # formatting
pytest                           # tests

For local packaging smoke builds, see Packaging.

Screen capture, global hotkeys, and full-screen overlays depend on the target desktop session, so platform backends need smoke testing on their OS. Pure logic and Qt widgets can be developed and tested headlessly with QT_QPA_PLATFORM=offscreen where appropriate. Window-activation scenarios (tests/test_activation_macos.py) only run under a real macOS window server — the macOS CI leg, or a Mac without QT_QPA_PLATFORM set — because the offscreen platform performs no activation arbitration at all.

Project layout

src/shotquill/
├── app.py                # menu-bar app: tray icon, hotkey → capture → output wiring
├── cli.py                # `squill` argument parsing & exit-code contract
├── headless.py           # shared no-GUI capture/OCR core used by cli.py and mcp.py
├── mcp.py                # `squill mcp` — zero-dependency MCP stdio server
├── audit.py / paths.py   # audit trail for programmatic captures; platform dirs
├── config.py / i18n.py   # QSettings-backed prefs; EN/中文 string table
├── imaging.py            # raw capture pixels → QImage
├── capture/              # base.py + macos.py (ScreenCaptureKit), qtgrab.py (X11), wayland.py, windows.py
├── hotkeys/              # base.py + macos.py (Carbon), linux.py, wayland.py, windows.py
├── ocr/                  # base.py interface; macos.py, linux.py, windows.py
├── output/               # saver.py (files), clipboard.py
├── autostart/            # base.py + macos.py, linux.py, windows.py
└── ui/                   # editor, canvas, tools, smart capture overlay, settings, pin

Each tests/test_*.py mirrors a module above; platform-independent logic is tested headlessly, and capture/hotkeys/ocr/autostart backends hide behind base.py interfaces so a new OS is a new backend, not a UI rewrite.

Platform permissions

macOS — on first run, grant this in System Settings → Privacy & Security:

  • Screen Recording — required to capture the screen and enumerate windows.

Global capture hotkeys use Carbon RegisterEventHotKey, so they do not require Input Monitoring. ShotQuill's Settings dialog shows the live status of Screen Recording, with a button that jumps straight to the right privacy pane.

Linux / X11 — no special permission is required: the X server lets every client read the screen and listen for keys. xhost-style restrictions, an extreme SELinux/AppArmor profile, or a remote session without forwarding can each break capture; squill doctor reports what's missing.

Linux / Wayland — capture goes through xdg-desktop-portal: the first capture pops a system dialog asking which screen / window to share, and the choice is remembered for the session. Global hotkeys go through the GlobalShortcuts portal when the compositor implements it; there is no separate per-app keylogging-style permission to grant.


Uninstall

macOS

brew uninstall --cask shotquill        # Homebrew install
# or just drag /Applications/ShotQuill.app to the Trash (direct download)

ShotQuill keeps no hidden state beyond these per-user files — remove them for a clean slate:

What Where
Settings ~/Library/Preferences/com.wardmos.ShotQuill.plist
Launch-at-login agent ~/Library/LaunchAgents/com.wardmos.shotquill.plist (only if enabled in Settings)
Blocklist ~/Library/Application Support/shotquill/blocklist.json
Allowlist ~/Library/Application Support/shotquill/allowlist.json
Audit log ~/Library/Logs/shotquill/
Your screenshots ~/Pictures/ShotQuill/ (or your configured folder) — yours to keep

Linux

pipx uninstall shotquill               # pipx install
# or delete the downloaded .AppImage
What Where
Settings ~/.config/wardmos/ShotQuill.conf (QSettings INI)
Autostart entry ~/.config/autostart/shotquill.desktop (only if enabled in Settings)
Blocklist ${XDG_CONFIG_HOME:-~/.config}/shotquill/blocklist.json
Allowlist ${XDG_CONFIG_HOME:-~/.config}/shotquill/allowlist.json
Audit log ${XDG_STATE_HOME:-~/.local/state}/shotquill/
Your screenshots ~/Pictures/ShotQuill/ (or your configured folder) — yours to keep

Windows

Delete the unzipped release folder, or uninstall the Python package if you installed with pip.

What Where
Settings HKCU\Software\wardmos\ShotQuill (QSettings registry store)
Launch-at-login entry HKCU\Software\Microsoft\Windows\CurrentVersion\Run (only if enabled in Settings)
Blocklist %APPDATA%\shotquill\blocklist.json
Allowlist %APPDATA%\shotquill\allowlist.json
Audit/debug logs %LOCALAPPDATA%\shotquill\Logs\
Recorded sessions %LOCALAPPDATA%\shotquill\records\
Your screenshots Pictures\ShotQuill\ (or your configured folder) — yours to keep

Roadmap

  • Smart (window / region / full-screen) + full-screen capture
  • Annotation editor (shapes, text, highlighter, mosaic) + pin-to-screen
  • On-device OCR (macOS Vision; Linux Tesseract; Windows WinRT)
  • Hands-free auto save + clipboard
  • CLI for scripts & AI agents (squill capture / window list / display list / ocr / diff / session / doctor / mcp, plus blocklist / allowlist)
  • MCP server, so agents can capture and read the screen over Model Context Protocol
  • Linux / X11 backends — GUI, CLI, and MCP: menu-bar app via PySide6 + XDG autostart, full-screen / region capture via QScreen.grabWindow, global hotkeys via pynput
  • Linux / Wayland GUI, CLI, and MCP via xdg-desktop-portal (Screenshot + GlobalShortcuts portals where available)
  • Multi-monitor selectionsquill display list + capture --display N (and the matching MCP display_list tool / display argument)
  • Linux OCR backend (Tesseract) — squill ocr and the editor's extract-text action when the tesseract CLI is installed
  • Wayland smart-window parity — capture and hotkeys use portals, but window enumeration is still unavailable by design, so window highlight / direct window picking remains an X11/macOS/Windows capability
  • X11 window enumerationsquill window list, smart-capture window highlight, and full-screen blocklist redaction, via EWMH over python-xlib (Wayland forbids enumerating other apps' windows, so it stays unsupported there by design)
  • Windows backend — capture (QScreen.grabWindow), window enumeration (capture/windows.py, user32 EnumWindows), global hotkeys, and launch-at-login (the per-user Run key); on-device OCR via the WinRT engine ships behind the optional windows-ocr extra
  • Scrolling / long-page capture

Contributing

Issues and pull requests are welcome. Please run ruff check, ruff format, and pytest before submitting; CI runs the same on Linux, macOS, and Windows.


License

Apache-2.0. Copyright (C) 2026 wardmos.

ShotQuill bundles Qt via PySide6, which is licensed under the LGPLv3; the corresponding license notices are included with distributed builds.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

shotquill-0.0.13.tar.gz (424.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

shotquill-0.0.13-py3-none-any.whl (282.6 kB view details)

Uploaded Python 3

File details

Details for the file shotquill-0.0.13.tar.gz.

File metadata

  • Download URL: shotquill-0.0.13.tar.gz
  • Upload date:
  • Size: 424.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for shotquill-0.0.13.tar.gz
Algorithm Hash digest
SHA256 73c5040536b674f69ce78b359ef1dc238642a2c543c4babf3e72c44cccf5cf65
MD5 e8000ce4d67dc39a040f72e928930bd5
BLAKE2b-256 96a26f1946cbe6fe794b0c638ae1cbde4a5f31abfdcdf04269b7dd579ab8495c

See more details on using hashes here.

Provenance

The following attestation bundles were made for shotquill-0.0.13.tar.gz:

Publisher: release.yml on wardmos/shotquill

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file shotquill-0.0.13-py3-none-any.whl.

File metadata

  • Download URL: shotquill-0.0.13-py3-none-any.whl
  • Upload date:
  • Size: 282.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for shotquill-0.0.13-py3-none-any.whl
Algorithm Hash digest
SHA256 5a7a70f6fd3e6a5f33bd03b04490c5249a7b4f312432b11d530fefb8173d4c3b
MD5 b9da7024c55e111a7a4f330840bc1aa5
BLAKE2b-256 58c174d75f3c45a9f6d8aee2ea8e899ef37ad2ca0abb39e991a790f25c47d01a

See more details on using hashes here.

Provenance

The following attestation bundles were made for shotquill-0.0.13-py3-none-any.whl:

Publisher: release.yml on wardmos/shotquill

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page