Pointframe MCP Server

io.github.dimitar-radenkovv6.7.25Updated Oct 3, 2026

Windows screenshots, OCR, and redacted screen recording for AI agents. No desktop app needed.

Overview

AI-generated overview

Lets an AI assistant capture Windows screenshots, read on-screen text with OCR, and record redacted MP4 clips of a monitor or window.

What it does
Exposes tools to list monitors and visible windows, capture a monitor, sub-region, or window as a PNG, run OCR on a monitor or window to return recognized text, and start, check, or stop whole-monitor MP4 recordings with optional redaction rectangles. It also searches a local catalog of saved captures by filename or indexed OCR text and retrieves artifacts by opaque ID. Captured images are returned inline, downscaled, unless image output is disabled.
When to use it
Useful when an agent needs a real visual artifact of the Windows desktop rather than a text description: bug-report screenshots, reading error dialogs or terminal output via OCR, privacy-redacted support recordings, UI regression evidence, and multi-monitor troubleshooting.
Requirements
Windows 10 or later, desktop only. Runs as a local stdio process from an .mcpb bundle; the desktop app and .NET runtime are not required. Recording needs ffmpeg.exe, which the published bundle places next to the server executable. Artifacts are written under %LOCALAPPDATA%\Pointframe. No accounts, API keys, or environment variables are declared.
Before you install
Capture and recording read whatever is on screen, so sensitive content can end up in saved PNGs, MP4s, and OCR text; redaction rectangles must be supplied before frames reach ffmpeg. Recording excludes microphone audio. The server writes files to disk and can start or stop recordings. The desktop app collects anonymous usage telemetry, though screenshots, recordings, OCR output, file names, and paths are stated not to be sent.

Installation

In SourceWeft

  1. Open Pointframe MCP Server in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

Pointframe

[Pointframe icon]

Pointframe

A free Windows screenshot and recording tool built for fast bug reports, walkthroughs, and support replies.
Capture a region, a window, or a whole monitor — annotate, blur, record to MP4/GIF, and extract text with OCR.
Drive it from the tray app, the standalone CLI, or an AI agent over MCP.

🌐 Visit the Official Website

[CI] [codecov] [Latest release] [winget] [Downloads] [CLI downloads] [MCP downloads]

☕ If Pointframe saves you time, consider buying me a beer:
[PayPal] [Revolut]

🚀 Quick Start

Install in seconds with the Windows Package Manager:

Starting with the 5.0 release line, the winget package ID is DimitarRadenkov.Pointframe.

powershell
winget install DimitarRadenkov.Pointframe

Prefer a manual install? Download the latest installer from the Releases page.

  1. Install Pointframe with winget install DimitarRadenkov.Pointframe or download the latest installer from Releases.
  2. Press Print Screen to capture a region.
  3. Add arrows, text, or blur and then copy, save, pin, or record.

You can complete your first capture workflow in under a minute.

For the standalone command-line workflow, installation, artifact verification, exit codes, and troubleshooting, see the dedicated Pointframe CLI README.

Pointframe CLI

A self-contained Windows CLI for monitor and window discovery, PNG screenshots of a monitor, a sub-region, or a single window, on-screen text extraction via OCR, and whole-monitor MP4 recordings. The Pointframe desktop app, the .NET runtime, and the .NET SDK are not required.

powershell
winget install DimitarRadenkov.Pointframe.Clipointframe displays

winget adds a pointframe command to PATH. Each GitHub Release also includes Pointframe.Cli-<version>-win-x64.zip for a manual install: extract it and run Pointframe.Cli.exe.

The CLI requires an interactive Windows desktop session. It cannot capture a user's desktop from a Windows service (session 0).

powershell
.\Pointframe.Cli.exe displays.\Pointframe.Cli.exe windows.\Pointframe.Cli.exe capture --monitor '\\.\DISPLAY1' --output .\shot.png.\Pointframe.Cli.exe capture --monitor '\\.\DISPLAY1' --region 100,100,800,600.\Pointframe.Cli.exe capture-window --window-id 12345678.\Pointframe.Cli.exe ocr --monitor '\\.\DISPLAY1'.\Pointframe.Cli.exe ocr-window --window-id 12345678.\Pointframe.Cli.exe record --monitor '\\.\DISPLAY1' --seconds 10 --output .\take1.mp4

