SkillTotal

Is agents safe?

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

agents 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 network egress — capabilities are what the code can do, not a verdict on intent. Risk score 0/100 (low).

agents 0.24.0

npm_package · npm:agents
LOW
0
/ 100 risk score
Snapshot · scanned Sep 25, 2026 · agents@0.24.0 · 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 agents's authors. Report a false positive.

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

Behavioral traits

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

Tool surface
Tool Usage
Filesystem reach
Tool Execution Context
Network egress
Interaction & Communication / Direct Communication

Findings (4)

MEDIUMNode.js filesystem readST-FS-NODE-READ

The component reads files from disk.

return computer ? await workspace.fs.readFile(path, "utf8") : await workspace.readFile(path);
return await drain(await workspace.fs.readFile(path));

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.

if (computer) await workspace.fs.writeFile(path, content);
if (computer) await workspace.fs.writeFile(path, resource.content);
if (computer) await workspace.fs.writeFile(path, bytes);

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.

MEDIUMNode.js network egressST-NET-NODE

The component makes outbound network requests.

*   - RPC methods only. `.fetch()` is not supported (will throw).
fetch(request: Request): Promise<Response>;
* previous "construct a Request in the parent DO and `stub.fetch()`
* Facet-parent stubs route normal HTTP `.fetch()` calls through the
const response = await retryDurableObjectOperation(() => namespace.get(id, getOptions).fetch(cloneRequestForFetch(request)), {
response = await fetch(`${apiBaseUrl}/conversations.open`, {
response = await fetch(`${apiBaseUrl}/${method}`, {
response = await fetch(`${apiBaseUrl}/bot${options.botToken}/sendMessage`, {
return asApiResponse(await (await fetch(`${apiBaseUrl}/bot${options.botToken}/sendMessageDraft`, {
const response = await fetch(messagesUrl, {
const response = await fetch(getMessagesUrl.toString(), {
static fetch(_opts: PartyFetchOptions): Promise<Response>;
if (opts.basePath) return PartySocket.fetch({
return PartySocket.fetch({
fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
const response = await fetch(endpoint, { headers: options?.headers });
const wsResponse = await fetch(fetchUrl, { headers: {
const response = await browser.fetch(browserSessionEndpoint(void 0, options), { method: "POST" });
const response = await browser.fetch(`https://localhost/v1/devtools/browser/${sessionId}/json/list`);
const response = await browser.fetch(`https://localhost/v1/devtools/browser/${sessionId}`, { method: "DELETE" });
const response = await browser.fetch(browserSessionEndpoint(void 0, {
const ws = (await browser.fetch(browserSessionEndpoint(sessionId), { headers: { Upgrade: "websocket" } })).webSocket;
const response = await fetch(endpoint, { headers });

Why it matters: Usually legitimate, but confirm the destinations are expected and no sensitive data leaves.

Fix: Confirm the destination hosts are expected and that no sensitive data is sent off-host.

LOWMCP tool surface detectedST-MCP-DETECTED

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

* navigator.modelContext?.registerTool({
* navigator.modelContext?.registerTool({
modelContext.registerTool(toolDef, { signal: controller.signal });
{"version":3,"file":"webmcp.js","names":[],"sources":["../../src/experimental/webmcp.ts"],"sourcesContent":["/**\n * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n * !! WARNING: EXPERIMENTAL — DO NOT USE IN PRODU …
{"version":3,"file":"webmcp.js","names":[],"sources":["../../src/experimental/webmcp.ts"],"sourcesContent":["/**\n * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n * !! WARNING: EXPERIMENTAL — DO NOT USE IN PRODU …
return server.registerTool(name, {
{"version":3,"file":"x402.js","names":[],"sources":["../../../src/mcp/client/x402.ts"],"sourcesContent":["/**\n * X402 MCP Integration (v2)\n *\n * Based on:\n * - Coinbase's x402 (Apache 2.0): https://github.com/coinbase/x402\n * - @ethann …

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 →