Why this verdict
- inconclusive: gap dynamic_metadata at src/server.ts
- inconclusive: gap manifest_unparseable at chatmcp.yaml
- inconclusive: gap no_tools_extracted at package.json
Security findings 0
No individual findings recorded
The inconclusive verdict rests on the coverage gaps below.
Notes 5
Capabilities, vulnerabilities and disclosed behavior worth knowing. Nothing here works against the person who installs it, so notes never change the verdict.
Data exfiltration
mediumNoteConfirmed on reviewlow confidenceThe SCRAPELESS_BASE_URL environment variable overrides the destination of every request carrying the Scrapeless API key; an operator who sets it controls where the key goes, which is operator-controlled configuration.
process.env.SCRAPELESS_BASE_URL?.trim()
trigger:conditionalvector:code
Reviewer's reasoning
SCRAPELESS_BASE_URL is an operator-set environment variable that changes the endpoint for the user's own API key, which is operator-controlled configuration (test 5 carve-out); the user chooses the value, so this is not a server-chosen redirect.
Credential access
mediumNoteConfirmed on reviewmedium confidenceThe server reads the Scrapeless API key from the SCRAPELESS_API_KEY and SCRAPELESS_KEY environment variables and sends it as the x-api-token header to the publisher's service; this is the service's own credential used for its declared purpose, undeclared in the claims but not hidden.
process.env.SCRAPELESS_API_KEY?.trim()
vector:code
Reviewer's reasoning
The API key is read from the environment and sent as x-api-token to the publisher's own service, which issued it and is the declared purpose; the credential does not go to an unrelated host.
Credential access
mediumNoteConfirmed on reviewmedium confidenceThe context manager logs the first eight characters of the API key on every context creation, reuse and clear; this is a hygiene issue leaking key prefixes into local logs.
Creating new Context for API key: ${key?.substring(0, 8)}...vector:code
Reviewer's reasoning
Logging an eight-character key prefix to local console output is a hygiene mistake (test 5); it is not sent to any remote host and does not expose the full key.
Credential access
mediumNoteConfirmed on reviewmedium confidenceThe server sets the undeclared environment variable SCRAPELESS_IS_ONLINE to 'true' in its own process at startup; nothing in the declared purpose requires it and no consumer of it is shown, so it is an unexplained but non-hidden residue with no observed harm.
process.env.SCRAPELESS_IS_ONLINE = "true";
vector:code
Reviewer's reasoning
Setting SCRAPELESS_IS_ONLINE in the server's own process is an undeclared but visible residue with no shown harm or consumer; it is a hygiene issue, not concealment.
Data exfiltration
mediumNoteConfirmed on reviewlow confidenceThe ai_scraper tool accepts a caller-supplied webhook URL that Scrapeless calls with task results; a steered agent could direct results to an arbitrary host, which is a vulnerability the caller can use and is part of the declared task surface.
Webhook URL Scrapeless calls when the task completes.
vector:metadata
Reviewer's reasoning
The caller-supplied webhook URL only redirects results if an agent is steered by outside input to set it; the artifact makes this possible but does not itself act against the user, so test 3 applies.
Third-party flags 1
Behavior aimed at other sites, platforms or people, such as evading rate limits or offensive-security tooling. It does not affect the person who installs it, so it never changes the verdict.
Privilege escalation
lowNoteConfirmed on reviewmedium confidenceThe scrape_screenshot tool description advertises bypassing bot detection and CAPTCHAs via residential proxies on third-party sites, an access-control evasion that affects websites other than the user.
Restrictions: Bypasses bot detection and CAPTCHAs using residential proxies.
vector:metadata
Reviewer's reasoning
The tool advertises bypassing bot detection and CAPTCHAs on third-party websites; this evasion harms website operators rather than the installing user, so it is a third-party finding at note level.
Coverage gaps 8
Parts of the artifact the static analysis could not fully examine.
manifest_unparseable yaml: while scanning a block scalar
chatmcp.yaml
dynamic_metadata line 41: tool (computed name) name depends on unsupported construct (unsupported): Object.values(toolsList)
src/server.ts
dynamic_metadata line 41: tool (computed name) input schema depends on unsupported construct (unsupported): Object.values(toolsList)
src/server.ts
dynamic_metadata line 41: tool (computed name) annotations depends on unsupported construct (unsupported): Object.values(toolsList)
src/server.ts
dynamic_metadata line 49: tool (computed name) name depends on unsupported construct (unsupported): Object.values(browserTools)
src/server.ts
dynamic_metadata line 49: tool (computed name) input schema depends on unsupported construct (unsupported): Object.values(browserTools)
src/server.ts
dynamic_metadata line 49: tool (computed name) annotations depends on unsupported construct (unsupported): Object.values(browserTools)
src/server.ts
no_tools_extracted MCP server target with no statically extractable tools/prompts/resources
package.json