SassyMCP

io.github.sassyconsultingllcPublished by GitHub account sassyconsultingllcv1.18.0Updated Nov 4, 2026

One MCP server that replaces 75+ — 278 tools in a single exe, smart-loaded.

Overview

AI-generated overview

A single local MCP server bundling 278 tools across 18 groups — files, shell, GitHub, desktop and phone control — with smart loading and a permission engine.

What you can do
  • Read, write, copy, move, archive and safely delete files and directories, with overwrites staged for recovery
  • Run and interact with persistent shell sessions, list and set environment variables, and inspect configuration
  • Work with GitHub: list and create issues, open pull requests, apply branch protection, check releases and changelogs
  • Control the desktop: take screenshots, click, OCR the screen, and drive Android devices
  • Manage its own safety and operations: permission modes, tool profiles, audit logs, health checks, license and setup wizards
When to use it
Useful when you want one server instead of stacking separate filesystem, terminal, GitHub and device-control servers, and you are comfortable giving an assistant broad local machine access under a policy engine you configure.
Requirements
Runs as a local process on the user's machine (stdio); a standalone executable or a PyPI package needing Python 3.11+ when run from source. Optional integrations need credentials: GITHUB_TOKEN for GitHub tools, SSH_HOST, SSH_USER and SSH_PASS for remote Linux, and SASSYMCP_AUTH_TOKEN for non-loopback HTTP. Some tools need external binaries such as adb, nmap, plink, scrcpy, tesseract or Chrome on PATH.
Before you install
This is a high-privilege server: it writes and overwrites files, runs shell commands, clicks on the real desktop, and can control phones. Defaults are gated by a permission engine, but a bypass mode allows nearly everything except protected paths. It stores state, audit logs, tokens and optional SSH and GitHub credentials under its home directory, and can patch other MCP clients' config files on install. Review the mode and allowed directories before use.

Installation

In SourceWeft

  1. Open SassyMCP 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

SassyMCP

One MCP server to replace them all.

278 tools | 39 modules | 18 tool groups | Replaces 75+ MCP servers | ~35MB standalone exe

Last updated: 2026-09-21 — v1.16.0 | all tools unlocked; optional supporter license

Compatible with Claude Desktop, Grok Desktop, Cursor, Windsurf, and any MCP client.

The official GitHub MCP server has critical SHA-handling bugs. SassyMCP's GitHub module uses correct blob SHA lookups, proper path encoding, atomic multi-file commits via Git Data API, retry logic with exponential backoff, and rate-limit awareness. It's a drop-in replacement that actually works.

Why SassyMCP?

The MCP ecosystem is fragmented. Need file operations? Install Filesystem server. Need terminal? Desktop Commander. GitHub? Another server. Android? Another. Screenshots? Another. You end up with 6-10 separate MCP servers, each consuming context window, each with its own config, bugs, and update cycle.

SassyMCP replaces 75+ individual MCP servers — including Desktop Commander (5.9k stars), Windows-MCP (5k stars), GitHub MCP Server (28.6k stars), Anthropic's official Filesystem and Memory servers, mobile-mcp (4.4k stars), and dozens more — with a single ~35MB exe.

Key differentiators:

  • Smart Tool Loading — Only loads tool groups you use. Reduces context window overhead from ~25K tokens to ~5K tokens by default.
  • Dynamic Vision — Real-time screen monitoring with change detection for both desktop and Android. No more screenshot-and-pray.
  • Android Interaction — Full phone control via UI accessibility tree: tap, swipe, type, with automatic sensitive context detection (auth/payment screens auto-block).
  • Pause/Resume — User takes over the phone for manual steps (login, 2FA, account selection), AI watches and learns, then resumes autonomously.
  • Usage Tracking — ML-lite scoring of tool invocations with exponential decay. Your most-used tools load first.
  • Context Estimation — Built-in tool to measure how much of your 200K context window tool definitions consume.
  • Response Minification — GitHub API responses stripped of URL metadata bloat (40-70% smaller).
  • Safe Delete — Delete commands (rm, del, Remove-Item, etc.) are intercepted across all shells. Instead of destroying files, targets are moved to a _DELETE_/ staging folder in the same directory for human review — protecting against AI hallucinations.
  • Guided Setup — Wizard walks through persona, GitHub token, SSH credentials, and optional tool discovery.

What It Replaces

DomainSassyMCP ModuleReplacesTop Alternative
File operationsFileOps, Editor11 filesystem/editor MCP serversFilesystem (Anthropic official)
Shell / terminalShell, Session5 shell MCP serversDesktop Commander (5.9k stars)
Desktop automationUIAutomation, Vision9 desktop MCP serversWindows-MCP (5k stars)
GitHub / GitGitHub Quick, GitHub Full5 GitHub/Git MCP serversGitHub MCP Server (28.6k stars)
Android / phoneADB, PhoneScreen9 mobile MCP serversmobile-mcp (4.4k stars)
Network scanningNetworkAudit8 nmap/security MCP serversmcp-for-security (601 stars)
Security auditingSecurityAudit8 security MCP serversmcp-security-hub (509 stars)
SSH / remote LinuxLinux7 SSH MCP serversssh-mcp (365 stars)
Memory / stateMemory, StateManager7 memory MCP serversmcp-memory-service (1.6k stars)
OCR / screen readingVision7 OCR/vision MCP serversPaddleOCR MCP
Web inspectionWebInspector, Utility7 web/fetch MCP serversFetch (Anthropic official)
Windows systemRegistry, ProcessManager, Clipboard, EventLog, Bluetooth13 Windows MCP serversWindows-MCP (5k stars)

Plus features with no MCP server equivalent: phone pause/resume with sensitive context detection (auto-blocks on login/payment screens), operational hooks (14 expert playbooks), safe delete interception, Windows autorun forensics, Android+Windows clipboard sync, usage-weighted smart loading.

Licensing

Every tool group ships unlocked, for everyone, with no key required. As of v1.13.0 the release model is all-or-nothing — there is no free/pro split, no gated groups, no crippled demo. The 278 tools you see in the module table below are the product, out of the box.

Supporter licenses (optional): SassyMCP can still be purchased through LemonSqueezy as a one-time supporter license (no subscriptions). Activating a key registers your machine as a seat and records a supporter tier that shows in the startup banner, control panel, and VS Code cockpit — all tools are unlocked regardless of tier. Buy once to support development; refunds revoke the label automatically.

Activation flow (supporters):

  1. Purchase at https://sassyconsultingllc.com/store — LemonSqueezy emails you a key (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX).
  2. Activate from your AI agent: sassy_setup_license action=activate key=...
  3. Or from a terminal: sassymcp.exe setup opens the interactive menu.

Offline operation: Once activated, a local HMAC-signed payload lets the supporter tier validate fully offline. A weekly re-check against LS catches refunds and cancellations; a faster startup check against the SassyMCP billing oracle cuts refund-to-revocation latency to seconds. Missing, expired, tampered, or corrupt license files just show the free label — tool availability is never affected.

Back-compat: SASSYMCP_LICENSE_BYPASS=1 (the old dev escape hatch that unlocked gated groups) is accepted and ignored — there is nothing left to bypass.

Running supervised (sassymcp supervise)

For always-on / remote deployments, run SassyMCP under its built-in supervisor instead of bare launcher scripts:

sassymcp.exe supervise start              # bridge only (127.0.0.1:21001)sassymcp.exe supervise start --tunnel-mode managed   # also run the cloudflared tunnel as a childsassymcp.exe supervise status             # JSON status; exit code != 0 if unhealthysassymcp.exe supervise stop               # graceful stop

The supervisor owns the runtime tree and makes it self-healing and orphan-proof:

  • No orphans, ever. A hard kill of the supervisor (crash, kill -9, taskkill /f) takes every child with it — on Windows via a Job Object (KILL_ON_JOB_CLOSE), on Linux via process groups + PR_SET_PDEATHSIG. No leftover bridge holding a wedged SQLite/WAL lock, which is what the old taskkill-based scripts caused.
  • Self-healing. Crashed children restart with exponential backoff (and give up cleanly after a crash-loop, rather than spinning).
  • Catches hangs. An HTTP readiness probe recycles a hung-but-alive bridge — the failure a Windows scheduled task can never detect.
  • Crash-survivable control. A pidfile + on-disk registry under $SASSYMCP_HOME mean supervise status/stop work even when the bridge is down, so an operator or agent can recover a wedged system.

start-supervised.bat wraps this as the recommended Windows launcher. stdio mode (Claude Desktop pipe) is client-owned and intentionally not supervised.

Modules

ModuleToolsGroupDescription
Meta11metaContext estimation, tool usage analytics, group management
Batch1metaMulti-tool batch fan-out in a single call
FileOps10coreRead, write, search, move, copy, edit, mkdir, file info, safe delete
Shell2corePowerShell, CMD, WSL execution with syntax normalization and delete interception
UIAutomation6coreDesktop state, click, type, hotkeys, screenshots, screen info
Editor2coreSurgical find/replace, multi-edit
Audit4coreAudit log read, search, clear, false-positive tracking
Session6corePersistent terminal sessions (start, read, send, stop)
GitHub Quick6github_quickDaily-driver: push_files, get_file, issue, PR, protect
GitHub Full80github_fullComplete GitHub API: repos, issues, PRs, actions, security, gists
Persona7personaExpert-mode directives, decision framework, engineering standards
Utility11utilityEnv vars, toast, zip/tar/unzip/untar, HTTP requests, file diff
SetupWizard7setupSetup wizard, GitHub token guide, SSH setup, tool checker, license activation
ToolsManager1setupExternal tool bootstrap and detection
Observability3infrastructureHealth, metrics, tool stats
StateManager3infrastructurePersistent key-value state across sessions
RuntimeConfig5infrastructurePermission modes, runtime config, recent tool calls
Offline3infrastructureOffline fallback status and local-model handoff
Memory9memoryPersistent cross-session memory, milestones, task handoffs, pattern learning
Updater4updaterVersion checks, changelog, self-update
ADB10androidAndroid shell, packages, file transfer, logcat, screencap
PhoneScreen14androidUI tree reader, phone glance/watch, tap/swipe/type/key, pause/resume, scrcpy
iPhone6iphoneiOS device info, screenshot, syslog, apps, IPA install — experimental, needs libimobiledevice
NetworkAudit7systemnetstat, ARP, WiFi scan, port scan, DNS, traceroute
ProcessManager5systemCross-platform process list/kill, system info
Bluetooth3systemWindows + Android BT enumeration
EventLog3systemWindows Event Log + Android logcat
Clipboard4systemCross-platform clipboard sync
SecurityAudit7forensicsHash, permissions, certs, APK, firewall, Defender
Registry4forensicsRead, write, export, autorun forensics (Windows)
Vision8v020Screen capture, OCR, dynamic glance/watch/diff
AppLauncher6v020Launch apps, focus/close/resize/snap windows
WebInspector5v020Security headers, URL screenshots, tech stack detection
Crosslink7v020Cross-session messaging via HTTP API + SQLite
Coordination4v020Multi-agent coordination board and peer delegation
Linux1linuxRemote SSH execution via plink/OpenSSH
Combos3combosMulti-step workflows in one call: PR review, phone observe, codebase grep
Prompts0promptsMCP slash-menu shortcuts (no tools — prompts only)
SelfMod0—Retired stub — self-modification removed (no tools)

Counts generated from the registered tool set (278 tools across 39 modules, 18 groups; the prompts group exposes MCP prompts rather than tools).

Full per-tool reference (generated): docs/TOOLS.md.

iPhone support (experimental)

SassyMCP can talk to iPhones over USB via libimobiledevice. This is new in v1.16.0 and experimental — Android-over-ADB remains the mature path.

