registry  /  cotal-ai  /  0.11.6

cotal-ai@0.11.6

Cotal — lateral agent coordination over NATS. Run `npx cotal-ai` for the CLI.

AI Security Review

scanned 2h ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. No concrete malicious chain is established. The package seeds first-party agent extensions on CLI first run and includes an explicit installer that can modify a Hermes installation.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
User runs `cotal` for first-run setup or explicitly runs the Hermes connector installer.
Impact
Can add Cotal integration to supported agent runtimes and launch coordinated peers; this is a guarded but high-impact agent control surface.
Mechanism
First-party agent extension setup, local service launch, and agent-peer control tools.
Rationale
This is not malicious by source evidence: there is no install-time hook or confirmed exfiltration/payload chain. It warrants a warning because it establishes a first-party AI-agent extension lifecycle and exposes agent-spawn capabilities.
Evidence
package.jsondist/cotal.jsseeded-connectors/hermes/bin/install.mjsseeded-connectors/opencode/dist/serve.jsseeded-connectors/pi/dist/index.jsseeded-connectors/claude/dist/hook.cjs

Decision evidence

public snapshot
AI called this Suspicious at 89.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • `dist/cotal.js` enables extensions and documents first-run seeding of four agent connectors.
  • `seeded-connectors/hermes/bin/install.mjs` installs/enables a Hermes plugin and writes COTAL settings when explicitly run.
  • `seeded-connectors/opencode/dist/serve.js` launches OpenCode and manages local state under `COTAL_OPENCODE_HOME/.cotal`.
  • Bundled connectors expose agent spawn/persona controls, a meaningful agent-capability surface.
Evidence against
  • Root `package.json` has no preinstall, install, or postinstall hook.
  • `dist/cotal.js` is a user-invoked CLI bin; importing/installing the root package does not execute its CLI path.
  • OpenCode launcher binds its service to `127.0.0.1` and its fetch call targets that local service.
  • No confirmed credential harvesting, arbitrary remote payload execution, reverse shell, or command-output exfiltration was found.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsEvalFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsMinifiedObfuscatedUrlStrings
ManifestNo manifest risk signals triggered.
scanned 11 file(s), 9.43 MB of source, external domains: 127.0.0.1, a2a-protocol.org, broker.cotal.ai, cotal.ai, cotal.localhost, datatracker.ietf.org, docs.confluent.io, docs.cotal.ai, docs.discord.com, docs.nats.io, github.com, hermes-agent.nousresearch.com, json-schema.org, modelcontextprotocol.io, mosquitto.org, nousresearch.com, opencode.ai, raw.githubusercontent.com, slack.engineering, spec.matrix.org, www.npmjs.com, www.rfc-editor.org, www.w3.org, xmpp.org
Oversized source lightweight scan
seeded-connectors/claude/dist/mcp.cjs2.43 MB file, sampled 256 KB
FilesystemNetworkChildProcessEnvironmentVarsEvalCryptoHighEntropyStringsUrlStringsdocs.cotal.aijson-schema.orgraw.githubusercontent.com
seeded-connectors/pi/dist/standalone.js2.08 MB file, sampled 256 KB
EnvironmentVarsCryptoHighEntropyStrings

Source & flagged code

10 flagged · loading source
seeded-connectors/claude/dist/index.jsView file
55// (node `InitializeOnce`, winsock/ICU can't load) — and a `pty`-runtime (ConPTY) child does NOT L56: // inherit it the way a plain child_process does, so a manager-spawned agent dies before its first L57: // line. The rest let agents resolve the system drive, arch, and Program/Data roots they shell out
High
Child Process

Package source references child process execution.

