preflight

https://github.com/AdelElo13/mac-control-mcp

mac-control-mcp

Hostile

Score 0 / 100 · 80 files read · 0 critical, 3 high, 18 medium, 10 low findings

Report 5973ecf36ab69dc6 · first scanned 2026-10-28 · scanned 4× · keyed to the exact package contents, so this link always shows this version

Listed in the Agent Census directory data

Subscores

credentials0
exfiltration92
execution0
injection100
obfuscation100
files100

100 is clean. Deductions come only from the cited findings below.

Findings

highReferences the SSH directory (~/.ssh)
RELEASE_NOTES_v0.5.0.md · line 30 · rule H1
tory denylist: ``` .ssh, Library/Keychains, Library/Mail, Library/Messages, Library/Calendars, Library/Cookies, Library/IdentityS
highReferences an SSH private key file
RELEASE_NOTES_v0.5.0.md · line 37 · rule H1
h entry, so `~/.ssh/id_ed25519`, `~/safe/symlink -> ~/.ssh/anything`, and `~/.ssh/../.ssh/id_rsa` all fail closed. ### P0 #3 — `o
highReferences the GPG keyring (~/.gnupg)
RELEASE_NOTES_v0.5.0.md · line 33 · rule H1
, .mac-control-mcp, .gnupg, .aws, .kube ``` Matches the tail of the canonical path against each entry, so `~/.ssh/id_ed25519`, `~
mediumEnumerates the full process environment (all variables, not one named key)
.s1-evidence/r2-probe-tests.py · line 91 · rule M2
rt)] with patch.dict(os.environ, S1_SCRATCH='/fake'), patch('subprocess.run', fixture.run), \ patch.object(Path, 'mkd
mediumCan run shell commands from code
.s1-evidence/r2-probe-tests.py · line 67 · rule M1
'\n' return subprocess.CompletedProcess(argv, 0, stdout=output, stderr='') def require(condition, message): if not c
mediumEnumerates the full process environment (all variables, not one named key)
.s1-evidence/reviewer/a8-web/check.py · line 12 · rule M2
/ 'probe.py') env = dict(os.environ, PROBE_MAX='300000') def require(condition, message): if not condition: raise Ru
mediumCan run shell commands from code
.s1-evidence/reviewer/a8-web/check.py · line 24 · rule M1
n') completed = subprocess.run(argv, env=env, text=True, capture_output=True, timeout=900, check=True) (out / (label + '.t
mediumCan run shell commands from code
.s1-evidence/reviewer/session.py · line 17 · rule M1
txt").open("w") p = subprocess.Popen([binary], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=server_errors) buffer = b"" r
mediumCode contacts static.modelcontextprotocol.io, which the documentation never mentions
(package) · line 1 · rule M3
static.modelcontextprotocol.io
mediumEnumerates the full process environment (all variables, not one named key)
LIVE-CHECKS.md · line 875 · rule M2
/ 'probe.py') env = dict(os.environ, PROBE_MAX='300000') def require(condition, message): if not condition: raise Ru
mediumCan run shell commands from code
npm/bin/mac-control-mcp.js · line 11 · rule M1
n } = require('node:child_process'); const { parseArgs, HELP_TEXT, missingBundleMessage } = require('../lib/cli'); const { APP_PA
mediumCan run shell commands from code
npm/lib/install-core.js · line 29 · rule M1
c } = require('node:child_process'); const { parseTeamIdentifier, EXPECTED_TEAM_ID } = require('./release'); const { readPlistStr
mediumRuns a command automatically at install time (postinstall)
npm/package.json · line 1 · rule M4
postinstall: node scripts/install.js
mediumCan run shell commands from code
npm/test/archive.test.js · line 15 · rule M1
c } = require('node:child_process'); const { assertSafeArchivePaths, assertSafeArchiveLinks } = require('../lib/release'); const
mediumCan run shell commands from code
npm/test/cli.test.js · line 8 · rule M1
c } = require('node:child_process'); const { parseArgs, HELP_TEXT, missingBundleMessage } = require('../lib/cli'); const { readPl
mediumCan run shell commands from code
npm/test/helpers/fixture-app.js · line 22 · rule M1
c } = require('node:child_process'); const { parseTeamIdentifier, EXPECTED_TEAM_ID } = require('../../lib/release'); const { EXPE
mediumCan run shell commands from code
npm/test/helpers/tls.js · line 12 · rule M1
c } = require('node:child_process'); /** * @returns {{key: string, cert: string}|null} */ function makeSelfSignedCert() { con
mediumCan run shell commands from code
npm/test/postinstall.e2e.test.js · line 26 · rule M1
c } = require('node:child_process'); const { tarballName, sha256Name, EXPECTED_TEAM_ID, parseTeamIdentifier } = require('../lib/r
mediumCan run shell commands from code
scripts/e2e-coverage.js · line 28 · rule M1
spawn } = require('child_process'); const path = require('path'); const os = require('os'); const fs = require('fs'); // -------
mediumCan run shell commands from code
TestHarness/s2_concurrency.py · line 17 · rule M1
self.process = subprocess.Popen( [binary], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subp
mediumCan run shell commands from code
TestHarness/test_s2_concurrency.py · line 34 · rule M1
return subprocess.run( [sys.executable, str(PROBE), str(server), pids, "1", *extra],
lowReads named environment variables (normal for API keys; listed in the permission summary)
.s1-evidence/r2-probe-tests.py · line 91 · rule L1
with patch.dict(os.environ, S1_SCRATCH='/fake'), patch('subprocess.run', fixture.run), \ patch.object(Path, 'mkdir'),
lowReads named environment variables (normal for API keys; listed in the permission summary)
.s1-evidence/reviewer/a8-web/check.py · line 8 · rule L1
reviewer/a8-web') / os.environ.get('S1_A8_LABEL', 'after') out.mkdir(parents=True, exist_ok=True) binary = os.environ.get('S1_BINA
lowReads named environment variables (normal for API keys; listed in the permission summary)
.s1-evidence/reviewer/session.py · line 11 · rule L1
port Path binary = os.environ.get("S1_BINARY", ".build/debug/mac-control-mcp") mode = os.environ.get("S1_MODE", "check") window_m
lowReads named environment variables (normal for API keys; listed in the permission summary)
npm/lib/download.js · line 28 · rule L1
rl(targetUrl, env = process.env) { const target = new URL(targetUrl); const noProxy = env.NO_PROXY || env.no_proxy || ''; if
lowReads named environment variables (normal for API keys; listed in the permission summary)
npm/lib/release.js · line 33 · rule L1
eleaseBaseUrl(env = process.env) { const raw = env[RELEASE_BASE_URL_ENV]; if (raw === undefined || raw.trim() === '') return R
lowReads named environment variables (normal for API keys; listed in the permission summary)
npm/scripts/install.js · line 214 · rule L1
tion main() { if (process.env.MAC_CONTROL_MCP_SKIP_DOWNLOAD === '1') { log('MAC_CONTROL_MCP_SKIP_DOWNLOAD=1 — skipping binar
lowReads named environment variables (normal for API keys; listed in the permission summary)
npm/test/helpers/fixture-app.js · line 29 · rule L1
; const fromEnv = process.env.MAC_CONTROL_MCP_TEST_FIXTURE_APP; if (fromEnv && fromEnv.trim() !== '') list.push(fromEnv.trim()
lowReads named environment variables (normal for API keys; listed in the permission summary)
npm/test/postinstall.e2e.test.js · line 136 · rule L1
env: { ...process.env, MAC_CONTROL_MCP_RELEASE_BASE_URL: mirror.baseUrl, MAC_CONTROL_MCP_TEST_VERSION: versi
lowReads named environment variables (normal for API keys; listed in the permission summary)
scripts/e2e-coverage.js · line 357 · rule L1
if (f.payload && process.env.VERBOSE) { console.log(` payload: ${JSON.stringify(f.payload).slice(0, 200)}…`);
lowReads named environment variables (normal for API keys; listed in the permission summary)
TestHarness/test_s2_concurrency.py · line 17 · rule L1
lse: mode = os.environ.get("S2_FAKE_MODE", "valid") if mode == "eof": sys.exit(0) nodes = [] i

Permission surface

Network endpoints
example.orggithub.comimg.shields.iomirror.example.comregistry.modelcontextprotocol.ioregistry.npmjs.orgstatic.modelcontextprotocol.iowww.npmjs.com
Environment read
MAC_CONTROL_MCP_SKIP_DOWNLOADMAC_CONTROL_MCP_TEST_FIXTURE_APPMAC_CONTROL_MCP_TEST_VERSIONS1_A8_LABELS1_BINARYS1_MODES1_OUTPUTS1_PERF_MENU_TITLES1_SCRATCHS1_WINDOW_MENUS2_FAKE_MODES2_FINDER_PIDS2_NEWS2_OLDS2_OUTS2_SETTINGS_PIDVERBOSE
Shell execution
yes — code or scripts can run shell commands
Install hooks
postinstall: node scripts/install.js
Credential material
Enumerates the full process environment (all variables, not one named key)
References the SSH directory (~/.ssh)
References an SSH private key file
References the GPG keyring (~/.gnupg)
Reads named environment variables (normal for API keys; listed in the permission summary)

Provenance

Source
GitHub
Repository
AdelElo13/mac-control-mcp
Owner
AdelElo13
Stars
18
Forks
3
Repo created
2026-04-16
Last push
2026-10-16
License
MIT

Watch this package

Interest list only. We store the address and this report link, nothing else. No mail is sent in v1.

Share this report: https://preflight.orbitaldeskllc.com/r/5973ecf36ab69dc6