Prerequisites

  • Install libimobiledevice: brew install libimobiledevice (macOS) or sudo apt install libimobiledevice-utils (Linux). Windows hosts have limited support — use WSL2 or a macOS/Linux host.
  • Pair the device once: run idevicepair pair and tap Trust on the iPhone. iOS 17+ requires this pairing step before any tool will see the device.
  • If several iPhones are connected, pass the udid parameter (from sassy_iphone_list) to target one.

Tools: sassy_iphone_list, sassy_iphone_info, sassy_iphone_screenshot, sassy_iphone_syslog (bounded capture), sassy_iphone_apps, sassy_iphone_install (requires confirm='YES'). Every tool degrades gracefully when the binaries or a trusted device are missing — you'll get an install hint or a pairing reminder, never a traceback.

Dynamic Vision

Desktop (Vision module)

Traditional MCP screenshots are blind — you capture one frame and hope it's the right one. SassyMCP's dynamic vision changes this:

ToolPurpose
sassy_screen_glanceFast grayscale capture at ~3-6KB. Call repeatedly to "watch" the screen.
sassy_screen_watchMonitor for N seconds, returns only frames where content changed (pixel diff threshold).
sassy_screen_diffBefore/after comparison — takes frame, waits, takes another, returns both + a diff image highlighting changes.

All three use grayscale + heavy JPEG compression to keep context cost minimal. A glance is ~2KB vs ~14KB for a full-color capture.

Android (PhoneScreen module)

The phone isn't just a camera target — SassyMCP reads its UI accessibility tree:

ToolPurpose
sassy_phone_uiReads every visible UI element — text, description, coordinates, clickable/focused/checked state. Structured data, not pixels.
sassy_phone_stateForeground app, screen on/off, battery, WiFi, notification count.
sassy_phone_glanceLow-res grayscale phone screenshot via direct pipe (~4-8KB).
sassy_phone_watchMonitors UI tree changes over duration. Returns snapshots only when elements change.

Phone Interaction

Full touch input via ADB — the AI can operate the phone:

ToolPurpose
sassy_phone_tapTap screen coordinates
sassy_phone_swipeSwipe between two points
sassy_phone_typeType text into focused field
sassy_phone_keySend key events (HOME, BACK, ENTER, VOLUME, etc.)
sassy_phone_openLaunch an app by package name

Sensitive Context Detection

All interaction tools (tap, swipe, type) automatically scan the UI tree before executing. If they detect login screens, payment forms, account selectors, 2FA prompts, or permission dialogs, the tool refuses to execute and returns what it sees instead. The AI then describes the screen to you and asks what to do. Pass confirmed=True after explicit user approval.

Safe Delete (Delete Interception)

AI agents can hallucinate destructive commands. SassyMCP intercepts all delete-family commands across every shell and every tool entry point, then moves targets to a _DELETE_/ staging folder instead of destroying them. Every interception is written to the audit log with the raw command, parsed targets, and move results.

Coverage — every destructive path is gated:

ToolGuard
sassy_shellIntercepts delete commands, stages targets to _DELETE_/
sassy_session_send / sassy_session_startSame interceptor — persistent terminals can't bypass
sassy_linux_execRefuses destructive commands on the remote host
sassy_adb_shellRefuses destructive commands on Android device (override with allow_destructive=True)
sassy_safe_deleteExplicit staging tool — moves symlinks as symlinks (no resolve() in the move path)
sassy_write_file (rewrite mode)Snapshots existing file into _DELETE_/ before overwriting
sassy_edit_block / sassy_edit_multiRefuses protected paths, snapshots existing content to _DELETE_/<name>.pre-edit.<ts><ext> before applying
sassy_copyRefuses existing destination (no silent overwrite), refuses protected src/dst
sassy_moveRefuses silent destination overwrite, refuses protected src/dst
sassy_audit_clearRotates the audit log instead of deleting it; requires confirm='YES'

Intercepted command keywords: rm, rmdir, unlink (Unix/WSL), del, erase, rd (CMD), Remove-Item, ri, rni (PowerShell aliases), sdelete / sdelete64 (Sysinternals).

Also caught (beyond bare keywords):

  • Shell wrappers — powershell -c "del foo", cmd /c del foo, bash -c "rm foo", wsl -- rm foo (payload is recursively scanned)
  • Base64 payloads — powershell -EncodedCommand <base64> is decoded (UTF-16-LE) and recursively scanned
  • .NET calls — [System.IO.File]::Delete(...), [System.IO.Directory]::Delete(...)
  • Clear-Content, Set-Content -Value '' (literal empty only — normal -Value "foo" is allowed)
  • Out-File -Force, New-Item -Force (overwrite-style)
  • copy /y, xcopy /y — CMD silent-overwrite flags
  • robocopy /MIR and robocopy /PURGE — mirror/purge modes delete destination files
  • Truncate-by-redirect — > file.txt, type foo > bar.txt, cmd; > file.txt (append >> and stream 2> / &> correctly ignored)
  • Move-Item foo $null
  • Assignment prefixes — $null = ri foo is correctly unwrapped

Protected roots (refused by every guarded tool, not just the interceptor): the SassyMCP source tree itself, ~/.sassymcp/ (audit + config), and any _DELETE_/ staging folder (no staging recursion). Protection uses resolve() so path traversal (..\), symlinks, and Windows 8.3 short names all normalize correctly before the check.

ScenarioResult
rm -rf /Hard-blocked by the always-on blocklist — no move attempted
rm important.txtBlocked, file moved to ./_DELETE_/important.txt
del /q *.logBlocked, all .log files moved to ./_DELETE_/
Remove-Item -Path C:\data\oldBlocked, old moved to C:\data\_DELETE_\old
cmd /c del foo (wrapper)Blocked — payload is unwrapped and intercepted
gci *.tmp | ri (PS alias)Blocked — ri alias is matched
sassy_write_file("doc.txt", ..., "rewrite") on existing filePrior content snapshotted to _DELETE_/doc.overwrite.<ts>.txt first
ls -laExecutes normally — not a delete command

Name collisions in _DELETE_/ are handled automatically with counter suffixes (file.txt, file_1.txt, file_2.txt). On Windows, paths with backslashes (C:\Users\foo\bar) are preserved correctly by the parser — no shlex mangling.

Pause / Resume

For complex flows where the user needs to take over:

ToolPurpose
sassy_phone_pauseBlocks all interaction tools. Observation tools (ui, glance, watch) still work.
sassy_phone_resumeUnblocks interaction. AI picks up where it left off, informed by everything it observed during pause.

Workflow:

  1. AI operates phone autonomously for routine tasks
  2. AI hits a login screen → sensitive context auto-blocks → AI tells the user
  3. User says "hold on" → AI calls sassy_phone_pause
  4. User logs in manually. AI watches via sassy_phone_ui / sassy_phone_glance
  5. User says "done" → AI calls sassy_phone_resume
  6. AI continues, now aware the user logged into a specific account

Permission Engine & Control Panel

SassyMCP gates the shell and file tools through one policy engine (sassymcp.policy) with four modes, set via sassy_permission set_mode or the Control Panel:

ModeBehavior
strictBlock destructive patterns everywhere (default)
confirmDestructive patterns return a confirm token
sandboxRelaxed gating inside the project roots; anything resolving outside the jail is refused — run an ungated model, confined to a folder
bypassAllow everything except protected paths (explicit, audited)

A Claude-style allow / ask / deny rules layer (tool-glob + path-glob + command-regex; first match wins) overrides the mode default. The catastrophic block-list (format, mkfs, …) and the protected-path invariant (the SassyMCP source tree + ~/.sassymcp) hold in every mode, including bypass.

The Control Panel is a localhost web UI for all of the above — a live event log, the settings/mode editor, and a classifier + rules editor. It binds 127.0.0.1 only and needs the per-install token in ~/.sassymcp/control_panel.token. Start it with sassy_panel start (or set panel.enabled / SASSYMCP_PANEL=1 to launch it at boot), then open the printed http://127.0.0.1:8765/?token=… URL.

Tool profiles

Tool profiles gate which tools an MCP session can see (tools/list) and call (tools/call) — a per-session, human-controlled subset of the catalog, managed from the Control Panel (a Profiles tab, backed by GET/POST /api/profile). There is deliberately no MCP tool that can switch or widen the profile, so a session can never escalate itself out of a restrictive profile; fan-out through sassy_batch respects the same gate.

ProfileTool groups
fullAll 18 groups (default on every start)
developermeta, core, infrastructure, utility, github_quick, github_full, v020, memory, persona, setup, updater
forensicsmeta, core, infrastructure, forensics, utility, system, memory
devicesmeta, core, infrastructure, android, iphone, utility, memory
sysadminmeta, core, infrastructure, system, linux, utility, memory, updater
readonlyEvery tool whose curated MCP annotation is readOnlyHint=true — computed per-tool, not from groups
customAn explicit group set you tick in the dashboard

Rules worth knowing:

  • Session-scoped, never persisted. A restart always comes back up on full. Profiles are a runtime seatbelt, not access control — the panel token is the trust boundary.
  • meta stays on. Its introspection tools (sassy_tool_groups, sassy_self_check, …) are the session's only window into what it can see; hiding them would strand the session with no way to inspect the gate.
  • Widening needs confirm='YES'. Any switch that would expose a currently-hidden tool is an audited escalation and requires explicit confirmation (the panel UI sends it for you, mirroring the bypass-mode convention). Narrowing never does.
  • A tool hidden from tools/list is also uncallable via tools/call — a client cannot call what it cannot see.

Guided Setup

On first launch (no ~/.sassymcp/persona.md), the wizard tools are prominently available and the AI is given an onboarding playbook via the registered hook. The flow is conversational — the AI asks, you answer, it calls the tools.

Onboarding procedure (recommended order)

Each step is independent and skippable. Just tell the AI "set up SassyMCP" or "let's get started" and it'll walk this:

#StepToolWhat happens
0License (optional)sassy_setup_license action="status" then action="activate" key=...Reports supporter tier. All tools are unlocked regardless — a key just registers your seat and supporter status.
1Personasassy_setup_wizardAsks the questionnaire below, generates ~/.sassymcp/persona.md, hot-reloads the persona module.
2GitHubsassy_setup_github action="check" → action="open_browser" → action="save_token" token=...Validates an existing GITHUB_TOKEN, or opens github.com/settings/tokens, walks you through scope selection, then saves and re-validates.
3SSH / Linuxsassy_setup_ssh action="check" → action="save" host=... user=... password=... → action="test"Locates plink, stores creds in process env, runs an echo round-trip to verify.
4Optional toolssassy_setup_check_toolsScans for nmap, tesseract, adb, scrcpy, plink, Chrome; reports install URLs for what's missing.
✓Status checksassy_setup_statusShows what's configured, what's still missing, and the action_required hint. Run this any time.
⚙️Auth tokenssassy_setup_generate_token client_id="claude-desktop"Generates a 32-byte URL-safe token for HTTP/tunnel mode and writes ~/.sassymcp/tokens.json.

Skip any step with action="skip" (where supported) — config records the skip so the AI doesn't re-prompt.

The persona questionnaire

sassy_setup_wizard accepts these fields. All optional — defaults shown.

FieldValues / formatDefault
roledeveloper | sysadmin | security | devops | data | designer | manager | otherdeveloper
expertise_leveljunior | mid | senior | principal | staffsenior
specializationsComma-separated areas — e.g. "web security, cloud infra, mobile"empty
languagesComma-separated — e.g. "Python, Rust, TypeScript, Go"empty
frameworksComma-separated — e.g. "React, FastAPI, Cloudflare Workers"empty
systemsNewline-separated hostname — OS — role entriesempty
projectsNewline-separated name — status — description entriesempty
communication_styleterse (code only) | balanced (brief explanations) | verbose (detailed rationale)terse
security_posturestandard (OWASP) | hardened (+ CSP/HSTS/rate-limit) | paranoid (+ air-gap, cert pinning, zero trust)standard
mcp_clientsWhich AI tools connect — e.g. "Claude Desktop, Cursor, Grok Desktop"empty
notesFree-form text — anything else the AI should know about how you workempty