seeded-connectors/claude/dist/index.jsView on unpkg · L55
seeded-connectors/pi/dist/index.jsView file
12import { L13: hardenPrivate, L14: loadAgentFile as loadAgentFile2, ... L22: import { DEFAULT_SERVER, assertValidChannel, channelInAllow, isConcreteChannel, loadAgentFile, parseJoinLink } from "@cotal-ai/core"; L23: var FEEDBACK_URL = "https://broker.cotal.ai/v1/feedback"; L24: var PUBLIC_FEEDBACK_URL = "https://cotal.ai/v1/feedback"; ... L29: } L30: function hasIdentity(env = process.env) { L31: return Boolean(env.COTAL_NAME?.trim() || env.COTAL_LINK?.trim() || env.COTAL_AGENT_FILE?.trim()); ... L35: const def = env.COTAL_AGENT_FILE?.trim() ? loadAgentFile(env.COTAL_AGENT_FILE.trim()) : void 0; L36: const name = env.COTAL_NAME?.trim() || def?.name || (link ? userInfo().username : void 0); L37: if (!name)
Critical
Command Output Exfiltration

Source executes local commands and sends command output to an external endpoint.

seeded-connectors/pi/dist/index.jsView on unpkg · L12
15566"summary": "cotal is the operator command line for the reference implementation: bring a mesh up, mint identities, launch agents, watch what they do, and tear it all down.", L15567: "body": "# `cotal` CLI reference\n\n> **Reference**: describes the TypeScript reference implementation (the `cotal` CLI), not the wire contract. \xB7 **For:** operators \xB7 **Wire... L15568: },
High
Shell

Package source references shell execution.

seeded-connectors/pi/dist/index.jsView on unpkg · L15566
seeded-connectors/claude/dist/hook.cjsView file
7var __hasOwnProp = Object.prototype.hasOwnProperty; L8: var __commonJS = (cb, mod) => function __require() { L9: return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
Medium
Dynamic Require

Package source references dynamic require/import behavior.

seeded-connectors/claude/dist/hook.cjsView on unpkg · L7
seeded-connectors/opencode/dist/serve.jsView file
1// src/serve.ts L2: import { execFileSync, spawn } from "node:child_process"; L3: import { createServer } from "node:net"; L4: import { once } from "node:events"; ... L8: function resolveOpencodeBin() { L9: const override = process.env.COTAL_OPENCODE_BIN?.trim(); L10: if (override) return override; L11: if (process.platform !== "win32") return "opencode"; L12: for (const dir of (process.env.PATH ?? "").split(delimiter)) { ... L31: async function killServe(serve) { L32: if (serve.exitCode !== null || serve.signalCode !== null) return; L33: serve.kill("SIGTERM");
Critical
Reverse Shell

Source matches reverse-shell style process and socket wiring.

seeded-connectors/opencode/dist/serve.jsView on unpkg · L1
1// src/serve.ts L2: import { execFileSync, spawn } from "node:child_process"; L3: import { createServer } from "node:net"; L4: import { once } from "node:events"; ... L8: function resolveOpencodeBin() { L9: const override = process.env.COTAL_OPENCODE_BIN?.trim(); L10: if (override) return override;
High
Same File Env Network Execution

A single source file combines environment access, network access, and code or shell execution; review context before blocking.

seeded-connectors/opencode/dist/serve.jsView on unpkg · L1
1// src/serve.ts L2: import { execFileSync, spawn } from "node:child_process"; L3: import { createServer } from "node:net"; L4: import { once } from "node:events"; ... L8: function resolveOpencodeBin() { L9: const override = process.env.COTAL_OPENCODE_BIN?.trim(); L10: if (override) return override; L11: if (process.platform !== "win32") return "opencode"; L12: for (const dir of (process.env.PATH ?? "").split(delimiter)) { ... L31: async function killServe(serve) { L32: if (serve.exitCode !== null || serve.signalCode !== null) return; L33: serve.kill("SIGTERM");
High
Sandbox Evasion Gated Capability

Source gates dangerous network, credential, or execution behavior behind CI, host, platform, time, or geo fingerprint checks.

seeded-connectors/opencode/dist/serve.jsView on unpkg · L1
seeded-connectors/hermes/bin/install.mjsView file
21Cross-file remote execution chain: seeded-connectors/hermes/bin/install.mjs spawns seeded-connectors/hermes/plugin/cotal/_sidecar/standalone.cjs; helper contains network access plus dynamic code execution. L21: */ L22: import { execFileSync } from "node:child_process"; L23: import { ... L31: } from "node:fs"; L32: import { createConnection } from "node:net"; L33: import { homedir, tmpdir } from "node:os"; ... L47: const die = (msg) => { L48: process.stderr.write(`✗ ${msg}\n`); L49: process.exit(1); ... L119: function configFromFlags(flags, defaults) { L120: const link = flags.link || process.env.COTAL_LINK; L121: if (link) return { COTAL_LINK: link, COTAL_NAME: flags.name || process.env.COTAL_NAME || defaults.name };
High
Cross File Remote Execution Context

Source spawns a local helper that also contains network and dynamic execution context; review data flow before blocking.

seeded-connectors/hermes/bin/install.mjsView on unpkg · L21
seeded-connectors/hermes/plugin/cotal/hooks.pyView file
path = seeded-[redacted].py kind = build_helper sizeBytes = 2717 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

seeded-connectors/hermes/plugin/cotal/hooks.pyView on unpkg
seeded-connectors/claude/dist/mcp.cjsView file
path = seeded-connectors/claude/dist/mcp.cjs kind = oversized_source_file sizeBytes = 2547400 magicHex = [redacted]
High
Oversized Source File

Package contains source files above the static scanner size ceiling.

seeded-connectors/claude/dist/mcp.cjsView on unpkg

Findings

2 Critical6 High5 Medium6 Low
CriticalCommand Output Exfiltrationseeded-connectors/pi/dist/index.js
CriticalReverse Shellseeded-connectors/opencode/dist/serve.js
HighChild Processseeded-connectors/claude/dist/index.js
HighShellseeded-connectors/pi/dist/index.js
HighSame File Env Network Executionseeded-connectors/opencode/dist/serve.js
HighSandbox Evasion Gated Capabilityseeded-connectors/opencode/dist/serve.js
HighCross File Remote Execution Contextseeded-connectors/hermes/bin/install.mjs
HighOversized Source Fileseeded-connectors/claude/dist/mcp.cjs
MediumDynamic Requireseeded-connectors/claude/dist/hook.cjs
MediumNetwork
MediumEnvironment Vars
MediumShips Build Helperseeded-connectors/hermes/plugin/cotal/hooks.py
MediumStructural Risk Force Deep Review
LowScripts Present
LowEval
LowFilesystem
LowObfuscated
LowHigh Entropy Strings
LowUrl Strings