Use the exact monitorName emitted by displays, or a window handle emitted by windows. Every command other than --help/--version writes a single-line JSON response to standard output on both the success and the failure path, so a script can parse it the same way either way: success exits 0, a runtime failure exits 1 and carries an Error.Code (target_not_found, target_not_capturable, invalid_region, invalid_output_path, canceled, or capture_failed), and invalid arguments exit 2 with usage text on standard error.

Pass --output <file> (-o) to any command that produces a file to choose the exact path to write; parent directories are created for you. Without it, screenshots and their metadata sidecars are saved under %LOCALAPPDATA%\Pointframe\Screenshots and recordings under %LOCALAPPDATA%\Pointframe\Recordings, each with a generated timestamped name.

ocr captures the monitor the same way capture does, then runs Windows OCR against the captured image and adds a RecognizedText field to the JSON output (null when no text is found or no OCR language pack is installed). capture-window and ocr-window do the same for a single window by handle, using visible screen-rectangle semantics: an occluding window may appear in the capture, and minimized, zero-size, off-screen, and multi-monitor-spanning windows are rejected. record starts a direct MP4 recording, waits for the requested --seconds (or an earlier Ctrl+C for a graceful early stop that still finalizes and reports the artifact), then writes the combined session/artifact JSON; recordings require ffmpeg.exe on PATH, via POINTFRAME_FFMPEG_PATH, or bundled next to the executable.

Pointframe MCP Server

Pointframe also ships a standalone MCP server for agents that need to inspect the Windows desktop and produce verifiable screenshot or recording artifacts. The MCP server uses Pointframe.Engine directly; it does not start the Pointframe tray application, create a WPF overlay, or require the full Pointframe installer.

The standalone host requires an interactive Windows desktop session. It is a local stdio server intended to be launched by VS Code, Copilot, or another MCP client.

MCP capabilities

The server exposes:

  • 🔎 search_captures — search the local catalog of saved screenshots by filename or indexed OCR text. Results may be incomplete while newly discovered images are indexed.
  • 🗂️ get_capture — retrieve a catalog artifact by its opaque ID, including metadata and an optional downscaled inline preview. It never accepts arbitrary local paths.
  • 🖥️ list_displays — return monitor identifiers, physical pixel bounds, and DPI scales.
  • 🪟 list_windows — return visible top-level windows with handles, titles, process names, bounds, and containing monitor names. Window handles are session-local and temporary.
  • 📸 capture_monitor — capture a named monitor, or an optional monitor-local sub-region of it, and return a PNG artifact plus metadata. The captured image is also returned inline as an image block (downscaled to at most 1600 px on its longest edge) so the calling model can see it directly; pass includeImage: false to get metadata only.
  • 📸 capture_window — capture the visible screen rectangle of a window by its handle from list_windows. Occluding windows may appear; minimized, off-screen, and multi-monitor-spanning windows are rejected. Returns the image inline like capture_monitor unless includeImage: false.
  • 🔤 read_text_from_monitor — capture a named monitor (optionally a sub-region) and run OCR against it, returning the PNG artifact plus recognized text (null when no text is found or no OCR language pack is installed). The captured image is also returned inline unless includeImage: false.
  • 🔤 read_text_from_window — capture a window by handle and run OCR against it. Same screen-rectangle capture semantics as capture_window, and the same inline-image behavior.
  • 🎥 start_recording — start a whole-monitor MP4 recording. redactionRegionsCaptureLocalPixels is optional; omit it to record without redaction.
  • ⏹️ stop_recording — stop the active recording and return the finalized MP4 artifact, metadata, and event sidecar references.
  • ⏱️ get_recording_status — report whether a recording is currently active and, if so, its session details and elapsed duration; returns no session when nothing is recording.

The server also exposes MCP resources:

  • pointframe://commands — the exact list of registered tool identifiers (varies depending on whether desktop testing is enabled).
  • pointframe://server-info — server version, whether desktop testing tools are enabled, and whether ffmpeg (required for recording) was found, along with where it was found (EnvironmentVariable, Bundled, or Path). Useful for a health check before calling start_recording.

The normal workflow is:

  1. Call list_displays and select a returned monitorName.
  2. Call capture_monitor with that exact monitor name, call read_text_from_monitor to also extract on-screen text, or call start_recording. Pass an optional region ({x, y, width, height} in monitor-local physical pixels) to capture_monitor/read_text_from_monitor to limit the capture to a sub-rectangle instead of the whole monitor; a region outside the monitor's bounds is rejected rather than clipped.
  3. For recording, pass redaction rectangles in capture-local physical pixels. Omit the argument entirely when no redaction is required.
  4. Call get_recording_status at any time to check whether a recording is active before calling stop_recording.
  5. Call stop_recording to finalize the MP4 and retrieve its metadata.