Output goes to ~/.sassymcp/persona.md (the persona module reads it on every session) and the run is recorded in ~/.sassymcp/config.json (setup_complete, setup_timestamp, setup_version). Re-run sassy_setup_wizard any time to regenerate — the persona module hot-reloads with the new profile.

Triggering the flow from your client

The onboarding hook fires on phrases like "setup", "first time", "get started", "onboard", "new user", "set up sassymcp". Anything close to those will pull the playbook into the AI's context. If you want to drive it manually, just call sassy_setup_status first to see where you are, then walk the table above.

Smart Loading

By default, SassyMCP only loads frequently-used tool groups. This keeps tool definitions under 5% of your context window.

bash
# Default: loads core, github_quick, persona, meta, utility, setup, infrastructureuv run sassymcp
# Load everything (~22K tokens of context)SASSYMCP_LOAD_ALL=1 uv run sassymcp
# Load specific groupsSASSYMCP_GROUPS=core,github_quick,android,v020 uv run sassymcp

Available Groups

GroupModulesDefault
corefileops, shell, ui_automation, editor, audit, sessionYes
metametaYes
infrastructureobservability, state_manager, runtime_configYes
github_quickgithub_quick (6 lean tools)Yes
personapersonaYes
utilityutilityYes
setupsetup_wizard, tools_managerYes
memorymemoryYes
updaterupdaterYes
comboscombos (4 tools)No
promptsprompts (slash-menu shortcuts)Yes
github_fullgithub_ops (80 tools)No
androidadb, phone_screenNo
systemnetwork_audit, process_manager, security_audit, registry, bluetooth, eventlog, clipboardNo
v020vision, app_launcher, web_inspector, crosslinkNo
linuxlinuxNo

Install

Pick whichever entry point matches how you already work. All four converge on the same shared brain at ~/.sassymcp/ — your persona, memory, license, and audit log are visible to every connected MCP client.

One-click via DXT (Claude Desktop)

Download sassymcp.dxt from the latest release, double-click — Claude Desktop installs it. On first launch, sassymcp auto-detects every other MCP client on your machine (Cursor, VS Code Copilot, Windsurf, Continue, Cline, Zed, Grok Desktop) and patches each one's config so they all see SassyMCP without you editing any JSON.

VS Code extension

Install the VS Code extension from the .vsix attached to the latest release until the Visual Studio Marketplace listing is live. The extension locates sassymcp.exe (PATH or the sassymcp.exePath setting), runs the same auto-config CLI, and adds a status bar item showing supporter-tier label and brain health. Command palette: Open Sassy Brain Cockpit, Run Setup Wizard, Reinstall Client Configs, Open Audit Log, Open _DELETE_ Folder, Show Brain Status.

Manual auto-config CLI

If you have sassymcp.exe already (from the portable zip or pip install) and want to register it with every MCP client without per-client JSON editing:

sassymcp-install

That detects Claude Desktop, VS Code Copilot, Cursor, Windsurf, Continue, Cline, Zed, and Grok Desktop and patches each one's config atomically. Re-running is a noop. Take a look first with sassymcp-install --dry-run. Remove with sassymcp-install --uninstall. The CLI takes a timestamped backup of any existing config before its first edit.

Portable bundle

The portable zip (sassymcp-v*-portable.zip with bundled adb, nmap, plink, scrcpy, tesseract, cloudflared, and the start-*.bat launchers) is no longer published — the release pipeline does not build it. Use the standalone executable below (and install any helper tools you need on PATH), or pip install sassymcp for the full Python install.

Standalone executable (no tools bundled)

If you don't need the bundled nmap / adb / cloudflared (or you have them on PATH already), grab just sassymcp.exe (~35 MB) from the latest release. Drop it anywhere and point your MCP client at it.

First-run wizard: Double-click sassymcp.exe (or run it from a terminal with no flags) on a fresh machine and you'll get an interactive menu — auto-detect AI agents and register SassyMCP, activate a LemonSqueezy license key, generate / list bearer tokens, or start the HTTP server. Run sassymcp.exe setup anytime to re-open the menu. Once a persona is configured, bare invocation falls back to starting the HTTP server (the v1.5 behavior) so existing setups are unchanged.

Linux (pip only)

CI publishes no Linux binary. On Linux, install the wheel: pip install sassymcp. (The standalone executable is Windows-only; macOS ships a universal2 binary — see sassymcp-macos on the release page.)

MSI installer (manual builds only)

No MSI is published by CI — build-msi.ps1 exists for manual MSI builds (WiX 3.x) from a staged sassymcp.exe, and installer.wxs is a manual-build reference template, not a maintained installer.

Activating a supporter license (optional)

There is no separate "licensed download" and nothing to unlock — everyone runs the same fully-unlocked binary from the GitHub releases. If you want to support development, buy a license at sassyconsultingllc.com/store and activate it to register your seat and supporter tier:

powershell
# from your AI agent:sassy_setup_license action=activate key=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX# or from a terminal — interactive menu, choose "Activate license":sassymcp.exe setup

The license registers this machine as a LemonSqueezy instance (seat); sassy_setup_license action=deactivate frees the seat to move to another machine.

From source

bash
git clone https://github.com/sassyconsultingllc/SassyMCP.gitcd SassyMCPuv sync
# Optional dependencies:uv pip install pytesseract playwrightplaywright install chromium

Cloudflare Tunnel (remote access)

Want to drive SassyMCP from a remote MCP client (Claude Web, another machine)? The portable bundle ships a turnkey launcher. Full step-by-step is in docs/TUNNEL.md; the short version:

powershell
winget install Cloudflare.cloudflared          # one-timecloudflared tunnel login                       # authenticate against your CF accountcloudflared tunnel create sassymcp             # create a named tunnelcloudflared tunnel route dns sassymcp mcp.<your-domain>.tld# Write ~/.cloudflared/config.yml with the ingress block (see TUNNEL.md)
[Environment]::SetEnvironmentVariable("SASSYMCP_AUTH_TOKEN", "<your token>", "User")[Environment]::SetEnvironmentVariable(    "SASSYMCP_ALLOWED_HOSTS",    "mcp.<your-domain>.tld,localhost,127.0.0.1", "User")
cd D:\Tools\SassyMCP                           # wherever you extracted.\start-tunnel.bat sassymcp                    # tunnel name as arg, or set SASSYMCP_TUNNEL_NAME

start-tunnel.bat launches the HTTP bridge on 127.0.0.1:21001 and runs cloudflared tunnel run <name> in the foreground. Nothing in the script is vendor-specific — you supply the tunnel name and the hostname. Clients send Authorization: Bearer <SASSYMCP_AUTH_TOKEN> against https://mcp.<your-domain>.tld/mcp.

For hosted-Claude clients that require OAuth 2.1 DCR/PKCE instead of a static bearer, deploy the optional Worker under sassymcp-oauth/ — copy wrangler.toml.example to wrangler.toml, fill in your hostname and KV id, and wrangler deploy. See docs/TUNNEL.md for the full OAuth section.

MCP Client Config

