Lightweight local-first monitoring for Linux, Windows, and macOS — history, trends, alerts, web UI and MCP without a central monitoring stack.
Drift inferred · capture-to-capture
No drift recorded — single capability capture; advisories appear once its surface changes.
transport stdio · http counts 0 tools · 0 res
· 0 prompts
permission surface via code analysis
No tools enumerated yet for this server.
prompt-surface
shipped agent-instruction files + hidden-content / dangerous-code findings —
quoted from the analyzed source
analyzed commit 1bf5ca8 · analyzer v33 · 2d ago
skills & prompt files 3
danger signals1
- dynamic code execution __import__() dannysheehan-ftmon-1bf5ca8/tests/unit/test_definitions.py :769
assert "response_time_s" not in __import__(
evidence-backed
findings quoted directly from the published source artifact — not inferred
code files: 191
filesystem 83
- fs (weak) dannysheehan-ftmon-1bf5ca8/extra-monitors/battery/tests/test_check_battery.py :9
from pathlib import Path - fs (weak) dannysheehan-ftmon-1bf5ca8/extra-monitors/package-updates/tests/test_check_apt_updates.py :9
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/spikes/macos-support/log_stream_spike.py :12
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/spikes/macos-support/notification_spike.py :8
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/spikes/macos-support/reload_target.py :10
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/spikes/windows-support/evtlog_spike.py :95
print("subscription 1 open (EvtSubscribeToFutureEvents), writing marker A ...") - fs dannysheehan-ftmon-1bf5ca8/spikes/windows-support/toast_spike.py :30
print("finding: it fails open (no exception) rather than failing loud.") - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/checks/registry.py :10
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/checks/runner.py :7
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/checks/trust.py :26
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/cli.py :17
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/config.py :21
from pathlib import Path
show 28 more
- fs dannysheehan-ftmon-1bf5ca8/src/ftmon/daemon.py :23
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/definitions/loader.py :24
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/definitions/manage.py :20
from pathlib import Path - fs (weak) dannysheehan-ftmon-1bf5ca8/src/ftmon/demo.py :17
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/engine/events.py :445
daemon restart cannot re-open (and re-notify) a live episode. The - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/mcp_server.py :26
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/notify/desktop.py :18
import shutil - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/notify/file.py :12
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/notify/http.py :45
with transport.open(request, timeout=TIMEOUT_SECONDS) as response: - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/notify/osascript.py :9
import shutil - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/paths.py :24
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/recipes/catalogue.py :12
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/recipes/install.py :16
from pathlib import Path - fs (weak) dannysheehan-ftmon-1bf5ca8/src/ftmon/sources/fixtures.py :30
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/sources/system.py :112
with open(path) as f: - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/store/db.py :9
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/store/doctor.py :8
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/store/query.py :1148
if the incident wasn't open (already acked/cleared/unknown).""" - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/web/app.py :13
from pathlib import Path - fs dannysheehan-ftmon-1bf5ca8/src/ftmon/web/demo_app.py :10
from pathlib import Path - fs (weak) dannysheehan-ftmon-1bf5ca8/tests/ai_skills/test_shared_skills.py :6
from pathlib import Path - fs (weak) dannysheehan-ftmon-1bf5ca8/tests/e2e/harness.py :20
import shutil - fs (weak) dannysheehan-ftmon-1bf5ca8/tests/e2e/test_daemon_e2e.py :12
from pathlib import Path - fs (weak) dannysheehan-ftmon-1bf5ca8/tests/e2e/test_recipe_install_e2e.py :8
from pathlib import Path - fs (weak) dannysheehan-ftmon-1bf5ca8/tests/e2e_real/test_real_system.py :13
import shutil - fs (weak) dannysheehan-ftmon-1bf5ca8/tests/e2e_real/test_server_deployment.py :11
import shutil - fs (weak) dannysheehan-ftmon-1bf5ca8/tests/exchange/test_exchange.py :7
import shutil - fs (weak) dannysheehan-ftmon-1bf5ca8/tests/extra_monitors/test_recipes.py :6
from pathlib import Path, PurePosixPath, PureWindowsPath
43 more not shown — this panel samples each group; the count above is the real total.
shell / exec 30
- shell (weak) dannysheehan-ftmon-1bf5ca8/extra-monitors/battery/tests/test_check_battery.py :7
import subprocess - shell (weak) dannysheehan-ftmon-1bf5ca8/extra-monitors/package-updates/tests/test_check_apt_updates.py :7
import subprocess - shell dannysheehan-ftmon-1bf5ca8/spikes/macos-support/log_stream_spike.py :8
import subprocess - shell dannysheehan-ftmon-1bf5ca8/spikes/macos-support/notification_spike.py :7
import subprocess - shell dannysheehan-ftmon-1bf5ca8/spikes/windows-support/reload_signal_spike.py :18
import subprocess - shell dannysheehan-ftmon-1bf5ca8/spikes/windows-support/task_scheduler_spike.py :10
import subprocess - shell dannysheehan-ftmon-1bf5ca8/src/ftmon/checks/runner.py :5
import subprocess - shell dannysheehan-ftmon-1bf5ca8/src/ftmon/engine/actions.py :13
import subprocess - shell dannysheehan-ftmon-1bf5ca8/src/ftmon/notify/desktop.py :19
import subprocess - shell dannysheehan-ftmon-1bf5ca8/src/ftmon/notify/osascript.py :10
import subprocess - shell dannysheehan-ftmon-1bf5ca8/src/ftmon/paths.py :20
import subprocess - shell dannysheehan-ftmon-1bf5ca8/src/ftmon/sources/journald.py :21
import subprocess
show 18 more
- shell dannysheehan-ftmon-1bf5ca8/src/ftmon/sources/oslog.py :13
import subprocess - shell dannysheehan-ftmon-1bf5ca8/src/ftmon/sources/unit.py :34
import subprocess - shell (weak) dannysheehan-ftmon-1bf5ca8/tests/e2e/harness.py :23
import subprocess - shell (weak) dannysheehan-ftmon-1bf5ca8/tests/e2e/test_daemon_e2e.py :10
import subprocess - shell (weak) dannysheehan-ftmon-1bf5ca8/tests/e2e/test_demo_builder.py :7
import subprocess - shell (weak) dannysheehan-ftmon-1bf5ca8/tests/e2e_real/test_real_system.py :15
import subprocess - shell (weak) dannysheehan-ftmon-1bf5ca8/tests/e2e_real/test_server_deployment.py :12
import subprocess - shell (weak) dannysheehan-ftmon-1bf5ca8/tests/unit/test_core.py :5
import subprocess - shell (weak) dannysheehan-ftmon-1bf5ca8/tests/unit/test_external_checks.py :6
import subprocess - shell (weak) dannysheehan-ftmon-1bf5ca8/tests/unit/test_notify_osascript.py :5
import subprocess - shell (weak) dannysheehan-ftmon-1bf5ca8/tests/unit/test_paths_windows.py :6
import subprocess - shell (weak) dannysheehan-ftmon-1bf5ca8/tests/unit/test_windows_tasks.py :13
import subprocess - shell dannysheehan-ftmon-1bf5ca8/tools/windows/build_windows.py :19
import subprocess - shell dannysheehan-ftmon-1bf5ca8/tools/windows/check_version_agreement.py :8
import subprocess - shell (weak) dannysheehan-ftmon-1bf5ca8/tools/windows/msi_lifecycle_test.py :22
import subprocess - shell dannysheehan-ftmon-1bf5ca8/tools/windows/record_native_checklist.py :31
import subprocess - shell dannysheehan-ftmon-1bf5ca8/tools/windows/sign_windows.py :24
import subprocess - shell dannysheehan-ftmon-1bf5ca8/tools/windows/smoke_installed.py :13
import subprocess
network 15
- net dannysheehan-ftmon-1bf5ca8/src/ftmon/clock.py :17
import socket - net dannysheehan-ftmon-1bf5ca8/src/ftmon/config.py :22
from urllib.parse import urlsplit - net dannysheehan-ftmon-1bf5ca8/src/ftmon/notify/http.py :5
import urllib.error - net dannysheehan-ftmon-1bf5ca8/src/ftmon/notify/ntfy.py :5
import urllib.request - net dannysheehan-ftmon-1bf5ca8/src/ftmon/notify/webhook.py :6
import urllib.request - net dannysheehan-ftmon-1bf5ca8/src/ftmon/paths.py :18
import socket - net dannysheehan-ftmon-1bf5ca8/src/ftmon/sources/system.py :10
import socket - net dannysheehan-ftmon-1bf5ca8/src/ftmon/web/app.py :14
from urllib.parse import parse_qs, urlencode - net (weak) dannysheehan-ftmon-1bf5ca8/tests/e2e/harness.py :22
import socket - net (weak) dannysheehan-ftmon-1bf5ca8/tests/e2e_real/test_real_system.py :18
import urllib.request - net (weak) dannysheehan-ftmon-1bf5ca8/tests/exchange/test_exchange.py :10
from urllib.parse import urlsplit - net (weak) dannysheehan-ftmon-1bf5ca8/tests/unit/test_core.py :4
import socket
show 3 more
- net (weak) dannysheehan-ftmon-1bf5ca8/tests/unit/test_notify_remote.py :8
import urllib.error - net dannysheehan-ftmon-1bf5ca8/tools/build_exchange.py :20
from urllib.parse import urlparse - net dannysheehan-ftmon-1bf5ca8/tools/windows/smoke_installed.py :12
import socket
database 22
- db dannysheehan-ftmon-1bf5ca8/src/ftmon/daemon.py :19
import sqlite3 - db (weak) dannysheehan-ftmon-1bf5ca8/src/ftmon/demo.py :14
import sqlite3 - db dannysheehan-ftmon-1bf5ca8/src/ftmon/store/db.py :8
import sqlite3 - db dannysheehan-ftmon-1bf5ca8/src/ftmon/store/doctor.py :7
import sqlite3 - db dannysheehan-ftmon-1bf5ca8/src/ftmon/store/outbox.py :12
import sqlite3 - db dannysheehan-ftmon-1bf5ca8/src/ftmon/store/query.py :11
import sqlite3 - db dannysheehan-ftmon-1bf5ca8/src/ftmon/store/retention.py :23
import sqlite3 - db dannysheehan-ftmon-1bf5ca8/src/ftmon/store/writer.py :16
import sqlite3 - db dannysheehan-ftmon-1bf5ca8/src/ftmon/web/app.py :8
import sqlite3 - db dannysheehan-ftmon-1bf5ca8/src/ftmon/web/demo_app.py :8
import sqlite3 - db (weak) dannysheehan-ftmon-1bf5ca8/tests/e2e/test_daemon_e2e.py :9
import sqlite3 - db (weak) dannysheehan-ftmon-1bf5ca8/tests/e2e/test_demo_builder.py :6
import sqlite3
show 10 more
- db (weak) dannysheehan-ftmon-1bf5ca8/tests/e2e/test_recipe_install_e2e.py :6
import sqlite3 - db (weak) dannysheehan-ftmon-1bf5ca8/tests/e2e_real/test_real_system.py :14
import sqlite3 - db (weak) dannysheehan-ftmon-1bf5ca8/tests/unit/test_demo.py :6
import sqlite3 - db (weak) dannysheehan-ftmon-1bf5ca8/tests/unit/test_doctor.py :4
import sqlite3 - db (weak) dannysheehan-ftmon-1bf5ca8/tests/unit/test_engine.py :699
import sqlite3 - db (weak) dannysheehan-ftmon-1bf5ca8/tests/unit/test_external_integration.py :5
import sqlite3 - db (weak) dannysheehan-ftmon-1bf5ca8/tests/unit/test_notification_dispatch.py :4
import sqlite3 - db (weak) dannysheehan-ftmon-1bf5ca8/tests/unit/test_store.py :7
import sqlite3 - db dannysheehan-ftmon-1bf5ca8/tools/check_retention_recovery.py :26
import sqlite3 - db dannysheehan-ftmon-1bf5ca8/tools/soak_report.py :38
import sqlite3
declared dependencies 9
- mcp@>=2,<3
- psutil@>=6
- platformdirs@>=4
- starlette@>=0.40
- uvicorn@>=0.30
- jinja2@>=3.1
- tomli-w@>=1
- pywin32@>=312; sys_platform ==
- win32@*