Example tool arguments:

json
{  "monitorName": "\\\\.\\DISPLAY1"}
json
{  "monitorName": "\\\\.\\DISPLAY1",  "redactionRegionsCaptureLocalPixels": [    { "x": 120, "y": 80, "width": 240, "height": 48 }  ],  "framesPerSecond": 20}

Responses contain structured JSON with Success, operation identifiers, artifact paths, byte lengths, SHA-256 hashes, monitor geometry, DPI information, and sidecar paths. Artifact paths are local filesystem paths on the machine running the MCP server. The four capture and OCR tools additionally return the captured image itself as an inline image content block — downscaled to at most 1600 px on its longest edge, while the full-resolution PNG is always saved to disk — so a client that cannot reach the server's filesystem can still see the screenshot. Pass includeImage: false to suppress it.

MCP use cases

The MCP server is useful when an agent needs a local, verifiable visual artifact rather than a text-only description of the Windows desktop:

  • Bug report capture: call list_displays, select the affected monitor, then call capture_monitor to produce a PNG and metadata sidecar that can be attached to a report.
  • Reading on-screen text: call read_text_from_monitor to extract error dialogs, logs, or terminal output as plain text alongside the screenshot, without a separate OCR step.
  • Privacy-safe support recording: call start_recording with capture-local rectangles covering credentials, tokens, customer data, or other sensitive areas, then call stop_recording when the reproduction is complete. Redaction is applied before frames are passed to ffmpeg.
  • UI regression evidence: capture the relevant monitor before and after an interaction and use the returned artifact paths and SHA-256 values to identify exactly which files were produced.
  • Multi-monitor troubleshooting: discover displays first and target the exact monitorName returned by list_displays instead of relying on screen order or desktop coordinates.
  • Reproducible automation artifacts: use the structured response metadata to record the operation ID, monitor, DPI, physical bounds, file size, timestamp, and checksum alongside test or support results.

The server is intentionally local: it is not a remote desktop service and does not start the Pointframe WPF application. Recording does not include microphone audio. Event sidecars contain lifecycle and declared-redaction events, but do not contain bitmap data, OCR text, clipboard contents, or prompts.

Artifacts are written beneath %LOCALAPPDATA%\Pointframe:

text
Screenshots\*.pngScreenshots\*.png.metadata.jsonRecordings\*.mp4Recordings\*.mp4.metadata.jsonRecordings\*.mp4.events.jsonl

Metadata includes the artifact path, byte length, SHA-256, timestamp, monitor, DPI, and physical capture bounds. Recording event sidecars contain lifecycle and declared-redaction events without bitmap data, OCR text, clipboard contents, or prompts.

Connect your MCP client

The server ships as a .mcpb bundle on every release: the self-contained win-x64 server, ffmpeg.exe for recording, and an MCPB manifest.json. It does not need the Pointframe desktop app or the .NET runtime.

Claude Desktop. Download Pointframe.Mcp-win-x64.mcpb and open it; Claude Desktop installs it as an extension.

Every other client runs the server from a folder on disk. Download and unpack the latest bundle once (a .mcpb is a ZIP archive), and run the same lines again to update:

powershell
$dir = "$env:LOCALAPPDATA\Programs\Pointframe.Mcp"$mcpb = "$env:TEMP\Pointframe.Mcp-win-x64.mcpb"Invoke-WebRequest https://github.com/dimitar-radenkov/Pointframe/releases/latest/download/Pointframe.Mcp-win-x64.mcpb -OutFile $mcpbNew-Item -ItemType Directory -Force $dir | Out-Nulltar -xf $mcpb -C $dir

Stop the server in your client before updating, because Windows locks a running Pointframe.Mcp.exe. Then register it:

  • Claude Code

    powershell
    claude mcp add --scope user pointframe -- "$env:LOCALAPPDATA\Programs\Pointframe.Mcp\Pointframe.Mcp.exe"
  • VS Code: run MCP: Add Server from the Command Palette, choose Command (stdio), and enter the path to Pointframe.Mcp.exe. Or add it to .vscode/mcp.json or your user MCP configuration, using your own user name in the path:

    json
    {  "servers": {    "pointframe": {      "type": "stdio",      "command": "C:\Users\<you>\AppData\Local\Programs\Pointframe.Mcp\Pointframe.Mcp.exe"    }  }}
  • Cursor, Windsurf, and other clients that use the mcpServers format, such as %USERPROFILE%\.cursor\mcp.json:

    json
    {  "mcpServers": {    "pointframe": {      "command": "C:\Users\<you>\AppData\Local\Programs\Pointframe.Mcp\Pointframe.Mcp.exe"    }  }}