SassyMCP speaks standard MCP. Anything that connects works — no client-side modifications required. The portable bundle ships ready-to-edit templates under deploy/*_config.template.json. Pick the row for your client, copy the template, replace REPLACE_WITH_PATH with the absolute path to sassymcp.exe, and save it where the client expects.

ClientTransportConfig file locationTemplate
Claude Desktopstdio%APPDATA%\Claude\claude_desktop_config.json (Win) / ~/Library/Application Support/Claude/claude_desktop_config.json (mac)claude_desktop_config.template.json
Cursorstdio~/.cursor/mcp.json (global) or <project>/.cursor/mcp.json (per-project)cursor_mcp_config.template.json
Windsurfstdio~/.codeium/windsurf/mcp_config.jsonwindsurf_mcp_config.template.json
Cline (VS Code)stdioVS Code settings → cline.mcpServers (same mcpServers shape)use claude_desktop_config.template.json
Continue.devstdio~/.continue/config.json (merge under experimental.modelContextProtocolServers)continue_mcp_config.template.json
Grok DesktopHTTPGrok Desktop MCP settingsgrok_desktop_config.template.json
Any other MCP clientstdio or HTTPclient's MCP configuse the closest template; the mcpServers shape is conventional

Standard mcpServers shape (Claude Desktop, Cursor, Windsurf, Cline)

Using the exe:

json
{  "mcpServers": {    "sassymcp": {      "command": "C:\\path\\to\\sassymcp.exe",      "env": {        "SASSYMCP_LOAD_ALL": "1",        "GITHUB_TOKEN": "ghp_your_token_here"      }    }  }}

From source:

json
{  "mcpServers": {    "sassymcp": {      "command": "uv",      "args": ["--directory", "C:\\path\\to\\SassyMCP", "run", "sassymcp"],      "env": {        "SASSYMCP_LOAD_ALL": "1",        "GITHUB_TOKEN": "ghp_your_token_here"      }    }  }}

Continue.dev shape (different schema)

json
{  "experimental": {    "modelContextProtocolServers": [      {        "transport": {          "type": "stdio",          "command": "C:\\path\\to\\sassymcp.exe"        }      }    ]  }}

HTTP / Grok Desktop / custom HTTP clients

Run the server in HTTP mode (sassymcp.exe --http, default 127.0.0.1:21001) and point your client at http://127.0.0.1:21001/mcp/. Set SASSYMCP_AUTH_TOKEN if the bind is non-loopback.

json
{  "mcpServers": {    "sassymcp": {      "url": "http://127.0.0.1:21001/mcp/"    }  }}

What's actually Claude-flavored (cosmetic only)

A few docstrings and the legacy .claude/skills/sassymcp-update.md slash-command target Claude Code specifically. Other clients ignore them and use sassy_update_* tools directly. No tool, transport, or auth path requires Claude — the server doesn't know which LLM is on the other end.

Transport Modes

ModeCommandUse Case
Stdiosassymcp.exeClaude Desktop, Cursor (direct pipe)
HTTPsassymcp.exe --httpGrok Desktop, Windsurf (localhost:21001)
HTTP LANsassymcp.exe --http --host 0.0.0.0Multi-device (requires auth token)
HTTPSsassymcp.exe --http --sslEncrypted (auto-generates self-signed cert)
SSEsassymcp.exe --http --sseLegacy transport

Running Multiple Instances (Dual Session)

Two SassyMCP processes on the same machine — for example, a local stdio instance for Claude Desktop and a remote HTTPS instance behind a Cloudflare Tunnel for Claude Web — can clobber each other's state if they share ~/.sassymcp/. The fix is one env var per instance.

Conflicts to resolve per-instance

ResourceDefaultHow to give each instance its own
HTTP port21001--port 21002 (HTTP-mode instances only)
Crosslink HTTP port9377sassy_crosslink_register port=9378
Auth tokenenv SASSYMCP_AUTH_TOKENSet per-process in launcher's env
Per-user state dir~/.sassymcpSASSYMCP_HOME=/path/to/dir ← the new env var (v1.3.4+)
SSL cert/key$SASSYMCP_HOME/server.{crt,key}Auto-isolated when SASSYMCP_HOME is set; or --ssl-cert / --ssl-key

Example: local stdio + remote tunnel side-by-side

Instance A — local stdio for Claude Desktop (claude_desktop_config.json):

json
{  "mcpServers": {    "sassymcp-local": {      "command": "C:\\Tools\\SassyMCP\\sassymcp.exe",      "env": {        "SASSYMCP_LOAD_ALL": "1",        "SASSYMCP_HOME": "C:\\Users\\<you>\\.sassymcp-local"      }    }  }}

Instance B — remote HTTPS via Cloudflare Tunnel (start-tunnel.bat + a wrapper that sets the env):

batch
set SASSYMCP_HOME=C:\Users\<you>\.sassymcp-remoteset SASSYMCP_AUTH_TOKEN=<token-for-remote>set PORT=21002"%~dp0sassymcp.exe" --http --host 127.0.0.1 --port %PORT%

Then cloudflared tunnel run <name> forwards https://<your-tunnel>/mcp to 127.0.0.1:21002.

What's isolated when SASSYMCP_HOME differs

Each instance gets its own:

  • persona.md — different profiles per session
  • config.json — different runtime config (allowed dirs, blocked commands, etc.)
  • tokens.json — different scoped auth tokens
  • license.json — separate license activation
  • audit.log / audit.jsonl — no interleaved writes
  • crosslink.db — separate cross-session message queues
  • memory.db — separate persistent memories
  • tool_state.db / tool_usage.json — separate per-tool state and usage analytics
  • server.crt / server.key — separate self-signed certs
  • The _security protected-paths check honors SASSYMCP_HOME too — neither instance can sassy_safe_delete into the other's home

What's still shared between instances

  • The repo source tree (always protected from delete/overwrite by _security)
  • %LOCALAPPDATA%\SassyMCP\updates\ — the updater download stage (harmless; tagged by version under it)
  • The bundled tools in the portable zip (adb, nmap, cloudflared, etc.) — read-only from both instances

Putting it in the OS (so both start at boot)

The legacy personal/autostart-bridge.bat + personal/register-autostart.ps1 template is gitignored — copy it, tweak the paths and the SASSYMCP_HOME for each instance, then Register-ScheduledTask once per instance.

Environment Variables

VariablePurpose
SASSYMCP_LOAD_ALL=1Load every tool group
SASSYMCP_GROUPS=core,androidLoad specific groups
SASSYMCP_AUTH_TOKEN=xxxBearer token for HTTP auth
SASSYMCP_DEV=1Enable live reload (dev mode)
SASSYMCP_NO_UPDATE_CHECK=1Disable the startup update check (no GitHub API call)
SASSYMCP_HOME=/path/to/dirOverride the per-user state dir (default ~/.sassymcp). Required when running multiple instances on one machine.
SASSYMCP_REPO=/path/to/repoOverride the auto-detected repo root in tools/mercury_audit_sassymcp.py (dev tool only)
GITHUB_TOKEN=xxxGitHub API access
SSH_HOST=xxxRemote Linux hostname/IP
SSH_USER=xxxRemote Linux username
SSH_PASS=xxxRemote Linux password

External Tools

All bundled in the beta zip package. Install separately only if using the standalone exe.

ToolUsed ByBundledInstall (if needed)
ADBAll sassy_adb_* + sassy_phone_* toolsYesAndroid Platform Tools
nmapsassy_port_scanYesnmap.org
plinksassy_linux_execYesPuTTY
scrcpysassy_scrcpy_* toolsYesscrcpy releases
Tesseractsassy_screen_ocr, sassy_find_text_on_screenYestesseract-ocr
Chromesassy_url_screenshotNogoogle.com/chrome

Run sassy_setup_check_tools to verify all tools are detected.

Requirements

  • Windows 10/11, macOS 12+, or Linux — one source, routed at the head (sassymcp._platform) to the right command per host. See Cross-platform below.
  • Python 3.11+ (only if running from source; the standalone binary is self-contained — built per OS, since PyInstaller can't cross-compile)

Cross-platform

The same SassyMCP source runs on Windows, macOS, and Linux. The host OS is resolved once at import; every tool then routes to the host-appropriate command — shells (PowerShell / zsh|bash), clipboard (Get-Clipboard / pbpaste), event log (Get-WinEvent / log show / journald), firewall (netsh / socketfilterfw / ufw), Wi-Fi, Bluetooth, window control (pywinauto / AppleScript System Events / wmctrl), SSH (plink / native ssh), package installs (winget / brew / apt), and more.

  • Build: build.bat (Windows) or build.sh (macOS/Linux). Build each binary on its own OS.
  • macOS permissions: window-control and screenshot tools need Accessibility and Screen Recording permission for the app running SassyMCP (System Settings → Privacy & Security).
  • A handful of concepts are Windows-only by nature (raw Registry read/write/export); those report a clear message and point to the native equivalent (defaults, launchd). Forensic persistence (sassy_autorun_entries) IS cross-platform (Run keys / LaunchAgents / systemd+cron).

License

Proprietary - Copyright (c) 2026 Sassy Consulting LLC. All rights reserved.

Source: README.md at commit ca10608

Tools

91

sassy_write_file

Mutating: creates or overwrites files. mode defaults to 'rewrite' (full replace); on an existing file the prior contents are first snapshotted into the adjacent _DELETE_/ staging folder as stem.overwrite.<timestamp>.ext, so overwrites are recoverable. mode 'append' adds bytes to the end. Missing parent directories are created. encoding defaults to utf-8 (any Python codec name); line_endings defaults to 'preserve' (verbatim), with 'lf' and 'crlf' normalizing all line breaks (crlf is useful for Windows .bat/.ps1 files). It bypasses the shell-keyword interceptor entirely, but protected paths (SassyMCP source tree, ~/.sassymcp, ~/.ssh, ~/.aws, etc.) are refused. Use it to create files or full rewrites; prefer sassy_edit_block or sassy_edit_multi for small changes to existing files.

Parametersmodepathrequiredcontentrequiredencodingline_endings

sassy_ghq_issues

Read-only. Lists issues in a repo, 30 per page. Required: owner, repo. Optional state (open is default; closed or all are valid) and page (default 1; GitHub pages are 1-indexed). Returns the issue list as JSON. Note the GitHub issues endpoint includes pull requests in its results, so some entries may be PRs. Requires a GitHub token (GITHUB_TOKEN or GITHUB_PERSONAL_ACCESS_TOKEN). Use for a quick daily-driver listing; for label filters, sorting, direction, or custom page sizes use the github_full tool sassy_gh_list_issues. To create an issue use sassy_ghq_issue.

Parameterspagereporequiredownerrequiredstate

sassy_state_clear

Destructive and mutating: permanently deletes stored state from the persistent per-tool SQLite state store (tool_state.db in the SassyMCP home directory). Optional tool_name="": when given, deletes every key saved under that tool name; when empty, deletes ALL state for ALL tools across the server with no way to recover. Requires confirm='YES' (exact, case-sensitive) on every call, matching the sassy_permission privilege mutations and sassy_audit_clear. Use to reset a misbehaving tool's remembered state or to wipe the whole state store clean; read first with sassy_state_get and back up values with sassy_state_set if they matter.

Parametersconfirmtool_name

sassy_audit_log

Read-only. Returns the tail of the audit log (~/.sassymcp/audit.log), which records every tool call with timestamp, tool name, and sanitized (secret-redacted) arguments, plus policy and interceptor events. count sets how many of the most recent lines are returned (default 50), newest last. Use it to review what tools were called recently and with what arguments. When you need entries matching a term rather than the plain tail, use sassy_audit_search.

Parameterscount

sassy_recent_tool_calls

Read-only. Returns recent tool call records parsed from the structured JSONL audit log (the same store the audit module writes; sassy_audit_log reads the plain-text audit.log variant). Optional max_results=50 (docstring caps at 1-1000; the code takes the newest N entries), tool_name="" filters to one tool name, since_minutes=0 means all time or only calls within the last N minutes. Output includes the call entries newest-last, the returned count, and total_in_log (all lines in the file, including skipped/malformed). Returns an empty list with a note if no audit log exists. Use for session history, debugging what ran, and usage review; for raw log text use sassy_audit_log, for keyword search use sassy_audit_search. Overlap note: sassy_audit_log covers the same recent-call history as plain text — prefer this tool when you want structured, filterable records.

Parameterstool_namemax_resultssince_minutes

sassy_observability_health

Read-only health check for monitoring. Returns a small dict: status (always "healthy" when reachable), uptime_seconds, tool_calls_total, error_count, and whether dev live-reload is enabled. Counters accumulate in memory since server start and reset on restart. Takes no parameters. Use for liveness probes, load balancers, or a quick sanity check that the server is up. For CPU/memory/disk figures use sassy_observability_metrics instead.

Takes no parameters.

sassy_offline_handoff

Mutating. Writes a structured offline handoff and optionally starts the local Hermes node. Required parameter task describes what was being worked on. Optional channel (default "joint") is the crosslink channel Hermes polls; next_steps is a newline- or semicolon-separated list of ordered steps; start_node=false, when true, launches hermes_node.py in a persistent session. The tool writes key task_offline_<channel>_state to memory, mirrors it to the crosslink channel, and returns the exact env line and launch command plus the node session name. Errors are returned inline if hermes_node.py is missing or no fallback model is ready. Use after sassy_offline_status confirms the link is down, when handing ongoing work to a local model; read Hermes replies with sassy_crosslink_recv.

Parameterstaskrequiredchannelnext_stepsstart_node

sassy_session_read

Read-only. Returns output from a named persistent session that arrived since the last read (the cursor advances, so each call yields only new text), truncated to the last 10000 characters, plus an alive flag and the total buffer size. Fails if the session name does not exist. Use it to poll long-running sessions created by sassy_session_start or auto-detached from sassy_shell (timeout over 120s) without sending input; use sassy_session_send to interact.

Parametersnamerequired

sassy_get_config

Read-only. Returns the full SassyMCP configuration plus a live system snapshot: the config dict (default shell, file read/write line limits, allowed directories, blocked commands, interceptor and permission-engine settings, panel port/enabled), OS and Python details, process and system memory, disk usage, PID, uptime seconds, CPU count, loaded tool groups, and tool-usage stats from the audit log. Takes no parameters. Use to inspect current server settings before calling sassy_set_config, or to diagnose performance and environment issues. Prefer over guessing config values.

Takes no parameters.

sassy_setup_license

Manages the optional SassyMCP supporter license against LemonSqueezy. The action parameter (default "status") accepts status, activate, deactivate, validate; the key parameter is required only for activate and must look like XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. All tool groups are unlocked for everyone with no key, so activating registers your seat and tier label but unlocks nothing. action=status is read-only and reports tier, addons, validity, email, expiry, the license file path, and any LemonSqueezy instance identifiers. action=activate registers this machine and mints a local HMAC payload for offline use. action=deactivate frees the machine's seat and deletes the local file. action=validate forces an immediate LemonSqueezy re-check (normally weekly). Use status to inspect the current tier; only activate with a key purchased from sassyconsultingllc.com/store.

Parameterskeyaction

sassy_persona_full

Read-only. Loads the complete operating bundle in one call and returns a JSON object with six keys: style, decisions, practices, observability, capabilities, and context (each the same plain text document returned by the corresponding narrow tool). Takes no parameters. Call this on first connection to a SassyMCP session so the session starts with operating parameters, decision rules, engineering standards, the observability guide, the capabilities manual, and user context all at once. It is the heaviest of the persona tools in context cost; if you only need one section, call the narrow tool (sassy_persona_style, sassy_persona_decisions, sassy_persona_practices, sassy_persona_observability, sassy_persona_capabilities, or sassy_persona_context) instead.

Takes no parameters.

sassy_zip

Mutating: writes a new zip archive to disk. Creates a zip from a file or directory in source; directories are walked recursively and files are stored with paths relative to the source root, while a single file is stored under its basename. compression (default deflated) accepts deflated, stored, bzip2, or lzma, and unrecognized values fall back to deflated. output defaults to source plus .zip, replacing the extension for files. Sensitive members are not blocked (full-directory backups must keep working): if any archived file matches the sensitive-read denylist (SSH keys, credential stores, ...), the archive is still created but the result carries a 'warning' field listing them and the event is audit-logged. Returns the created path, file count, original and zip byte sizes, and a compression ratio percentage. Use it to package files for sharing; use sassy_unzip to extract what it creates.

Parametersoutputsourcerequiredcompression

sassy_update_list

Read-only. Lists the downloadable assets for one release as JSON: tag, current version, asset_count, and per-asset name, size_bytes, download_url, content_type, and download count. Optional tag; defaults to the latest release. Lookup is limited to the five newest published releases (older tags return a not-found error) and drafts are excluded. Requires network access to the GitHub releases endpoint. Use after sassy_update_check to pick the right asset_name for sassy_update_apply; use sassy_update_changelog for the release notes. Nothing here downloads or installs anything.

Parameterstag

sassy_audit_clear

Mutating but non-destructive: rotates the active audit logs rather than deleting anything. Requires confirm='YES'; anything else is refused. Renames $SASSYMCP_HOME/audit.log and audit.jsonl (default ~/.sassymcp) to audit.cleared.<YYYYMMDDTHHMMSS>.log/.jsonl, then logs the rotation itself into the fresh log. Nothing is ever unlinked, so forensic history is preserved in the archives. Use when you want a fresh log tail while keeping history; prefer sassy_audit_log or sassy_audit_search for reading entries.

Parametersconfirm

sassy_update_check

Read-only (fetches remote release state; changes nothing). The apt-update equivalent: contacts the GitHub releases endpoint and reports current version versus latest version as JSON with an upgradable boolean and a one-line summary. Results are cached for 5 minutes; pass force=true to bypass the cache and hit the network again. If GitHub is unreachable it returns an error instead of guessing. Takes no other parameters and requires network access. Use as the first update step to learn whether an upgrade exists; then use sassy_update_changelog to read the notes, sassy_update_list to see the assets, and sassy_update_apply to download.

Parametersforce

sassy_session_send

Mutating: types into a live persistent session like a terminal, with a newline appended automatically, and returns the last 5000 characters of new output after a brief pause. The input is scanned by the same gates as sassy_shell: blocklist matches and delete keywords (rm, del, Remove-Item) are refused here, because session input cannot be safely staged — use sassy_safe_delete for removals instead. Fails if the session does not exist or has exited. Use it to interact with REPLs, prompts, and dev servers running in a session; use sassy_shell for one-shot commands.

Parametersnamerequiredinput_textrequired

sassy_env_list

Read-only. Lists environment variables of the SassyMCP server process, sorted by name, with their count. filter_str (string, default empty) limits results to variable names containing that case-insensitive substring. Values that look sensitive (names containing token, key, secret, password, api, or credential) are masked to the first 4 and last 4 characters (or **** if short); other values are truncated at 200 characters. Use it to discover available variables before calling sassy_env_get, and use sassy_env_set to change one.

Parametersfilter_str

sassy_ghq_protect

Mutating: applies a fixed branch-protection preset to branch (default main) in owner/repo. The preset blocks force pushes and deletions and enforces the rules on admins, but sets no required status checks and no required PR reviews. Returns the protection result as JSON. Requires a GitHub token (GITHUB_TOKEN or GITHUB_PERSONAL_ACCESS_TOKEN). Use for the quick standard lock-down of main; for custom rules (required reviews, approval counts, status checks, allowing force pushes) use the github_full tool sassy_gh_protect_branch instead, and to inspect or remove protection use sassy_gh_get_branch_protection or sassy_gh_remove_branch_protection.

Parametersreporequiredownerrequiredbranch

sassy_mkdir

Mutating: creates a directory, including any missing parents, and succeeds silently if the path already exists. Refuses paths that fail the read-path policy (blocked or protected locations). Returns the resolved path. sassy_write_file already creates missing parent directories, so call this mainly when you need an empty directory or an explicit container for later steps.

Parameterspathrequired

sassy_hooks_deactivate

Mutating: removes hooks from the in-memory active list for this session. hook_name is optional; pass a specific active hook name to deactivate just it, or pass nothing to clear all active hooks at once. Returns {"deactivated": name} on success or {"status": "all hooks deactivated"} when clearing; attempting to deactivate a hook that is not active returns an error. Use it when a playbook no longer applies to the task or you want a clean slate before activating a different one; use sassy_hooks_list to see which hooks are currently active.

Parametershook_name

sassy_state_set

Mutating. Persists a value into the per-tool SQLite state store (tool_state.db in the SassyMCP home directory), surviving server restarts. Required: tool_name namespaces the entry (any tool name can be used); required: key is the storage key; required: value is a string that is stored verbatim (the tool does not JSON-encode it — pass already-encoded JSON if you want structured values). Overwrites any existing value for the same tool/key pair. Returns a confirmation string. Use to checkpoint progress, save cursors, or persist preferences between sessions; read with sassy_state_get and delete with sassy_state_clear. Not a substitute for the memory system, which stores semantic facts.

Parameterskeyrequiredvaluerequiredtool_namerequired

sassy_copy

Mutating: duplicates a file or an entire directory tree. Files are copied with metadata (shutil.copy2); directories copy recursively. Parent directories of the destination are created as needed. Refuses protected sources or destinations (SassyMCP source tree, ~/.sassymcp) and refuses sources on the sensitive-read denylist (SSH keys, AWS/GPG credentials, /etc/shadow, browser login DBs, SassyMCP tokens) — copying such material is treated as read-equivalent exfiltration and refused like a content read. Also refuses to overwrite an existing destination — run sassy_safe_delete on the destination first if you really need to replace it. Use it to duplicate files or trees; use sassy_move when you want to relocate rather than duplicate.

Parameterssourcerequireddestinationrequired

sassy_update_changelog

Read-only. Returns the release notes for one release as JSON with tag, release name, published_at, the notes body, and the release URL. Optional tag; defaults to the latest release when omitted. If the tag is not found among recent releases it returns an error. Requires network access to the GitHub releases endpoint. Use to see what changed before deciding to upgrade; for the downloadable assets of that release use sassy_update_list, and to stage the download use sassy_update_apply. Does not check whether you are behind; for that use sassy_update_check.

Parameterstag

sassy_list_dir

Read-only. Lists directory entries with [FILE] and [DIR] prefixes, directories sorted before files alphabetically. depth controls recursion (default 2, clamped to 1-10). Below the top level, dotfiles and node_modules/__pycache__/.git are skipped, and per-level caps apply (500 entries at top, 100 deeper, 1000 lines total) with warnings naming how many items were hidden. Use it to explore a directory tree; use sassy_file_info for metadata about one path and sassy_read_file to read a file's contents.

Parameterspathrequireddepth

sassy_permission

Read-only by default, mutating on change actions. Front door to the four-mode safety system gating shell and file tools. action="status" (default) reports the effective mode, derivation, sandbox roots, and active rules. set_mode sets permission.mode to strict (block destructive patterns), confirm (return a confirm token), sandbox (relaxed inside sandbox roots, anything outside is refused), or bypass (allow all except protected paths); mode="" clears the override so it derives from the legacy interceptor.destructiveAction setting. Switching to bypass requires confirm='YES' (exact, case-sensitive); the privilege mutations add_root (widens the sandbox jail), add_rule, and clear_rules also require confirm='YES', while remove_root (shrinks the jail) needs no confirmation. add_rule appends a JSON rule like {"action":"deny","tool":"sassy_shell","command":"rm"} (first match wins, before the mode default); clear_rules empties the list. Invalid modes and rules are rejected. Use to inspect or change safety gating; pair with sassy_shell_confirm in confirm mode.

Parametersmodepathruleactionconfirm

sassy_offline_status

Read-only. Runs the real network-state check and reports the full offline picture: link state (online, offline, or DNS-dead), DNS resolving, probe anchors, check age, gate mode and whether it is active, local loopback inference backends with available models and the chosen fallback, the hermes_node.py script path, counts of offline-safe vs LAN vs internet tools, and, when degraded, each unavailable tool with a named substitute. Optional probe=true (default) runs a fresh ~1-2 second probe; false reads the cached verdict instantly. Use as the first step when connectivity is suspect or before any offline workflow.

Parametersprobe

sassy_ghq_pr

Mutating: creates a pull request. Required: owner, repo, title, head (source branch containing your commits), base (target branch the PR merges into, e.g. main). Optional body (default empty string). Returns the created PR as JSON. Requires a GitHub token (GITHUB_TOKEN or GITHUB_PERSONAL_ACCESS_TOKEN). The tool itself creates immediately with no draft mode; for draft PRs or more control use the github_full tool sassy_gh_create_pr. To review an existing PR end-to-end (metadata, diff, comments, CI status) in one call, use sassy_combo_pr_review instead of fetching pieces manually.

Parametersbaserequiredbodyheadrequiredreporequiredownerrequiredtitlerequired

sassy_safe_delete

Mutating but non-destructive: instead of deleting, it moves the file or directory into a _DELETE_/ staging folder in the same parent directory, renaming with _1, _2 suffixes on collisions so nothing is silently lost. It moves the symlink itself, not its target. Refuses protected paths (SassyMCP source tree, ~/.sassymcp, existing _DELETE_ folders) and audits the interception. This is the required replacement for rm/del-style deletion: shell delete keywords are intercepted, and sassy_copy/sassy_move refuse to overwrite an existing destination until it is staged here first. Use it for any removal; review or restore items from the _DELETE_ folder later.

Parameterspathrequired

sassy_screenshot

Read-only with respect to the desktop; writes an image file. Saves a PNG screenshot of the screen and returns its path and pixel dimensions. path defaults to ~/sassymcp_screenshot.png; region is an 'x,y,w,h' string that takes precedence over monitor (a malformed region returns an explicit error instead of falling back to a full screenshot); monitor defaults to -1 (all monitors), 0 for primary, 1+ for others. The save path must pass validation and must not be a protected location. Use it to see the current screen state, especially before or after sassy_click/sassy_type_text; pair with sassy_screen_info for multi-monitor region math. Requires a GUI session; on headless hosts it returns an error.

Parameterspathregionmonitor

sassy_tool_groups

Read-only. Lists all available tool groups with their load status and metadata: member modules, one-line description, always_load flag, tool counts, network requirements, and per-group rate limits. Takes no parameters. Use this to see which groups are loaded before enabling more or diagnosing missing tools (missing tools are usually in a dormant on-demand group); use sassy_tool_group_toggle to change load state and sassy_tool_catalog to list the tools inside a group.

Takes no parameters.

sassy_session_list

Read-only. Lists all persistent terminal sessions as JSON: name, shell, pid, alive flag, uptime in seconds, output buffer size, exit code, plus a total count. Dead sessions remain listed until stopped. Use it to see what is running before sassy_session_read, sassy_session_send, or sassy_session_stop; auto-detached sassy_shell calls also appear here.

Takes no parameters.

sassy_env_set

Mutating: changes the process environment of the running SassyMCP server. Sets one variable immediately for the server process and anything it spawns from this point on. It does NOT modify system or user environment settings, and the change is lost when the server restarts. Returns the variable name, scope process, and an expiry note. Use it only for values needed during the current session; for permanent configuration change the OS or shell profile instead of calling this.

Parametersnamerequiredvaluerequired

sassy_click

Mutating: performs a real mouse click on the host desktop. Clicks at absolute screen coordinates (x, y required) with button defaulting to 'left' (also 'middle', 'right') and clicks defaulting to 1 for double-clicks and beyond. Coordinates are absolute across all monitors, so call sassy_screen_info first (or sassy_desktop_state) to find monitor positions and window locations. Works on Windows, macOS, and Linux via pyautogui. Use it for clicking GUI elements; use sassy_hotkey for keyboard shortcuts and sassy_type_text for entering text.

Parametersxrequiredyrequiredbuttonclicks

sassy_untar

Mutating: writes extracted files to disk. Extracts tar, tar.gz, tar.bz2, or tar.xz archives using a data-only extraction filter. destination defaults to the archive's parent directory under the archive name with the .tar extension removed. Existing files at the destination are silently overwritten. There is no password option, unlike sassy_unzip. Returns the extraction path, the file count, and a sample of the first 20 member names. Use it to open archives created by sassy_tar or downloaded from the web.

Parametersarchiverequireddestination

sassy_audit_false_positives

Read-only. Surfaces recent shell-interceptor pattern events from the local JSONL audit log (~/.sassymcp/audit.jsonl) as rows of timestamp | event | pattern | command (truncated to 120 chars). count caps rows (default 20), newest last. include_bypasses defaults to True, showing both pattern_block entries (commands refused) and pattern_bypass entries (allowed via sassy_shell's allow_pattern); set it False to see only refused commands. Use it to diagnose why a sassy_shell command was blocked and to pick the exact allow_pattern label for a retry. For general log history use sassy_audit_log.

Parameterscountinclude_bypasses

sassy_tar

Mutating: writes a new tar archive to disk. Creates a tar from a file or directory path in source; directory contents are stored under the top-level directory name. compress (default gz) accepts gz, bz2, xz, or none, and any other value returns an error. output defaults to the source path plus .tar.gz, .tar.bz2, .tar.xz, or .tar according to compress. Sensitive members are not blocked (full-directory backups must keep working): if any archived file matches the sensitive-read denylist (SSH keys, credential stores, ...), the archive is still created but the result carries a 'warning' field listing them and the event is audit-logged. Returns the created path, a file count, and the archive size in bytes. There is no password option, unlike sassy_unzip. Use it to bundle directories for transport or backup; use sassy_untar to extract what it creates.

Parametersoutputsourcerequiredcompress

sassy_ghq_issue

Mutating: creates a GitHub issue in the given repo. Required: owner, repo, title. Optional body (default empty string) and labels as a comma-separated string, e.g. labels bug,docs becomes a label array. Returns the created issue as JSON. Requires a GitHub token (GITHUB_TOKEN or GITHUB_PERSONAL_ACCESS_TOKEN). This is the lean daily-driver create path; for assignees, milestones, or other fields use the github_full tool sassy_gh_create_issue. To find existing issues first, call sassy_ghq_issues; to add a comment to an existing issue, use the github_full tool sassy_gh_add_issue_comment.

Parametersbodyreporequiredownerrequiredtitlerequiredlabels

sassy_setup_generate_token

Mutating: creates a cryptographically secure auth token (secrets.token_urlsafe(32)) and saves it to ~/.sassymcp/tokens.json, replacing any existing entry for the same client_id, then locks the file to owner-only (chmod 0600 on POSIX, ACL lockdown on Windows). The client_id parameter defaults to "default" and identifies the MCP client (e.g. claude-desktop, cursor). The scopes parameter is a comma-separated string defaulting to "read,write"; valid scopes are read, write, and admin. The returned token is shown once only, with usage instructions for the SASSYMCP_AUTH_TOKEN environment variable, the Authorization: Bearer <token> header, and the ?token= query form. Use this when onboarding a new MCP client that needs to authenticate. Trust assumption (deliberate): this tool is intentionally not gated by a confirmation — any MCP client that can call tools can mint bearer tokens, equivalent to the generate-token CLI subcommand, so local automation can bootstrap client auth. Treat every minted token like a password and review ~/.sassymcp/tokens.json if a session behaves unexpectedly. For a read-only view of existing token state, call sassy_setup_status first.

Parametersscopesclient_id

sassy_panel

Mutating (start/stop/rotate change state). Controls the Control Panel, the loopback-only web UI for the permission engine, settings, event log, and classifiers. Optional action (default "status"): status returns running state, the startup-enabled flag, and a tokenless URL — the bearer token is never revealed here; start launches the panel and enables auto-start at future startups (flips panel.enabled in config) and returns a tokenless URL plus a hint to call action="url"; stop shuts it down and disables auto-start; url prints the tokenized URL without starting (this is the explicit token-reveal action); rotate regenerates the panel bearer token, persists it to the token file, audit-logs the rotation, and returns the new token (the old token stops working immediately, no restart needed). Binds 127.0.0.1 on the configured port (default 8765, auto-increments if taken). Send the token in the X-Panel-Token header (the ?token= query form is deprecated but still accepted). Use for interactive inspection and tuning of permissions/settings rather than doing it by hand with sassy_set_config.

Parametersaction

sassy_setup_ssh

Mutating: saves SSH credentials to the process environment and config, and can open a real test connection. The action parameter (default "check") accepts check, save, test, skip. action=check is read-only: reports whether plink (Windows) or native ssh (macOS/Linux) was found, plus which of SSH_HOST, SSH_USER, SSH_PASS, SSH_KEY, SSH_SESSION are set. action=save requires host and user plus at least one auth source: key (a .ppk path, preferred), session (a saved PuTTY session name), or password (fed via stdin, never in the process list); missing pieces return status=incomplete. action=test runs the actual ssh command with a 15 second timeout and reports connected, failed, or error. Credentials last only for this session unless also set in system env or MCP client config.

Parameterskeyhostuseractionsessionpassword

sassy_setup_tools

Mutating installer for external tool dependencies; use action=check for the read-only report. The action parameter (default "check") accepts check, install, install_required, add_to_path. The tool_name parameter is required only for action=install and must be one of tesseract, adb, scrcpy, nmap, plink, cloudflared. action=check reports each tool as found with its path and required flag; only tesseract is required (OCR/vision need it unconditionally), while adb/scrcpy serve Android tools and plink serves SSH/Linux tools. action=install_required installs every missing required tool; action=install installs the named tool, both via the host package manager (winget, brew, or sudo apt-get) with a 180 second per-package timeout, so installs take minutes. Run action=add_to_path (or restart) afterward. For a read-only scan also covering Chrome and Python packages, use sassy_setup_check_tools.

Parametersactiontool_name

sassy_state_get

Read-only. Retrieves one value from the persistent per-tool SQLite state store (tool_state.db in the SassyMCP home directory), surviving server restarts. Required: tool_name namespaces the key under a tool; required: key is the stored key. Returns the JSON-decoded value (whatever was saved with sassy_state_set) or null if the tool/key was never set. Use to read remembered state such as checkpoints, cursors, or preferences; use sassy_state_clear to delete and sassy_state_set to write. This is separate from the memory system — it is for tool operational state, not semantic memories.

Parameterskeyrequiredtool_namerequired

sassy_diff

Read-only. Compares two files and returns a unified diff. Both files are read as UTF-8 (decoding errors replaced); returns an error if either path does not exist. context_lines (integer, default 3) sets how many unchanged lines surround each hunk. The response includes identical (true when files match), lines_added and lines_removed counts, and diff text truncated at 20,000 characters. It compares file contents only, not metadata like timestamps or permissions. Use it to verify exactly what changed between two file versions before copying, restoring, or reviewing them.

Parameterspath_arequiredpath_brequiredcontext_lines

sassy_update_apply

Mutating (writes a downloaded file to disk; does NOT execute anything). Downloads one release asset to staging and returns the local path plus a run command the user executes manually. Required: asset_name (exact filename; get valid names from sassy_update_list). Optional tag (default latest) and dest_dir (default LOCALAPPDATA/SassyMCP/updates on Windows, ~/SassyMCP/updates otherwise). If the release publishes a SHA-256 sidecar, the download is verified: on mismatch the file is deleted and the tool errors; with no sidecar it warns but proceeds. The run command is per asset type AND host OS: msiexec /i for .msi on Windows (.msi is Windows-only and refused with guidance on POSIX), Expand-Archive for .zip on Windows vs unzip -o plus chmod +x on POSIX, tar -xzf for .tar.gz/.tgz, direct path otherwise. Disabled in packaged/frozen builds: returns an error telling you to install a new release artifact instead. Requires network access.

Parameterstagdest_dirasset_namerequired

sassy_tool_catalog

Read-only. Enumerates every currently registered tool derived live from the tool registry (so it never drifts from reality), returning total count, per-group counts, the applied filters, and tools grouped by group as name plus one-line purpose, sorted by group then name. group (default empty = all) filters to one tool group; use sassy_tool_groups to learn valid group names. query (default empty) is a case-insensitive substring match against the tool name or its purpose line. Use this as the client-agnostic capability map to see what the server can actually do; prefer it over sassy_tool_groups when you need tool-level detail rather than group metadata.

Parametersgroupquery

sassy_tool_group_toggle

Mutating: flips a tool group's always_load flag in the running server process, enabling (enable=true, default) or disabling (enable=false) its modules, and attempts a tools/list_changed notification so capable clients (Claude Code, Cursor) refresh automatically. Clients that do not handle it (Claude Desktop today) need a manual server restart. group must be an exact group name (core, infrastructure, android, system, forensics, linux, github_quick, github_full, persona, utility, setup, memory, updater, combos, prompts); an unknown name returns an error listing the valid groups. Returns status, the group's modules, and whether the notification was sent. Use it to trim context by disabling heavy unused groups like github_full, or to load dormant capability on demand; check sassy_tool_groups first for current load status.

Parametersgrouprequiredenable

sassy_minify_test

Read-only diagnostic. sample_json is a JSON string containing a sample GitHub API response; nothing is sent anywhere. The tool parses it, runs it through the same minifier applied to GitHub tool responses, and reports original_chars, minified_chars, savings_percent, original/minified estimated tokens (chars divided by 4), tokens_saved, and the minified_data itself. Invalid JSON returns an error instead of results. Use it to gauge how much the GitHub response shrinker will reduce a heavy github_full response before you commit to a large call; it is a test harness, not a live API caller.

Parameterssample_jsonrequired

sassy_tool_usage

Read-only. Returns tool usage analytics tracked by the server and persisted across sessions in ~/.sassymcp/tool_usage.json (last 90 days, capped at 500 invocations per tool): unique_tools_ever, total_invocations, invocations_today, invocations_this_week, and a top_10 list of tool names with recency-weighted scores (0.0-1.0 via exponential decay, so recent calls count more). Takes no parameters. Use it to see which tools are actually exercised, to inform which groups are safe to disable, or to understand usage patterns; pair with sassy_tool_groups when deciding what to prune for context savings.

Takes no parameters.

sassy_persona_capabilities

Read-only. Returns the SassyMCP capabilities guide, the instruction manual for advanced features: dynamic desktop vision (sassy_screen_glance for cheap repeated watches, sassy_screen_watch for change-triggered frames, sassy_screen_diff for before/after verification, sassy_screen_capture for full-res), Android phone vision (sassy_phone_ui for the structured accessibility tree with coordinates, sassy_phone_state, sassy_phone_watch, sassy_phone_glance) and interaction (tap, swipe, type, key, open), sensitive context detection (interaction tools refuse on login, payment, account, 2FA, or permission screens unless confirmed=True after explicit user confirmation), pause/resume for user handoff, the setup wizard steps, and the hook playbook system (sassy_hooks_suggest/activate/deactivate with categories like web_audit, security_scan, code_review, phone_autonomous). Takes no parameters, returns plain text. Use before any vision, phone, or hook workflow to learn the tool roles and safety rules.

Takes no parameters.

sassy_hooks_suggest

Read-only. user_text is the user's request in free text (required); the tool scores it against each hook's trigger phrases and returns ranked matching hooks, the top_match name, and a hint naming the hook to consider activating. Returns an empty suggestion list with a note to proceed without a playbook when nothing matches. Use when you are unsure which hook applies or proactively when a request sounds like a known domain; then call sassy_hooks_activate with the top match.

Parametersuser_textrequired

sassy_hooks_activate

Mutating session state: appends the named hook to the in-memory active hook list (hooks can be stacked). Read the playbook carefully afterward. hook_name is the exact hook ID; if not found, the tool returns an error plus the available hook names and substring-based suggestions. On success it returns the full expert playbook: name, owning module, description, and step-by-step instructions covering which tools to use, in what order, what to look for, and what not to do. Use sassy_hooks_list first to discover valid hook names. Activate a hook when a task matches a known domain and you want structured expert guidance; use sassy_hooks_deactivate to unload it.

Parametershook_namerequired

sassy_persona_observability

Read-only. Returns the cross-system observability guide: which introspection tools exist and what each returns — sassy_get_config (system info, uptime, loaded modules), tool analytics (invocation counts, frequency scores), sassy_context_estimate (token use by tool definitions, critical for 100+ tool sessions), audit trail (every invocation with timestamp, sanitized args, elapsed ms), health metrics, cross-session status, and the capability map (sassy_self_check reconciles the module manifest against the live registry and flags BROKEN modules; sassy_tool_catalog lists every registered tool). Also prescribes the recommended first-call sequence: sassy_self_check, then sassy_tool_catalog, then sassy_persona_full, then sassy_hooks_suggest. Takes no parameters, returns plain text. Use when starting a session or debugging what the server can do.

Takes no parameters.

sassy_session_stop_all

Mutating: terminates every active persistent terminal session (each process is terminated and cleaned up) and returns a list of stopped names with exit codes plus a total count. Use it at the end of a task to clean up leftover dev servers, builds, and watchers; use sassy_session_stop when you only want to end one session.

Takes no parameters.

sassy_shell_confirm

Mutating: executes a sassy_shell command that was returned as confirmation_required instead of hard-blocked, because interceptor.destructiveAction is set to 'confirm'. Tokens are single-use and expire after 60 seconds; each is bound to the exact command, shell, and working directory that produced it, so replay against anything different is rejected. HIGH-tier commands also require confirm_phrase to match the phrase shown in the original confirmation_required response. Execution is audit-logged as pattern_confirm_executed. Use it only as the second step of the confirm flow; it cannot start a command on its own.

Parameterstokenrequiredconfirm_phrase

sassy_setup_wizard

Mutating: first-run questionnaire that writes the user profile to ~/.sassymcp/persona.md (keeping a one-deep persona.md.bak backup of any existing file before overwriting) and marks setup_complete in config. All parameters are optional: role (developer, sysadmin, security, devops, data, designer, manager, other; default developer), expertise_level (junior, mid, senior, principal, staff; default senior), communication_style (terse, balanced, verbose; default terse), security_posture (standard, hardened, paranoid; default standard), plus comma-separated specializations, languages, frameworks, newline-separated systems and projects, mcp_clients, and notes. The has_android and has_linux booleans (default false) drive the returned tools_to_install list: tesseract always included, adb and scrcpy when has_android is true, plink when has_linux is true. The wizard installs nothing itself; the response includes next_steps and a hint to run sassy_setup_tools(action=install_required), and reloads the persona module in-process. Re-run anytime to update the profile. The result includes a persona_backup field with the backup path (null on first run).

Parametersrolenotessystemsprojectshas_linuxlanguagesframeworkshas_androidmcp_clientsexpertise_levelspecializationssecurity_posture+1 more

sassy_set_config

Mutating. Overwrites a server configuration value and persists it to the SassyMCP home directory config.json immediately (the change affects current and future server runs). Required: key must be one of the supported config keys (defaultShell, fileReadLineLimit, fileWriteLineLimit, allowedDirectories, blockedCommands, interceptor.destructiveAction, interceptor.scanStringLiterals, permission.mode, permission.sandboxRoots, permission.rules, panel.enabled, panel.port) — unknown keys are rejected and the valid list is returned. Required: value is a JSON-encoded string that is parsed before storing (so pass '1000' for a number, '["x"]' for a list, '"powershell"' for a string); if parsing fails the raw string is stored. Returns the key with old and new values. Use to tune limits, the default shell, blocked commands, safety modes, or panel settings; inspect current values first with sassy_get_config.

Parameterskeyrequiredvaluerequired

sassy_observability_metrics

Read-only. Returns real-time server metrics: uptime_seconds, tool_calls_total, error_rate (percent, rounded to two decimals), timestamp, version, and live_reload_enabled. Also includes cpu_percent, memory_percent, and disk_percent when psutil is installed (optional dependency). Takes no parameters; counters are in-memory since server start. Use for performance monitoring, capacity questions, and error-rate checks. For a simple up/down probe use sassy_observability_health.

Takes no parameters.

sassy_file_info

Read-only. Returns JSON metadata for a path: resolved absolute path, type (file or directory), size in bytes, and modified/created epoch timestamps. For files it adds a line count (and last line index); Excel files (.xlsx, .xls, .xlsm) also get sheet names with row and column counts via openpyxl. For directories it adds item, file, and directory counts of the immediate children. Use it to inspect a path before reading or editing it; use sassy_list_dir to browse a directory's entries and sassy_read_file for contents.

Parameterspathrequired

sassy_observability_tool_stats

Read-only. Returns the in-memory tool usage tracker's stats (per-tool call counts, success/error tallies, recency scores) plus pruning_suggestions: tool names whose usage score falls below a 0.05 threshold, i.e. candidates for disabling to slim the tool surface. Takes no parameters. Use to see which tools are actually used and which can be pruned. Differs from sassy_observability_metrics (aggregate server counters) by reporting per-tool usage. For raw recent call records use sassy_recent_tool_calls.

Takes no parameters.

sassy_toast

Shows a desktop notification on the machine running SassyMCP; no files or data are changed. Routed per platform: Windows tries BurntToast, then .NET toast, then msg.exe; macOS uses osascript; Linux uses notify-send and fails if libnotify is not installed. title and message are required; duration accepts short or long (default short) and anything else is treated as short, mapping to normal or critical urgency on Linux. Returns sent or failed plus the method used, with a 10-second per-method timeout. Use it to alert on completion of a long-running task the user is watching for.

Parameterstitlerequiredmessagerequiredduration

sassy_search_files

Read-only. Searches recursively under path. search_type 'files' (default) matches pattern as a regex against filenames via a recursive glob filtered by file_pattern (e.g. '*.py'); 'content' matches pattern as a regex against file contents, skipping files over 5MB and emitting path:line: text (200 chars, optional context_lines of before/after context). ignore_case defaults to True; max_results defaults to 50 and is clamped to 1-500. Use it to locate files by name or find text across a tree; use sassy_read_file to read a specific hit and sassy_list_dir to browse instead.

Parameterspathrequiredpatternrequiredignore_casemax_resultssearch_typefile_patterncontext_lines

sassy_persona_context

Read-only. Returns the current user context loaded at startup from the persona file at $SASSYMCP_HOME/persona.md (default ~/.sassymcp/persona.md): role, expertise, managed systems, active projects, and communication preferences. If no file exists it returns a template telling you how to create one. Takes no parameters, returns plain text. This is personal user configuration, not server state. Use when you need who-you-are-working-for context; to get it bundled with all persona documents in one call, use sassy_persona_full instead.

Takes no parameters.

sassy_ghq_push

Mutating: creates or updates multiple files in one atomic commit via the Git Data API, avoiding the SHA/ETag problems of single-file writes. Required: owner, repo, branch (must be the target branch name, e.g. main or a feature branch), message (commit message), files as a JSON string: an array of {path, content} objects. Malformed files JSON returns an error instead of pushing. Each file write overwrites the existing content at that path, so get the current content with sassy_ghq_get first when editing existing files. Requires a GitHub token (GITHUB_TOKEN or GITHUB_PERSONAL_ACCESS_TOKEN). For single-file operations, branches, or repos the github_full tool sassy_gh_push_files is the fuller equivalent.

Parametersreporequiredfilesrequiredownerrequiredbranchrequiredmessagerequired

sassy_setup_check_tools

Read-only scan of external tool availability. Checks six system binaries (nmap, tesseract, adb, scrcpy, plink, chrome) by searching PATH plus known install locations, and three Python packages (pytesseract, playwright, watchdog). For each tool it reports installed true/false, the resolved path, whether it is required, which sassy_* tools use it, and an install URL when missing. Only tesseract is marked required, since OCR/vision tools need it unconditionally. The returned summary lists installed, missing_required, and missing_optional. Takes no parameters and writes nothing. Use this first when diagnosing missing dependencies; when you are ready to install them, use sassy_setup_tools instead.

Takes no parameters.

sassy_hooks_list

Read-only. Lists every registered operational hook with metadata only (no full instructions): name, owning module, one-line description, and trigger phrases, plus a count and the names of currently active hooks. Takes no parameters. Use this to discover which playbooks exist before calling sassy_hooks_activate; if you know the user's request but not the right hook, use sassy_hooks_suggest to rank matches against the request text first.

Takes no parameters.

sassy_hotkey

Mutating: sends a real keyboard shortcut to the host. keys is a '+'-separated combination, e.g. 'ctrl+c', 'alt+tab', 'ctrl+shift+s', split and passed to pyautogui. Works on Windows, macOS, and Linux. There is no output validation beyond the confirmation echo, so verify the effect with sassy_screenshot if it matters. Use it for shortcuts like save, copy, or window switching; use sassy_type_text to type actual text into a field and sassy_click for mouse actions.

Parameterskeysrequired

sassy_self_check

Read-only diagnostic. Reconciles the declared module manifest against the live tool registry and reports verdict "whole" or "DEGRADED", package version, runtime (frozen for packaged builds, source for checkouts), pid, live_tool_count, and a per-module import report. It distinguishes real problems from expected absences: BROKEN modules (expected in the default load but fail to import, logged at ERROR) versus dormant_by_design (on-demand groups not yet toggled on, absent by design) versus pruned_low_usage (dropped by usage scoring) versus unsupported (optional modules failing on this platform, non-fatal). Takes no parameters. Use it to verify server health or to diagnose missing tools without confusing intentional lazy-loading with real failures.

Takes no parameters.

sassy_persona_practices

Read-only. Returns the engineering standards document: security defaults applied to every project (input validation, output escaping, parameterized queries, CSRF, auth best practices, security headers, rate limiting, upload validation, secrets handling, dependency audits, TLS, structured logging), code quality rules (types, tests, comments explain why, error handling), architecture patterns (env config, health checks, graceful shutdown, idempotency, circuit breakers, feature flags), platform-specific guidelines (Cloudflare, Rust, Python, TypeScript, Go, Docker, Git), and MCP GitHub tool patterns (use sassy_gh_push_files rather than create_or_update_file for existing files). Takes no parameters, returns plain text. Use before writing or reviewing code to know the expected standards.

Takes no parameters.

sassy_session_stop

Mutating: terminates a named persistent session's process (graceful terminate, force kill after 5s), removes the session, and returns the name, exit code, and the last 3000 characters of unread output. Fails if the session does not exist. Use it to clean up a session you started; use sassy_session_stop_all to kill everything at once.

Parametersnamerequired

sassy_env_get

Read-only. Returns the value of one environment variable from the SassyMCP server process; returns an error if the variable is not set. If the variable name contains token, key, secret, password, or api (case-insensitive), the value is masked: values longer than 12 characters show the first 4 and last 4 characters, shorter ones show as ****. Non-sensitive values are returned in full. Use it to check a single variable; use sassy_env_list when you need to browse the environment or do not know the exact name.

Parametersnamerequired

sassy_http_ping

Read-only. Health-checks one or more URLs with a HEAD request each and reports status code plus round-trip time. urls is a single comma-separated string. Each URL gets a 5-second timeout, redirects are followed, and the response lists per-URL results (status code and ms), with status blocked when SSRF validation rejects a URL or error when the request fails. SSRF protection blocks private IPs, link-local addresses, cloud metadata, and non-http(s) schemes. Use it for quick up/down and latency checks; prefer sassy_http when you need the response body or anything beyond HEAD.

Parametersurlsrequired

sassy_type_text

Mutating: sends keystrokes to the focused field. It always clears the field first with ctrl-a + backspace, so it never appends — if you need to preserve existing content, this is the wrong tool. If target_x and target_y are both nonzero it clicks there first; text is then typed with interval seconds between keystrokes (default 0.02). Works on Windows, macOS, and Linux via pyautogui. Returns the character count typed. Use it to fill GUI fields; use sassy_hotkey for shortcuts like ctrl+s and sassy_click for mouse actions.

Parameterstextrequiredintervaltarget_xtarget_y

sassy_unzip

Mutating: writes extracted files to disk. Extracts a .zip archive to destination, defaulting to the archive's parent directory under the archive's stem name. password (default empty) unlocks encrypted zips. Zip-slip protection rejects the whole archive with an error if any entry path escapes the destination. Existing files at the destination are silently overwritten. Returns the extraction path, the file count, and a sample of the first 20 entry names. Use it to open zips from any source; use sassy_zip to create archives for extraction with this tool.

Parametersarchiverequiredpassworddestination

sassy_setup_status

Read-only aggregated setup report with no parameters. Reports setup_complete, persona file existence/size/path, auth state (whether SASSYMCP_AUTH_TOKEN is set in the environment, whether ~/.sassymcp/tokens.json exists, and overall auth_active), integrations (GitHub token configured plus the saved GitHub username, SSH configured plus the saved SSH host), the config file path with its key names, the SassyMCP data directory, and the files currently in it. If setup is not complete it includes an action_required field pointing at the next steps. This is the best first call when diagnosing an unknown machine or confirming what first-run steps remain. It never modifies anything. To fix what it reports as missing, call sassy_setup_wizard for the persona, sassy_setup_github or sassy_setup_ssh for integrations, or sassy_setup_tools for dependencies.

Takes no parameters.

sassy_edit_multi

Mutating: applies several surgical edits to one existing file in a single call, with the prior contents snapshotted into the adjacent _DELETE_/ staging folder first. edits is a JSON string array of {"old", "new"} objects, applied in order against the evolving content. Any edit whose old text has zero or more than one match aborts the whole call before anything is written, so nothing is partially applied. The file must exist and protected paths are refused. Returns only a count of applied edits, no preview. Use it to batch multiple unique-match changes in one file; use sassy_edit_block when you want a single edit with a context preview.

Parameterspathrequirededitsrequired

sassy_ghq_get

Read-only. Fetches one file from a repo and returns its contents plus SHA. Required: owner, repo, path (repo-relative file path). Optional ref (branch, tag, or commit SHA; default empty means the repo default branch). The API returns base64 content, but this tool decodes it for you and replaces the content field with decoded_content (UTF-8, errors replaced). Requires a GitHub token (GITHUB_TOKEN or GITHUB_PERSONAL_ACCESS_TOKEN). Use to read a file before pushing an updated copy with sassy_ghq_push; use sassy_ghq_get for directory paths only if you want the raw directory listing object. For the fuller variant (explicit tree traversal options) use the github_full tool sassy_gh_get_file_contents.

Parametersrefpathrequiredreporequiredownerrequired

sassy_persona_decisions

Read-only. Returns the decision framework defining when to act without discussion versus when to slow down: execute immediately for file ops, code changes, git, builds, and diagnostics; state approach then execute for architectural changes, schema changes, or breaking API changes; require explicit confirmation for production data destruction without backup, credential rotation on live systems, security posture reduction, or financial transactions; hard stop and refuse for SQLi/XSS/command-injection introduction, hardcoded secrets, or disabled auth. Takes no parameters, returns plain text. Use to calibrate caution on risky operations; pair with sassy_persona_full for the complete bundle.

Takes no parameters.

sassy_persona_style

Read-only. Returns the expert-mode operating parameters injected into the AI session: execution priority (act first, explain later), communication style (declarative, no preambles, no safety disclaimers on standard operations), autonomy level (never ask permission for reversible operations, complete full scope), and precision standards (exact tool names, paths, line numbers, quantified results). Takes no parameters and returns a plain text document. Use when you want the session's behavior directives alone; for the whole bundle (style + decisions + practices + observability + capabilities + user context) in one call, use sassy_persona_full instead.

Takes no parameters.

sassy_move

Mutating: moves or renames a file or directory to the destination path. Refuses protected sources and destinations, and refuses sources on the sensitive-read denylist (SSH keys, AWS/GPG credentials, /etc/shadow, browser login DBs, SassyMCP tokens) — moving such material is treated as read-equivalent exfiltration and refused like a content read. Also refuses to overwrite an existing destination — sassy_safe_delete the destination first if you genuinely need to replace it. Use it to relocate or rename; use sassy_copy to duplicate without removing the original, and sassy_safe_delete to remove instead.

Parameterssourcerequireddestinationrequired

sassy_session_start

Mutating: spawns a persistent terminal session under a unique name and returns its status, shell, and pid. shell defaults to the host native shell (powershell/cmd/wsl on Windows; bash/zsh/sh on macOS/Linux); command optionally runs immediately after startup. Reuse of a live name and initial commands tripping the delete interceptor are refused. stderr is merged into stdout and the per-session buffer keeps the last 50000 characters (tail). Use it for long-running work like dev servers or builds that you poll with sassy_session_read; use sassy_shell for one-shot commands and stop sessions with sassy_session_stop when done.

Parametersnamerequiredshellcommand

sassy_http

Can mutate or read depending on method. GET, HEAD, and OPTIONS run freely; POST, PUT, PATCH, and DELETE require allow_mutating=True (default False). Only http and https URLs are accepted, and SSRF validation blocks private IPs, link-local addresses, and cloud metadata endpoints. headers is a JSON object string, body is a UTF-8 string, timeout_seconds defaults to 15, and redirects are followed automatically. Returns status code, headers dict, method, url, and body, which is JSON-parsed when possible and otherwise plain text truncated at 10,000 characters. Use it for quick API calls; prefer web_inspector for deep page inspection.

Parametersurlrequiredbodymethodheadersallow_mutatingtimeout_seconds

sassy_read_file

Read-only. Reads a text file with line-based pagination and returns numbered lines under a header showing how many lines were selected, the start line, the total line count, and how many remain. offset is 0-based and defaults to 0; a negative offset reads the last N lines (tail mode, where length is ignored); length caps lines returned (default 1000). Directories are refused with a pointer to sassy_list_dir. Use it for large files by paging; prefer sassy_read_multiple when you need several files in one call, and sassy_search_files to find text across a tree.

Parameterspathrequiredlengthoffset

sassy_read_multiple

Read-only. Reads several files at once and concatenates them, each under a header like '--- path (N lines) ---'. paths is a JSON array of file paths (falls back to a comma-separated string if it is not valid JSON). A missing or unreadable file produces an inline error for that file without aborting the others. Use it to pull a handful of small files in one call; use sassy_read_file with offset/length for paging through a large file.

Parameterspathsrequired

sassy_screen_info

Read-only, takes no parameters. Returns the display configuration as JSON: every monitor with left/top/right/bottom/width/height, DPI scale_percent, and which is primary, plus a count. Uses native APIs on Windows (DPI-aware) and macOS (AppKit), falling back to a single-monitor pyautogui report elsewhere. Essential setup call for multi-monitor machines: run it before sassy_click or sassy_screenshot to translate absolute coordinates onto the right monitor.

Takes no parameters.

sassy_edit_block

Mutating: replaces a single exact occurrence of old_text with new_text in an existing file, and the prior contents are snapshotted into the adjacent _DELETE_/ staging folder before anything is written, so the change is recoverable. Refuses protected paths and refuses to run when old_text has multiple exact matches (add more context to make it unique). If there is no exact match, nothing is written: a fuzzy fallback (80% similarity) reports the closest text and a character diff instead. Reading is UTF-8 with error replacement; encoding and line endings are preserved. Returns a preview of the changed region with line numbers. Use it for one surgical edit; prefer sassy_edit_multi for batching several edits in one call.

Parameterspathrequirednew_textrequiredold_textrequired

sassy_context_estimate

Read-only. Estimates how much of the context window is consumed by currently registered MCP tool definitions, reporting total estimated tokens, percentage of a 200K window, the heaviest tools, tool count, and actionable recommendations (e.g. disable unused groups, drop github_full when tool count is high). Takes no parameters. If the tool registry cannot be read, it returns a note pointing to the SASSYMCP_LOAD_ALL / SASSYMCP_GROUPS environment settings instead of numbers. Use this first when context feels low or before enabling heavy groups; follow up with sassy_tool_groups to see what is loaded and sassy_tool_group_toggle to disable what you do not need.

Takes no parameters.

sassy_offline_commands

Read-only. Returns the offline-safe command listing built live from the tool registry, grouped by tool group with usage counts. Optional group filters to one group (see sassy_tool_groups for group names). Optional verbose=false returns names only (about a quarter of the tokens); true adds one-line purposes. LAN tools (SSH, wifi, adb wifi) are included since they need a network but not the internet. The response also lists tools unavailable offline and a system_prompt_snippet for pasting into a local model's prompt. Use before sassy_offline_handoff to build the local model's tool menu; never paste the full catalog into a small local model.

Parametersgroupverbose

sassy_setup_github

Mutating when saving; read-only for check and open_browser. The action parameter (default "check") selects the step. action=check validates the GITHUB_TOKEN or GITHUB_PERSONAL_ACCESS_TOKEN environment variable against the GitHub API and reports the login and scopes, or that no token exists. action=open_browser opens the GitHub token creation page locally and returns instructions with the recommended scopes (Contents, Issues, Pull Requests, Metadata). action=save_token validates the supplied token parameter (must start with ghp_ or github_pat_) against api.github.com/user; on success it stores the token in the process environment and records github_configured plus the GitHub username in config. The token lasts only for this session unless also set in system env or MCP client config. action=skip records the skip. Use this to enable the sassy_github_* tools.

Parameterstokenaction

sassy_shell

Mutating: executes an arbitrary shell command in the host shell — it can do anything the shell can. shell defaults to powershell on Windows or the login shell on macOS/Linux; POSIX shells run the command verbatim while PowerShell syntax is normalized. timeout_seconds defaults to 30 (clamped 1-300); over 120 the call auto-promotes to a background session, returning a JSON handle to poll with sassy_session_read. Safety gates always run: catastrophic blocklist entries hard-block, delete keywords auto-stage targets to _DELETE_/ when identifiable, and other destructive patterns block or return a confirmation_required token (when interceptor.destructiveAction is 'confirm'; redeem via sassy_shell_confirm). allow_pattern bypasses one named pattern only. Output shows [exit: N] plus stdout and stderr. Use for one-shot commands; prefer sassy_session_start for long-running work.

Parametersshellcommandrequiredallow_patterntimeout_seconds

sassy_desktop_state

Read-only. Lists visible open windows with title and absolute left/top/width/height coordinates spanning all monitors, returned as lean JSON. include_taskbar defaults to False, filtering out taskbar entries. Windows-only for window enumeration (pywinauto UIA backend); macOS enumerates via System Events and needs Accessibility permission granted to the app running SassyMCP; Linux returns an unsupported error. Requires a GUI session; headless hosts return an error. Use it with sassy_screen_info to locate UI elements before sassy_click, or for a quick sense of what is open on the desktop.

Parametersinclude_taskbar

Version history

4
  1. v1.18.0LatestOct 21, 2026
  2. v1.16.0Sep 22, 2026
  3. v1.15.2Sep 21, 2026
  4. v1.15.1Sep 16, 2026

Score

80% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts
  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts

    Declare a license in the repository or the registry entry.