SignalGrid MCP
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@SignalGrid MCPrun a full posture report"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
SignalGrid MCP
An MCP (Model Context Protocol) server that exposes macOS-native device trust signals — the facts about a Mac that cannot be gathered from a Linux container or a cloud runner. Every tool is strictly read-only: nothing on the device is ever mutated.
What it answers
Signal | Tool |
Who is this machine? (serial, UUID, chip, activation lock) |
|
What OS build is it on? |
|
Are SIP / FileVault / Gatekeeper / firewall on? |
|
What remote access is exposed? (SSH, Screen Sharing, SMB, ARD) |
|
Is it MDM/DEP enrolled? What profiles are installed? |
|
Is it patched? Are auto-updates on? |
|
Are XProtect / MRT malware definitions current? |
|
What got installed, and when? |
|
DNS, proxies, VPNs, interfaces |
|
What's listening on the network? |
|
What persists across reboots? (launchd items) |
|
Any third-party kernel extensions? |
|
Any stranded/conflicting system extensions? |
|
Who has accounts? Who is admin? |
|
What apps are installed, and who signed them? |
|
What's running right now? |
|
Is removable storage (a data-egress channel) connected? |
|
Does the device auto-lock when left idle? (walk-up risk) |
|
Is this app properly signed & notarized? |
|
Everything above the fold, in one call |
|
The SignalGrid decision for this Mac (allow / step-up / restrict / deny) |
|
The aggregate report is also exposed as an MCP resource at signalgrid://posture.
Call signalgrid_posture_report with include_verdict: true to get the raw facts
and the folded allow/step-up/restrict/deny decision in one round-trip (the same
fail-safe computation as signalgrid_trust_verdict).
Design principles
Read-only, always. Every tool carries
readOnlyHint: true,destructiveHint: false. No command mutates state.Unknown ≠ off. Posture checks distinguish "the check ran and said X" from "the check could not run" (missing binary, timeout, needs elevation).
enabled: nullalways means unknown — investigate, don't grade.No shell, no injection. Every command is an argv list executed without a shell; user input is never interpolated into a command line.
Context-efficient. Large inventories (apps, processes, launch items, install history, listeners) are paginated (
limit/offset, standardtotal/has_more/next_offsetenvelope), filterable (name_contains), and render as a compact markdown table by default or JSON on request.Degrades gracefully. On a non-macOS host, or when a probe needs elevation, tools return structured error/unknown text — they never crash.
How these signals reach the Grid (sourcing)
SignalGrid's decision fabric classifies every signal by how it is obtained —
api (a vendor read API), native (a first-party integration), grid_collected
(SignalGrid does the lifting itself), or unavailable (a real gap). This
server is the grid_collected path for macOS: SIP, FileVault, Gatekeeper, MDM
enrollment, XProtect currency and the rest are facts no cloud API hands you
faithfully in real time — you read them on the device.
Every signal here is therefore classified grid_collected at medium
fidelity — deliberately not high. The reads are authoritative, but the fabric
never over-trusts a signal it had to collect itself, and some probes degrade to
unknown without elevation.
The server publishes this mapping so a connecting fabric can discover each signal's provenance, as the MCP resource:
signalgrid://sourcingIt lists every posture-report section → the fabric signal it feeds → its
acquisition method and fidelity. tests/test_sourcing.py pins the manifest as a
bijection with the report sections, so no section can go un-sourced and no
stale entry can linger. (The per-signal descriptions are prose, not checked
against collector output.)
Install
Requires Python ≥ 3.10 on the Mac being assessed.
cd signalgrid-mcp
pip install -e . # or: uv pip install -e .Run
stdio transport (the server must run on the Mac it is assessing, as a subprocess of the MCP client):
signalgrid-mcp # console script
# or
python -m signalgrid_mcp.server
# or (back-compat)
python server.pyClaude Desktop / Claude Code config
{
"mcpServers": {
"signalgrid": {
"command": "python3",
"args": ["/Users/<you>/signalgrid-mcp/server.py"]
}
}
}Inspect interactively
npx @modelcontextprotocol/inspector python3 server.pyPermissions & elevation
The server intentionally runs unelevated. Some probes therefore report
null/unknown rather than an answer:
profiles list,systemsetup, and somelaunchctl print system/...targets want root.tmutil latestbackupand the Time Machine preference need Full Disk Access.Unelevated
lsofonly sees the current user's listeners.
This is by design: an unattended trust agent should not hold root. Treat
null as "unresolved signal" and escalate out-of-band if it matters.
Verify (turnkey, on the Mac)
One command sets up, tests, and inspects the live server end to end:
./verify.shIt creates a venv, installs, runs pytest, then inspects the server over MCP
stdio — listing and calling every tool. See RUNBOOK.md for the
step-by-step Mac verification, including how to chase down any signal that reads
unknown against real macOS output.
Testing
pip install -e ".[dev]"
pytestThe smoke tests run on any OS (they exercise the graceful-degradation paths on
Linux CI); the meaningful signal values obviously require macOS. For a Node-free
protocol inspection (no browser, no npx):
python tools/inspect_stdio.py # human-readable
python tools/inspect_stdio.py --json # machine-readable summaryLayout
signalgrid-mcp/
├── server.py # back-compat stdio entry point
├── verify.sh # one-command turnkey verify (install + test + inspect)
├── RUNBOOK.md # step-by-step Mac verification runbook
├── src/signalgrid_mcp/
│ ├── app.py # FastMCP instance + shared annotations
│ ├── runner.py # subprocess plumbing (run/text/probe/run_json)
│ ├── formatting.py # pagination, filtering, markdown/JSON rendering
│ ├── sourcing.py # grid_collected sourcing manifest (signalgrid://sourcing)
│ ├── server.py # entry point (main)
│ └── tools/ # one module per signal domain
├── tools/inspect_stdio.py # Node-free MCP inspector (protocol/read-only/honesty)
├── tests/test_smoke.py
├── tests/test_parsers.py # parser fixtures pinned against captured output
└── evaluation.xml # MCP eval suite (read-only Q&A pairs)This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/DanFashauer/signalgrid-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server