pir-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| PIR_REGIONS | No | Path to a JSON file containing regions to define at startup. | |
| PIR_MAX_CELLS | No | Grid resolution on the long side; smaller is coarser and more private. | 64 |
| PIR_THRESHOLD | No | Default change threshold. | 0.05 |
| PIR_SELECT_CMD | No | Command for selecting a region; must print 'x,y wxh'. Set to an empty string to remove those tools entirely. Default depends on platform (e.g., slurp on wlroots). | |
| PIR_CAPTURE_CMD | No | Template for the capture command; {x} {y} {w} {h} are substituted. Must print a binary PPM (P6) to stdout. Default depends on platform (e.g., grim on wlroots). | |
| PIR_INTERVAL_MS | No | Default sampling period in milliseconds. | 500 |
| PIR_MAX_WAIT_MS | No | Cap for blocking calls in milliseconds. | 540000 |
| PIR_DEFAULT_WAIT_MS | No | Default timeout for blocking calls in milliseconds. | 55000 |
| PIR_PICK_WINDOW_CMD | No | Command to let a person pick a window; must print the chosen window's id. Default is Hyprland-specific logic. | |
| PIR_SELECT_TIMEOUT_MS | No | How long the person has to draw a selection in milliseconds. | 60000 |
| PIR_CAPTURE_TIMEOUT_MS | No | How long one capture may take in milliseconds. | 10000 |
| PIR_WINDOW_GEOMETRY_CMD | No | Command to get a window's geometry; gets {id} substituted and must print 'x,y wxh'. Default is Hyprland-specific logic. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| pir_define_regionA | Name a rectangle of the screen to watch. Coordinates are in the global layout the capture tool uses (on a multi-monitor wlroots layout an output left of the primary has negative x). Masks are rects inside the region, in region-local pixels, that are ignored: put a clock or spinner there. Redefining a name replaces it and forgets its last sample. |
| pir_define_windowA | Watch a window rather than a fixed rectangle: geometry is looked up from the window id before every capture, so the region follows the window when it moves. A resize counts as maximal change. Masks are window-local. The id is whatever your window-geometry command understands (a Hyprland address like 0x5f3a..., an X11 window id). |
| pir_pick_windowA | Ask the person at the screen to click the window to watch (visible windows are offered as boxes; Escape cancels). The region then follows that window. Prefer this over pir_define_window when a human is present. |
| pir_pick_regionA | Ask the person at the screen to draw the rectangle to watch (a selector such as slurp appears; Escape cancels). Prefer this over pir_define_region whenever a human is present: they choose what is sensed, and you get the geometry back. Blocks until they finish or the selector times out. |
| pir_pick_maskA | Ask the person to draw a rectangle inside an existing region that should be ignored (a clock, a spinner, a caret). Forgets the region's last sample, since masked grids are not comparable to unmasked ones. |
| pir_list_regionsA | The regions currently defined, with their geometry and masks. |
| pir_remove_regionC | Forget a region. |
| pir_sampleA | Capture the region once and score it against the previous sample of the same region (null on the first call). Cheap and non-blocking: use it to check the capture command works, to take a baseline before doing something, or to ask 'did anything happen there since I last looked?'. |
| pir_wait_for_changeA | Block until the region looks different from how it looked when this call started, or until timeout_ms. Returns changed=true with the score, or changed=false with the largest score seen. Use it as a doorbell: 'wake me when the build output moves', 'when the dialog closes', 'when the game loads'. |
| pir_wait_for_stillnessA | Block until consecutive samples have stayed below threshold for still_for_ms, or until timeout_ms. A short window means 'the page/animation has settled, safe to act'. A long window on something that should keep changing (a clock, a progress bar, a status bar) means it is frozen: still=true is then the alarm. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 10 tools
Each tool targets a distinct operation: sampling, defining, picking, waiting, listing, removing. The define/pick and change/stillness pairs are clearly differentiated by coordinate vs. human selection and blocking vs. non-blocking behavior.
All tools follow the pir_ prefix with snake_case verb_noun or verb_prep_noun patterns (e.g., define_region, wait_for_change, list_regions). The naming is uniform and predictable.
Ten tools is well-scoped for a screen-region monitoring server, covering definition, selection, observation, and removal without unnecessary duplication or bloat.
The lifecycle is well covered: define/pick/list/remove regions, plus sample and wait operations. Minor gaps exist—masks can only be added interactively via pir_pick_mask, and there is no explicit update tool—but redefining a region replaces it, so most workflows are supported.