ScreenSight
AGENTS.md4 starsChanged 3 months agoMITView on GitHub
Instructions for any coding agent (opencode, Claude Code, etc.) working in this repo. Read PROJECT.md fully before writing code. It defines what's already built, what's left, and the safety invariants that are not up for reinterpretation. Build in this order — each step is independently testable before the next depends on it:
- Installs packages
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,843 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository2 other files it gives its agents.
- llms.txtllms.txt
- claude-codeSkill
The file
We split this AGENTS.md into the rules it gives an agent
6 rules. About 0 are common, 1 is distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 7
Read PROJECT.md fully before writing code.
- Very specific: line 11
Never bypass
core.capture_once(): Every code path that ends in a screenshot — CLI, MCP tool, daemon loop — must call core.capture_once(). - Very specific: line 12
The master switch check stays inside
core.py: Don't add a redundant "is it on?" check anywhere else that could drift out of sync — one … - Distinctive: line 13
Don't weaken the blocklist or redaction silently: If you need to change matching logic (e.g.
- Very specific: line 15
Cross-platform parity: If you add a feature to one capture/*.py backend, add it (or a documented graceful fallback) to all three.
- Very specific: line 24
No print statements inside src/screensight/* library code except __main__.py (CLI output) — library functions return values, the CLI …
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md
Instructions for any coding agent (opencode, Claude Code, etc.) working in this repo.
Read first
Read PROJECT.md fully before writing code. It defines what's already built, what's left, and the safety invariants that are not up for reinterpretation.
Ground rules
- Never bypass
core.capture_once(). Every code path that ends in a screenshot — CLI, MCP tool, daemon loop — must callcore.capture_once(). Do not callcapture/*.pybackends directly from anywhere exceptcore.py. If a new surface needs capture, import fromcore, not fromcapture. - The master switch check stays inside
core.py. Don't add a redundant "is it on?" check anywhere else that could drift out of sync — one source of truth. - Don't weaken the blocklist or redaction silently. If you need to change matching logic (e.g. blocklist substring → regex), keep it strictly more conservative (fewer false negatives), and note the change in
PROJECT.md's non-negotiables section if the behavior contract changes. - No new screenshot files accumulate on disk. One frame path (
config.FRAME_PATH), overwritten. If you add a "keep last N frames for diffing" feature, store them under~/.screensight/with the same off/cleanup guarantees, and delete onscreensight off. - Cross-platform parity. If you add a feature to one
capture/*.pybackend, add it (or a documented graceful fallback) to all three.active_window_title()returningNoneis a valid fallback — callers must already treatNoneas "unknown," never as "safe." - No new runtime dependencies without a reason. Current deps:
fastmcp,pillow. CLI uses stdlibargparse, notclick— keep it that way unless there's a concrete need. Platform capture uses native OS tools viasubprocess, never a screenshot pip package (keeps the "no extra app" property from the original). - Daemon must be a separate OS process, not a thread inside the MCP server. MCP servers commonly run over stdio per-session; a daemon needs to outlive that.
watch.pyshould be launchable viasubprocess.Popen(..., start_new_session=True)from both the CLI and the MCP tool, writing its own pidfile (config.DAEMON_PID_FILE) soscreen_watch_stopcan find and kill it. - MCP tool docstrings are user-facing. The calling agent reads the docstring to decide when to invoke a tool — write it like a man page entry, not a code comment. Tools live in
src/screensight/tools/split by domain (control.py,screen.py,audio.py,watch.py). Each module exports aregister(mcp: FastMCP) -> Nonefunction;mcp_server.pyis a thin orchestrator that callsregister_all(mcp)fromtools/__init__.py. To add a new tool, add the function to the appropriate domain module and register it there — do not add inline tools tomcp_server.py.
Conventions
- Python 3.10+, type hints everywhere,
from __future__ import annotationsat the top of every module (already the pattern in existing files — match it). dataclassesfor structured returns (seeCaptureResult,CaptureOutcome) instead of raw dicts/tuples, except at JSON-serialization boundaries (state files).- No print statements inside
src/screensight/*library code except__main__.py(CLI output) — library functions return values, the CLI formats them. - Errors surface as
ok: bool+error: str | Noneon result dataclasses, not exceptions, for anything that can fail for an expected reason (tool missing, permission denied, switch off). Reserve exceptions for genuine bugs.
Build order (see TASKS.md for the checklist)
Build in this order — each step is independently testable before the next depends on it:
watch.py(daemon) — testable via CLI alone before MCP exists.__main__.py(CLI) — wire upon/off/status/capture/watch/watch-stop/displaysagainstcore.pyandwatch.py.- Manually verify end-to-end on whatever OS you're running in (screenshot appears, blocklist works, watch daemon writes status file,
offcleans up). tools/sub-package — one module per domain (control.py,screen.py,audio.py,watch.py), each exporting aregister(mcp)function.mcp_server.pyis a thin orchestrator that callsregister_all(mcp). If you're duplicating logic between CLI and MCP server, stop and extract it intocore.pyorwatch.pyinstead.install.sh/install.ps1.skills/claude-code/SKILL.mdadapter.README.md.tests/.
Definition of done for v1
pip install .works from a clean venv.screensight on && screensight captureproduces a valid downscaled JPEG at~/.screensight/frame.jpgon macOS, Linux, and Windows/WSL (test whichever you have access to; note untested platforms in the PR description).screensight watch --interval 3runs as a background process, updatesdaemon.jsonon change, stops itself afterMAX_FRAMES_PER_WATCHframes or onscreensight watch-stop, and turns the master switch off when it exits.screensight-mcpstarts and lists all 9 tools when queried via any MCP client (fastmcp devor an actual agent).- Renaming the active window to something in the blocklist (e.g. a terminal titled "1Password") causes
captureto refuse and report why. screensight offdeletesframe.jpgif present.
FastMCP Official Documentation
Reference: FastMCP llms.txt — the fast, Pythonic way to build MCP servers and clients.
Core Server Concepts
- The FastMCP Server: The core FastMCP server class for building MCP applications
- Tools: Expose functions as executable capabilities for your MCP client
- Resources & Templates: Expose data sources and dynamic content generators to your MCP client
- Prompts: Create reusable, parameterized prompt templates for MCP clients
- MCP Context: Access MCP capabilities like logging, progress, and resources within your MCP objects
Server Features
- Authentication: Secure your FastMCP server with flexible authentication patterns
- Middleware: Add cross-cutting functionality with middleware that intercepts and modifies requests and responses
- Lifespans: Server-level setup and teardown with composable lifespans
- Session State: Persist state across requests on stateless connections
- Sampling: Generate text from a FastMCP server — by calling an LLM directly, or by asking the client to sample
- Progress Reporting: Update clients on the progress of long-running operations
- Client Logging: Send log messages back to MCP clients through the context
- Testing your FastMCP Server: How to test your FastMCP server
Transforms & Providers
- Transforms Overview: Modify components as they flow through your server
- Tool Transformation: Modify tool schemas - rename, reshape arguments, and customize behavior
- Providers: How FastMCP sources tools, resources, and prompts
- MCP Proxy Provider: Source components from other MCP servers
CLI & Deployment
- CLI: The fastmcp command-line interface
- Running Servers: Start, develop, and configure servers from the command line
- HTTP Deployment: Deploy your FastMCP server over HTTP for remote access
- Project Configuration: Use fastmcp.json for portable, declarative project configuration
Client
- The FastMCP Client: Programmatic client for interacting with MCP servers
- Calling Tools: Execute server-side tools and handle structured results
- Client Transports: Configure how clients connect to and communicate with MCP servers
Installation & Upgrading
- Installation: Install FastMCP and verify your setup
- Quickstart
- Upgrading from FastMCP 2: What changed in FastMCP 3
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

