MCP, MCP server
Health Export Mcp
Query your own Apple Health data from any MCP client.
Compatibility: Not stated.
Grade B
Minor issues only, no Medium or High. Worth a quick look at the findings below before installing.
Not a guarantee. A hygiene check of the source at the commit shown, not a security audit.
PERMISSION_DELETE_FILES NETWORK_NO_FIXED_HOST SECRETS_PATH_UNCONFIRMED SECRETS_ENV_READ
Why this grade
- PERMISSION_DELETE_FILES Low
Contains a call that can delete files.
events.test.mjs, line 124
fs.rmSync(path.join(DIR, '.health-pair.json')); - NETWORK_NO_FIXED_HOST Low
Makes a network call whose host is not written as a fixed address.
envelope.test.mjs, line 329
const req = http.request({ host: '127.0.0.1', port, path: '/health-cache', method: 'POST', - SECRETS_PATH_UNCONFIRMED Low
The Secrets check reports a credential or environment file, but no quoted line shows a recognisable path.
apply-mcp-config.mjs, line 49
const secret = useSecretEnv ? (process.env.HEALTH_EXPORT_PAIRING_SECRET || '') : ''; - SECRETS_ENV_READ Note
Reads an environment variable whose name contains KEY, SECRET, TOKEN, PASSWORD or CREDENTIAL.
apply-mcp-config.mjs, line 49
const secret = useSecretEnv ? (process.env.HEALTH_EXPORT_PAIRING_SECRET || '') : '';
Any High, or two or more Medium findings, give D. One Medium gives C. Low findings or a security Note give B. Each code names a finding behind the letter.
Grades are a hygiene check of the source at the commit shown, on the date checked, not a security audit or a guarantee. The free directory grades are automated. Before release, a PlugVet engineer reviews every paid report and any grade we hold back, including all F grades, against the source code and the evidence we quote.
What was checked
Plain notes from the hygiene checks.
Permissions
Concern
can delete files.
PERMISSION_DELETE_FILES
events.test.mjs, line 124
fs.rmSync(path.join(DIR, '.health-pair.json'));
freshness.test.mjs, line 80
for (const n of fs.readdirSync(dir)) fs.rmSync(path.join(dir, n), { force: true });
freshness.test.mjs, line 396
fs.rmSync(path.join(dir, 'health-events.json'));
Show more
healthstore.test.mjs, line 222
fs.rmSync(path.join(DIR, 'health-intraday.json'));
healthstore.test.mjs, line 231
fs.rmSync(path.join(DIR, 'health-intraday.json'));
pairing.test.mjs, line 34
fs.rmSync(dir, { recursive: true, force: true });
pairing.test.mjs, line 42
fs.rmSync(dir, { recursive: true, force: true });
pairing.test.mjs, line 52
fs.rmSync(dir, { recursive: true, force: true });
Install and update
Pass
No install-time script found, and dependencies are pinned or absent.
Network
Concern
can reach a host that is not written as a fixed address.
NETWORK_NO_FIXED_HOST
envelope.test.mjs, line 329
const req = http.request({ host: '127.0.0.1', port, path: '/health-cache', method: 'POST',
receiver.test.mjs, line 20
const req = http.request({ host: '127.0.0.1', port: PORT, path: pathname, method: 'POST',
receiver.test.mjs, line 30
const req = http.request({ host: '127.0.0.1', port, path: pathname, method: 'POST',
Show more
receiver.test.mjs, line 40
const sock = net.connect(PORT, '127.0.0.1', () => {
Secrets
Concern
reads a credential or environment file.
SECRETS_ENV_READ SECRETS_PATH_UNCONFIRMED
apply-mcp-config.mjs, line 49
const secret = useSecretEnv ? (process.env.HEALTH_EXPORT_PAIRING_SECRET || '') : '';
apply-mcp-config.mjs, line 65
? (process.env.HEALTH_EXPORT_LISTEN_TOKEN || process.env.HEALTH_EXPORT_PAIRING_SECRET || '')
apply-mcp-config.mjs, line 170
const entryEnv = root[spec.topKey][name].env || {};
Show more
apply-mcp-config.test.mjs, line 39
ok(cfg.mcpServers['health-export'].env.HEALTH_DATA_DIR === DATA, `${client}: data dir`);
apply-mcp-config.test.mjs, line 40
ok(!('PAIRING_SECRET' in cfg.mcpServers['health-export'].env), `${client}: no secret when none given`);
apply-mcp-config.test.mjs, line 49
ok(cfg2.mcpServers['health-export'].env.PAIRING_SECRET === 'SEKRIT', `${client}: secret written from env`);
apply-mcp-config.test.mjs, line 62
ok(cfg.servers['health-export'].env.PAIRING_SECRET === '${input:health_pairing_secret}', 'vscode: secret is an input ref');
apply-mcp-config.test.mjs, line 112
ok(cfg.mcpServers['health-export'].env.PAIRING_SECRET === 'KEEPME', 'preserve: secret survives a re-run without the flag');
apply-mcp-config.test.mjs, line 113
ok(cfg.mcpServers['health-export'].env.HEALTH_DATA_DIR === NEWDATA, 'preserve: data dir still updated');
apply-mcp-config.test.mjs, line 117
ok(!('PAIRING_SECRET' in cfg.mcpServers['health-export'].env), 'clear: --clear-pairing-secret removes it');
healthstore.mjs, line 175
const secret = process.env.PAIRING_SECRET || '';
normalize.test.mjs, line 19
delete process.env.PAIRING_SECRET;
normalize.test.mjs, line 311
process.env.PAIRING_SECRET = '
normalize.test.mjs, line 324
delete process.env.PAIRING_SECRET;
receiver.mjs, line 182
token = process.env.HEALTH_LISTEN_TOKEN || '',
Agent instructions
Pass
No instruction to ignore earlier instructions or to hide a step.
Obfuscation
Pass
No encoded or minified payload found.
Licence
Pass
A licence file is present (LICENSE).
Maintainer activity
Pass
The latest commit is within the last 365 days.
Note
Hygiene check of commit eaf5149c38ed. can delete files. can reach a host that is not written as a fixed address. reads a credential or environment file.
Date and source
Date checked:
github.com
Commit graded: eaf5149c38ed26c36892cf31772ce99be76a5a82
This link goes to the original host. PlugVet does not host or check what you download from there, and installing it is your own decision and risk.