SkillTotal

Is Hypertool MCP server safe?

No malicious indicators - review capabilities before installing
Notable — review in context (capabilities are not malware):
  • Node.js shell/command execution
  • Node.js filesystem read
  • Node.js filesystem write/delete

@toolprint/hypertool-mcp is an AI npm_package analyzed by SkillTotal's deterministic static scanner. The scan found no malicious indicators, though 4 risky constructs are reported for review. It can: filesystem read, filesystem write, mcp tools detected and shell execution — capabilities are what the code can do, not a verdict on intent. Risk score 0/100 (low).

@toolprint/hypertool-mcp 0.0.45

npm_package · npm:@toolprint/hypertool-mcp
LOW
0
/ 100 risk score
Snapshot · scanned Sep 24, 2026 · @toolprint/hypertool-mcp@0.0.45 · engine 0.53.0 / ruleset 60

Automated static-analysis result. It can contain false positives and false negatives, and is not a claim about the intent of Hypertool MCP server's authors. Report a false positive.

Capabilities — what this component can do (not a risk score):
filesystem readfilesystem writemcp tools detectedshell execution

Behavioral traits

How this component maps to the CSA agentic threat model. Descriptive — it never affects the risk score.

Tool surface
Tool Usage
Execution authority
Tool Access Control / Direct Tool Access
Filesystem reach
Tool Execution Context

Findings (4)

HIGHNode.js shell/command executionST-SHELL-NODE

The component can run operating-system commands or spawn processes.

import { execSync } from "child_process";
execSync("xclip -selection clipboard", { input: text });
execSync("xsel --clipboard --input", { input: text });
import { execSync } from "child_process";
execSync("xclip -selection clipboard", { input: text });
execSync("xsel --clipboard --input", { input: text });
import { spawnSync } from "child_process";
spawnSync("pbcopy", { input: rawCommand });

Why it matters: Powerful and often legitimate — confirm the commands aren't built from untrusted input.

Fix: Confirm the command and its arguments are fully controlled and not derived from untrusted input; prefer execFile with an argument array.

MEDIUMNode.js filesystem readST-FS-NODE-READ

The component reads files from disk.

const configContent = await fs.readFile(mcpConfigPath, "utf-8");
const configContent = await fs.readFile(envCheck.configPath, "utf-8");
const content = await fs.readFile(configPath, "utf-8");
const content = await fs.readFile(claudeConfigPath, "utf-8");
const content = await fs.readFile(cursorConfigPath, "utf-8");
const content = await fs.readFile(claudeCodePath, "utf-8");
const content = await fs.readFile(app.configPath, "utf-8");
const content = await fs.readFile(configPath, "utf-8");
const content = await fs.readFile(mainConfigPath, "utf-8");
const content = await fs.readFile(app.configPath, "utf-8");
const content = await fs.readFile(configPath, "utf-8");
const content = await fs.readFile(mainConfigPath, "utf-8");
const content = await fs.readFile(mainConfigPath, "utf-8");
const content = await this.fs.readFile(this.registryPath, "utf-8");
const content = await this.fs.readFile(srcPath);
const content = await this.fs.readFile(projectConfigPath, "utf-8");
const content = await this.fs.readFile(configPath, "utf-8");
const yamlContent = await this.fs.readFile(metadataPath, "utf-8");
const yamlContent = await this.fs.readFile(metadataPath, "utf-8");
const yamlContent = await this.fs.readFile(metadataPath, "utf-8");
const yamlContent = await this.fs.readFile(metadataPath, "utf-8");
const metadataContent = await this.fs.readFile(metadataPath, "utf-8");
const content = await this.fs.readFile(backupFile, "utf-8");
const content = await this.fs.readFile(path, "utf-8");
const serversContent = await this.fs.readFile(serversPath, "utf-8");

Why it matters: Usually legitimate, but worth confirming it can't be steered into reading sensitive files.

Fix: Confirm which files are read and that paths cannot be influenced by untrusted input to reach sensitive locations.

MEDIUMNode.js filesystem write/deleteST-FS-NODE-WRITE

The component writes or deletes files on disk.

await fs.writeFile(envCheck.configPath, JSON.stringify(config, null, 2));
await fs.writeFile(globalConfigPath, JSON.stringify(exampleConfig, null, 2), "utf-8");
await fs.writeFile(mainConfigPath, JSON.stringify(mainConfig, null, 2), "utf-8");
await fs.writeFile(configPath, JSON.stringify(config, null, 2));
await fs.writeFile(configPath, JSON.stringify(appConfig, null, 2));
await fs.writeFile(mainConfigPath, JSON.stringify(mainConfig, null, 2));
await fs.writeFile(mainConfigPath, JSON.stringify(mainConfig, null, 2), "utf-8");
await this.fs.writeFile(this.registryPath, JSON.stringify(this.registry, null, 2), "utf-8");
await this.fs.writeFile(destPath, content);
await this.fs.writeFile(metadataPath, yaml.stringify(metadata), "utf-8");
await this.fs.rm(tempDir, { recursive: true, force: true });
await this.fs.writeFile(metadataFilePath, yaml.stringify(metadata), "utf-8");
await this.fs.writeFile(join(appDir, basename(projectConfigPath)), content, "utf-8");
await this.fs.writeFile(join(appDir, filename), content, "utf-8");
await this.fs.rm(tempDir, { recursive: true, force: true });
await this.fs.rm(backupPath, { recursive: true, force: true });
await this.fs.unlink(backupPath);
await this.fs.unlink(metadataPath);
await this.fs.writeFile(targetPath, content, "utf-8");
await this.fs.writeFile(serversPath, JSON.stringify(servers, null, 2), "utf-8");
await this.fs.writeFile(groupsPath, JSON.stringify(groups, null, 2), "utf-8");
await this.fs.writeFile(sourcesPath, JSON.stringify(sources, null, 2), "utf-8");
await fs.writeFile(options.output, jsonOutput, "utf-8");
await fs.writeFile(filename, content, "utf-8");
await this.fs.writeFile(configPath, JSON.stringify(config, null, 2), "utf-8");

Why it matters: Usually legitimate, but worth confirming the paths can't be controlled by untrusted input.

Fix: Confirm which files are written/deleted and that paths cannot be influenced by untrusted input.

LOWMCP tool surface detectedST-MCP-DETECTED

An MCP tool surface (manifest or tool definitions) was found.

this.server = new Server({

Why it matters: Just context — review which tools it offers and their permissions.

Fix: Review the declared MCP tools and their permissions.

Check your own component

Run the same evidence-backed scan on any MCP server, agent skill, or package.

Scan your own component

How we determine this: deterministic static analysis (regex + AST), evidence-anchored, no code execution. Methodology →