To check the connection, ask the agent to list your displays; it should call list_displays. The pointframe://server-info resource reports the server version and whether ffmpeg was found for recording.

Each release is also published to the official MCP Registry as io.github.dimitar-radenkov/pointframe-mcp, so registry-aware clients can find and install it. The matching *.server.json attached to the release pins the MCPB URL and includes the bundle SHA-256; verify the adjacent .sha256 file before installation when your client does not verify the bundle itself.

For the opt-in black-box desktop-testing driver, including policy validation, worker behavior, gate procedures, and evidence limits, see the dedicated desktop-testing MCP README. Detailed operator notes remain in MCP desktop testing.

Build the MCP package locally

powershell
dotnet restore Pointframe.Mcp/Pointframe.Mcp.csproj./packaging/build-mcp-package.ps1 `  -Version "1.0.0" `  -FfmpegPath "C:\path\to\ffmpeg.exe"

Use the current release version instead of 1.0.0 when producing a release package. The script writes the MCPB bundle, a legacy ZIP with the same contents, a SHA-256 checksum, and release-ready server.json metadata under packaging/output.

For local development, point your client's configuration at the Debug executable instead, and rebuild Pointframe.Mcp after code changes before restarting the MCP server.

Test the MCP server locally

Build the server and run the repository's protocol smoke test:

powershell
dotnet build Pointframe.Mcp/Pointframe.Mcp.csproj./packaging/test-mcp-stdio.ps1 `  -ExecutablePath ".\Pointframe.Mcp\bin\Debug\net10.0-windows10.0.18362.0\Pointframe.Mcp.exe"

The smoke test verifies the MCP initialize handshake and confirms that the exact expected tool set is advertised, both with desktop testing disabled and enabled. To test an actual capture, configure the executable in VS Code, call list_displays, then call capture_monitor (or read_text_from_monitor) with one of the returned monitor names. A successful capture should have a matching .metadata.json sidecar whose SHA-256 and byte length agree with the image.

Recording currently captures a whole monitor without microphone audio. Redaction regions are capture-local physical pixels and are applied before ffmpeg receives the frame. The process must run in the logged-in interactive Windows session; Windows services running in session 0 cannot capture the user desktop.

Troubleshooting

  • No displays are returned or capture fails: run the MCP server in the same logged-in interactive Windows session as the desktop you want to capture. Windows services and session-0 processes cannot capture the user desktop.
  • capture_monitor rejects the monitor: use the exact monitorName returned by list_displays; do not substitute a friendly display label.
  • Recording cannot start: confirm that no other Pointframe recording is active, the requested monitor still exists, and framesPerSecond is between 1 and 60.
  • Recording finalization fails: make sure ffmpeg.exe is next to Pointframe.Mcp.exe in the extracted package, or rebuild the package with -FfmpegPath pointing to a valid Windows ffmpeg executable.
  • The MCP client reports invalid protocol output: stdout is reserved for MCP JSON-RPC messages. Run the published executable through the configured MCP client rather than wrapping it in a shell that writes additional output.
  • Artifacts cannot be opened: artifact paths refer to the MCP server's machine and user profile. The client must have access to that filesystem.

If you find Pointframe useful, a ⭐ on GitHub helps others discover it — thank you!

✨ Key highlights

  • Live Video Annotations: Draw, highlight, and redact while recording. No need for post-production video editing.
  • Privacy First (Live Blur): Drag over sensitive content (passwords, emails, API keys) to apply a live Gaussian blur that stays hidden in the final export.
  • Built-in OCR: Lasso any text on your screen (even in images or videos) to instantly copy it to your clipboard.
  • Pin to Screen: Pin captured screenshots as floating, always-on-top windows for quick reference while coding or writing.

🆕 What shipped in recent releases

Jul 2026

  • Tray menu UX refresh — Improved command grouping, clearer labels, and iconized top-level actions.
  • Capture Library OCR hardening — Better reliability and scale for OCR-backed library search.
  • Capture + recording hot-path optimizations — Smoother performance in frequent capture/recording flows.

Jun 2026

  • Clean Window Snip — Capture cleaner active-window results via tray action and hotkey.
  • Video watermark support — Configurable watermark overlays for recorded MP4 output.
  • Video trim workflow — Trim recordings directly in-app from recent recordings actions.
  • Auto-update tray notification improvements — Better update signaling and install flow behavior from tray.

May 2026

  • Capture delay customization — Adjustable delay presets to capture menus and transient UI states.
  • Screenshot watermark support — Add configurable watermarking for screenshots.
  • Library and tray workflow upgrades — Open folders submenu, richer recents actions, and improved tray ergonomics.
  • Expanded auto-update intervals — Additional cadence options including short intervals and disable mode.

Apr-Mar 2026 (foundation releases)

  • Whole-screen snip mode and whole-screen record hotkey.
  • Recording HUD improvements including compact mode and better in-recording controls.
  • GIF export, cursor highlight, and click ripple for clearer instructional recordings.
  • Open existing image, callout tool, color picker, pixel ruler, and style presets.
  • Telemetry and usage reporting foundation for anonymous feature adoption metrics.

For full detail by version, see the Releases page.

Why people use it

  • Show the problem, not just describe it — Bugs and UI issues are easier to understand when the screenshot or recording already contains the important highlights.
  • Make tutorials easier to follow — Arrows, text, and numbered steps keep people focused on what matters.
  • Hide private details before sharing — Blur emails, passwords, tokens, and anything else you do not want on screen.
  • Work from one place — Capture, annotate, copy, save, pin, and record without bouncing between tools.

Features

  • Region capture — Press the configured hotkey (default: Print Screen) to draw a selection on screen
  • Whole-screen snip — Instantly capture the entire screen from the tray icon or a dedicated hotkey
  • Clean window snip — Capture a cleaner active-window result directly from tray and dedicated hotkey
  • Frozen screen snapshot — The screen is captured instantly when the hotkey is pressed, freezing menus, tooltips, and popups exactly as they appear
  • Selection magnifier — A zoomed loupe follows your cursor while drawing the capture region for pixel-accurate selection
  • Configurable capture hotkeys — Change the region-capture hotkey and the whole-screen record hotkey independently from Settings
  • Annotation tools — Arrow, line, rectangle, circle, pen, highlighter, text, numbered labels, blur/pixelate, callout (speech bubble), color picker, pixel ruler
  • Style presets — Up to 5 named color-and-thickness shortcuts shown as quick-access dots in the annotation toolbar; fully configurable in Settings
  • Color picker tool — Sample any pixel color from the frozen screenshot; the loupe zooms in with a hex preview and sets the active annotation color
  • Pixel ruler tool — Draw a ruler across the screenshot to measure distances in pixels
  • Blur tool — Drag over sensitive content (faces, emails, passwords) to apply a Gaussian blur before sharing
  • OCR — Copy Text — Draw a lasso around text in the screenshot to extract it via OCR and copy to clipboard (uses Windows.Media.Ocr, no external dependencies)
  • Capture Library — Browse your saved captures, filter by date range, and search by filename or OCR text from the tray Library entry
  • Open existing image — Load a PNG, JPG/JPEG, or BMP from the tray menu and annotate it without taking a new screenshot
  • Pin screenshot — Pin the captured screenshot as a floating, always-on-top, resizable window for quick reference while you work
  • Screenshot Beautifier — Frame a capture on a gradient or solid background (seven presets) for a presentation-ready image
  • Screenshot watermark — Optionally stamp a configurable text watermark on captured screenshots
  • Undo / redo — Full undo/redo stack during annotation
  • Copy & auto-save — Copy to clipboard; optional auto-save to a configurable folder
  • Screen recording — Record a selected region to MP4 (H.264 via ffmpeg) or start a whole-screen recording instantly with Ctrl+Shift+R (default); optional microphone audio from a selected Windows input device
  • Recording-time annotations — Add shapes and text directly on top of a recording while it is in progress; switch between draw mode and interact mode from the floating HUD
  • Video watermark — Optionally burn a configurable watermark into MP4 recordings
  • Video trim — Trim the start and end of a recent recording from the tray's Recent recordings menu (requires ffmpeg)
  • Tray menu icons — Core tray actions now include consistent glyph icons for faster scanning
  • Cursor highlight — Configurable glowing ring around the cursor during recording so viewers never lose track of your pointer
  • Click ripple — Visual ripple effect on mouse clicks during recording to make interactions obvious
  • GIF export — Export any recent recording to GIF directly from the tray's Recent recordings menu (requires ffmpeg)
  • Recording transcripts — Automatically transcribe narrated recordings to .txt and .srt sidecar files. Runs entirely on your machine with Whisper — no cloud, no API key, nothing uploaded. English only; transcribes microphone narration, not system audio
  • Capture delay — Configurable countdown (0 / 3 / 5 / 10 s) before the selection overlay appears, useful for capturing menus and hover states
  • Auto-updates — A background service checks GitHub Releases on launch and on a configurable schedule (every 2 hours / 6 hours / 12 hours / day / 2 days / 3 days / never). When a new version is found a tray balloon appears; click it to confirm and install without opening the browser
  • System tray — Runs silently in the background; all actions accessible from the tray icon
  • Theme support — Choose Light, Dark, or follow the system theme from Settings

Use cases

  • Bug reports — Capture a precise region, annotate it, and copy or save the result for issue tracking and support requests
  • Documentation — Create quick step-by-step screenshots with arrows, numbered steps, and text callouts for guides and tutorials
  • Live workflow capture — Record a selected region while drawing annotations on top of the recording as you work
  • Sensitive content redaction — Blur passwords, emails, and other private details before sharing screenshots or recordings
  • Text extraction — Select text in a screenshot with OCR and copy it directly to the clipboard

System tray menu

Right-click the tray icon to access all actions:

ItemDescription
New SnipOpen the region-capture overlay (same as the capture hotkey)
Whole Screen SnipInstantly capture the entire screen
Clean Window SnipCapture the active window with a cleaner result
Open Image...Load a PNG / JPG / BMP file and open it in the annotation overlay
Recent CapturesSubmenu listing the last 5 saved screenshots; each has Open and Open folder actions
Recent RecordingsSubmenu listing the last 5 recordings; each has Open, Trim, Export to GIF, and Open folder actions
LibraryOpen the capture library window
Open FoldersQuick access to Snips Folder, Videos Folder, and Logs Folder
SettingsOpen the Settings window
Check for Updates / Install UpdateManually check for updates or install a pending update directly from tray
AboutShow version information
Quit PointframeQuit the application

Left-clicking the tray icon triggers New Snip directly.

Settings

Open Settings from the tray icon to configure:

Capture

SettingDescription
Screenshot save folderWhere auto-saved screenshots are written
Auto-save on copyAutomatically save every screenshot when copied
Capture delayCountdown (sec) before the selection overlay opens: 0 / 3 / 5 / 10
Capture hotkeyThe key that triggers the region-capture overlay (default: Print Screen); supports modifier keys (Ctrl, Shift, Alt)

Recording

SettingDescription
Recording output folderWhere recorded MP4 files are saved
Record hotkeyThe key combination that starts a whole-screen recording (default: Ctrl+Shift+R)
Video watermarkOptional watermark overlay in MP4 recordings
Cursor highlightShow a glowing ring around the cursor during recording; configurable size
Click rippleShow a ripple effect on mouse clicks during recording
Microphone (advanced)Include microphone audio when recording starts
Microphone device (advanced)Which Windows audio input device to use
Transcript (advanced)Generate a .txt and .srt transcript after a recording is saved (on by default). Requires microphone audio and the English speech model; the row shows which one is missing and offers to download it
GIF export FPS (advanced)Frame rate for GIF exports: 5 / 8 / 10 / 15 / 20

Annotation

SettingDescription
Default annotation colorPre-selected color when the overlay opens
Stroke thicknessDefault pen/shape width
Style presetsUp to 5 named color-and-thickness shortcuts shown in the annotation toolbar

Shortcuts

SettingDescription
Region capture hotkeyOpens the region capture overlay (default: Print Screen)
Whole-screen record hotkeyStarts whole-screen recording (default: Ctrl+Shift+R)
Clean window snip hotkeyStarts clean-window capture (default: Ctrl+Shift+W)
Overlay shortcutsConfigure copy, save-as, undo, redo, show-shortcuts, and close keys for the overlay

App

SettingDescription
ThemeApp appearance: Light, Dark, or System (follows Windows)
Auto-update check intervalHow often to check for new releases: Every 2 hours / Every 6 hours / Every 12 hours / Every day / Every 2 days / Every 3 days / Never

Keyboard shortcuts

ShortcutAction
Print Screen (default, configurable)Open region-capture overlay
Ctrl+Shift+R (default, configurable)Start whole-screen recording
Ctrl+Shift+W (default, configurable)Start clean-window snip
Ctrl+ZUndo last annotation
Ctrl+YRedo annotation
Ctrl+CCopy screenshot to clipboard
EscapeClose the overlay / cancel current action

Requirements

  • Windows 10 or later
  • .NET 10 Desktop Runtime
  • ffmpeg — for MP4 recording and GIF export. The installer offers to download it; it can also be placed next to the app or on PATH
  • English speech model (~141 MB) — only for recording transcripts. Tick the optional component during setup, or download it later from Settings ▸ Recording
  • Standalone MCP recording additionally requires ffmpeg.exe; the published MCP package builder places it next to Pointframe.Mcp.exe

Installation

Via Scoop

powershell
scoop install pointframe

Via winget (recommended)

powershell
winget install DimitarRadenkov.Pointframe

Manual installer

Download the latest installer from the Releases page and run it. During setup you can choose to download ffmpeg.exe, which is required for MP4 recording and GIF export.

Troubleshooting

  • Recording or GIF export does not start — Pointframe requires ffmpeg.exe for MP4 recording and GIF export. If you skipped the ffmpeg download during setup, install ffmpeg.exe next to the app, under Assets\ffmpeg, or on PATH.
  • OCR is unavailable — OCR uses Windows.Media.Ocr and requires a supported Windows build.
  • Hotkey seems ignored — Make sure another app is not already using the same key and try changing the capture hotkey in Settings.
  • App is running but not visible — Pointframe lives in the system tray after launch.

Building from source

powershell
git clone https://github.com/dimitar-radenkov/Pointframe.gitcd Pointframe
dotnet build Pointframe/Pointframe.csprojdotnet run   --project Pointframe/Pointframe.csproj
# Build the standalone MCP hostdotnet build Pointframe.Mcp/Pointframe.Mcp.csproj

Running tests

powershell
dotnet test Pointframe.Tests/Pointframe.Tests.csproj

Project structure

Pointframe/             Main WPF application  App.xaml.cs           DI setup, tray icon, global hotkeys  AnnotationTool.cs     Enum of all annotation tool types  CountdownWindow       Fullscreen countdown overlay  OverlayWindow         Region-selection and annotation UI  RecordingOverlayWindow  Live annotation surface during recording  ViewModels/           MVVM view models  Services/             Screen capture, recording, geometry, update check  Models/               Immutable data records and settings
Pointframe.Tests/       xUnit test project  Services/             Service unit tests  ViewModels/           ViewModel unit tests

Versioning

Versions are managed automatically by Nerdbank.GitVersioning.

  • The base version (major.minor) is declared in version.json.
  • The patch number is derived from the commit height — it increments automatically with every commit, so you never need to touch it manually.
  • On a tagged release (v*) the version has no pre-release suffix (e.g. 1.2.5). On non-release builds a short commit hash is appended (e.g. 1.2.5-g1a2b3c4).

To bump the version:

GoalAction
Bug-fix / patchNothing — commit height auto-increments
New feature (minor)Edit version.json → "version": "1.3"
Breaking change (major)Edit version.json → "version": "2.0"

Tech stack

  • WPF / .NET 10
  • CommunityToolkit.Mvvm — [ObservableProperty], [RelayCommand]
  • Microsoft.Extensions.DependencyInjection — constructor injection throughout
  • Serilog — file + debug logging (%LOCALAPPDATA%\Pointframe\logs\)
  • ffmpeg — external encoder used for MP4 recording and GIF export
  • Microsoft.Extensions.Hosting — Generic Host + BackgroundService for the auto-update background loop
  • Windows.Media.Ocr — built-in Windows OCR for text extraction
  • Hardcodet.Wpf.TaskbarNotification — system tray icon
  • Nerdbank.GitVersioning — automatic semantic versioning from git history
  • xUnit — unit tests
  • Azure Monitor / OpenTelemetry — anonymous usage telemetry (disabled when connection string is absent)

🤝 Contributing

We welcome contributions! Whether it's reporting a bug, suggesting a feature, or submitting a pull request. Pointframe is built on a very clean, modern stack (.NET 10, WPF, CommunityToolkit.Mvvm) making it a great jumping-off point for developers.

  1. Check out our Developer Guide and Architecture Knowledge Base.
  2. Browse the open issues or look for ones tagged good first issue.
  3. Open a Pull Request!

Privacy & Telemetry

Pointframe collects anonymous, privacy-safe usage telemetry in official builds to help understand how the app is used and catch errors early. Screenshots, recordings, OCR output, file names, file paths, exception messages, and stack traces are not sent as telemetry.

What is collected

Every event below is defined in TelemetryEventCatalog.cs, which is the single source of truth. A unit test fails the build if this table and the catalog ever disagree.

App lifecycle

EventProperties
app_startedos_build, screen_count
startup_completedduration_ms
app_heartbeatuptime_minutes (sent every 4 hours while the tray app remains open)
app_closedsession_minutes

Capture

EventProperties
snip_startedtype (region / whole_screen), source (tray / hotkey)
snip_cancelledtype (region / whole_screen)
capture_delay_useddelay_seconds
capture_completedaction (copy / save / save_as / auto_save)
capture_pinned—
first_capture_completedcapture_type, first_action, time_from_install_minutes when available
open_image_used—
annotation_committedtool, count (one event per tool, sent once when the annotation surface closes)

Recording

EventProperties
recording_startedtype (region / whole_screen)
recording_completedduration_seconds when available
transcript_completedsuccess, duration_seconds, plus segment_count on success or skip_reason when skipped
transcript_failedexception_type
first_recording_completedwith_audio, duration_seconds and time_from_install_minutes when available
recording_hud_pause_toggledstate
recording_hud_stoppedduration_seconds
recording_hud_microphone_toggledstate
recording_hud_display_mode_changeddisplay_mode
recording_hud_annotation_input_toggledannotation_input_state
recording_hud_tool_selectedannotation_tool
recording_hud_undo_annotations—
recording_hud_clear_annotations—
ffmpeg_missing—
microphone_unavailable—

Export and editing

EventProperties
gif_export_started—
gif_export_completedsuccess, duration_seconds
video_trim_opened—
video_trim_started—
video_trim_completedsuccess, canceled
beautify_opened—
screenshot_beautified—
screenshot_beautified_copied—

OCR and library

EventProperties
ocr_attemptedselection_width_px, selection_height_px
ocr_no_textselection_width_px, selection_height_px
ocr_usedselection_width_px, selection_height_px
library_open_used—
library_ocr_search_used—

Settings and About

EventProperties
settings_openedapp_section
settings_section_changedapp_section
settings_savedapp_section
settings_section_resetapp_section
settings_defaults_restored—
settings_canceled—
about_opened—
about_closed—
about_url_openedurl_host (host name only, never a full URL)

Updates and diagnostics

EventProperties
update_check_manual—
update_availableversion
update_confirmedversion
update_dismissedversion
unhandled_exceptionexception_type, context, last_action when available

Every event includes an app version, a per-run session_id, a telemetry_channel (product or diagnostic), a telemetry_schema_version, and an install_id when one is available. The install ID is a random GUID generated once on first launch and stored locally. It is used only to count unique installs; it is not tied to an account or identity.

Properties are allow-listed per event in the catalog: anything a caller passes that the event does not declare is reported as a schema violation, and every value is truncated to 200 characters. Both measures exist to keep paths, file names, and recognised text out of telemetry by construction rather than by convention.

The last_action value attached to unhandled_exception is the name of the most recent product event — background diagnostic events such as app_heartbeat never overwrite it.

Nothing leaves your machine except these anonymised events. Screenshots, recordings, OCR output, file names, and file paths are never transmitted. Local diagnostic logs are stored under %LOCALAPPDATA%\Pointframe\logs\ and may include local paths to help troubleshoot issues; they are not uploaded automatically.

Source builds

Telemetry is disabled automatically when the ApplicationInsights:ConnectionString value in appsettings.json is empty (which is the default in the source repository). Only official builds distributed via the installer include the real connection string.

For contributors

To enable telemetry locally during development, create Pointframe/appsettings.Local.json (gitignored):

json
{  "ApplicationInsights": {    "ConnectionString": "<your-connection-string>"  }}

To set up your own Azure Application Insights resource, follow the Azure Monitor setup guide.

Feature usage report

Use the ready-to-run KQL report pack in docs/appinsights-feature-usage-queries.kql to track:

  • Weekly active installs and sessions
  • Per-feature adoption (% installs that used each feature)
  • Feature funnel conversion (snip -> annotate -> pin/ocr)
  • Power-user and stickiness indicators
  • Version split and regression spotting after releases

Source: README.md at commit cd1707e

Tools

0
Tool metadata has not been indexed yet.

Version history

1
  1. v6.7.25LatestOct 3, 2026