Why this verdict
- inconclusive: gap dynamic_metadata at src/proxy.ts
- inconclusive: gap no_tools_extracted at package.json
Security findings 0
No individual findings recorded
The inconclusive verdict rests on the open questions and 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.
Tool poisoning
highNoteConfirmed on reviewlow confidenceThe proxy forwards tool, prompt, and resource metadata from a remote server fetched at runtime, so the descriptions the agent loads are not fixed in the reviewed artifact and cannot be reviewed statically.
tools list depends on dependency-provided value (dependency)
conceal:remotevector:metadata
Reviewer's reasoning
The proxy's declared core function is forwarding the publisher's own remote server's tool, prompt, and resource metadata; the unresolved metadata is a review limitation tied to the publisher's own upstream service, not a behavior the artifact adds on its own initiative.
Credential access
mediumNoteConfirmed on reviewmedium confidencevalidateApiUrl accepts plain http:// for any *.searchatlas.com host, so the bearer token or API key would be sent unencrypted when the URL is set to http.
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {vector:code
Reviewer's reasoning
The http acceptance only matters if the user or an outside party sets SEARCHATLAS_API_URL to an http URL; the artifact does not do this itself, so it is a weakness that needs operator-controlled input, and the host stays the issuing service.
Persistence
mediumNoteConfirmed on reviewmedium confidenceThe login command writes the token into the global Cursor, Claude Desktop, and Windsurf MCP configs and creates them when missing; this is disclosed in the file header and output and runs only when the user invokes login.
env: { SEARCHATLAS_TOKEN: token }vector:code
Reviewer's reasoning
Writing the token into global MCP client configs is the declared purpose of the user-invoked login command, and the file header and console output disclose it; the token goes to the MCP server that the user is configuring.
Credential access
mediumNoteConfirmed on reviewlow confidenceThe login flow tells the user to copy the dashboard token from browser localStorage and paste it into the CLI; the token is the vendor's own and the step is user-invoked.
Copy the result (with or without quotes)
vector:instruction
Reviewer's reasoning
The user manually copies their own vendor token from the dashboard after running login; the step is user-invoked and no third party receives the token.
Supply chain
lowNoteConfirmed on reviewmedium confidenceThe package.json prepare script runs the package's own local build (npm run build, which cleans dist and runs tsc) on install; this is undeclared but serves the artifact's own build and changes nothing outside it.
"prepare": "npm run build"
vector:code
Reviewer's reasoning
The prepare script runs the package's own local build (clean and tsc) on install, which is the artifact's own install path and changes nothing outside its own output; the undeclared mention is a hygiene gap, not a harmful step.
Open questions 1
What the analysis could not settle from the code alone.
What tool, prompt, and resource descriptions and schemas does the remote server return at runtime, and do they steer the agent beyond the declared task?
Tool poisoning
Coverage gaps 5
Parts of the artifact the static analysis could not fully examine.
dynamic_metadata line 108: tool (computed name) tools list depends on dependency-provided value (dependency): instance of a class from '@modelcontextprotocol/sdk': new Client( { name: `${opts.name}-proxy`, version: opts.version }, { capabilities: {} } )
src/proxy.ts
dynamic_metadata line 108: prompt (computed name) prompts list depends on dependency-provided value (dependency): instance of a class from '@modelcontextprotocol/sdk': new Client( { name: `${opts.name}-proxy`, version: opts.version }, { capabilities: {} } )
src/proxy.ts
dynamic_metadata line 108: resource (computed name) resources list depends on dependency-provided value (dependency): instance of a class from '@modelcontextprotocol/sdk': new Client( { name: `${opts.name}-proxy`, version: opts.version }, { capabilities: {} } )
src/proxy.ts
dynamic_metadata line 108: resource (computed name) resourceTemplates list depends on dependency-provided value (dependency): instance of a class from '@modelcontextprotocol/sdk': new Client( { name: `${opts.name}-proxy`, version: opts.version }, { capabilities: {} } )
src/proxy.ts
no_tools_extracted MCP server target with no statically extractable tools/prompts/resources
package.json